diff --git a/pcsx2/IopMem.cpp b/pcsx2/IopMem.cpp
index a30dd4682d..4d32c87180 100644
--- a/pcsx2/IopMem.cpp
+++ b/pcsx2/IopMem.cpp
@@ -32,6 +32,10 @@ static const uint m_psxMemSize =
0x00010000 + // psxP
0x00000100 ; // psxS
+// TODO: move to a header
+void Pcsx2HostFSwrite32(u32 addr, u32 value);
+u32 Pcsx2HostFSread32(u32 addr);
+
void psxMemAlloc()
{
if( m_psxAllMem == NULL )
@@ -238,7 +242,7 @@ u32 __fastcall iopMemRead32(u32 mem)
if (t == 0x1d00)
{
u32 ret;
- switch(mem & 0xF0)
+ switch(mem & 0x8F0)
{
case 0x00:
ret= psHu32(SBUS_F200);
@@ -258,6 +262,9 @@ u32 __fastcall iopMemRead32(u32 mem)
case 0x60:
ret = 0;
break;
+ case 0x800:
+ return Pcsx2HostFSread32(mem);
+
default:
ret = psxHu32(mem);
break;
@@ -353,7 +360,7 @@ void __fastcall iopMemWrite16(u32 mem, u16 value)
{
if (t == 0x1d00)
{
- switch (mem & 0xf0)
+ switch (mem & 0x8f0)
{
case 0x10:
// write to ps2 mem
@@ -379,7 +386,6 @@ void __fastcall iopMemWrite16(u32 mem, u16 value)
case 0x60:
psHu32(SBUS_F260) = 0;
return;
-
}
psxSu16(mem) = value; return;
}
@@ -425,7 +431,7 @@ void __fastcall iopMemWrite32(u32 mem, u32 value)
if (t == 0x1d00)
{
MEM_LOG("iop Sif reg write %x value %x", mem, value);
- switch (mem & 0xf0)
+ switch (mem & 0x8f0)
{
case 0x00: // EE write path (EE/IOP readable)
return; // this is the IOP, so read-only (do nothing)
@@ -462,6 +468,11 @@ void __fastcall iopMemWrite32(u32 mem, u32 value)
case 0x60:
psHu32(SBUS_F260) = 0;
return;
+
+ case 0x800:
+ Pcsx2HostFSwrite32(mem, value);
+ return;
+
}
psxSu32(mem) = value;
diff --git a/pcsx2/pcsx2hostfs.cpp b/pcsx2/pcsx2hostfs.cpp
new file mode 100644
index 0000000000..bf6e24bc7b
--- /dev/null
+++ b/pcsx2/pcsx2hostfs.cpp
@@ -0,0 +1,199 @@
+/* PCSX2 - PS2 Emulator for PCs
+ * Copyright (C) 2002-2009 PCSX2 Dev Team
+ *
+ * PCSX2 is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU Lesser General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with PCSX2.
+ * If not, see .
+ */
+
+
+#include "PrecompiledHeader.h"
+#include "IopCommon.h"
+#include "Utilities/Console.h"
+#include
+
+#pragma optimize("", off)
+
+#define PS2E_FIO_OPEN_CMD 0xcc2e0101
+#define PS2E_FIO_CLOSE_CMD 0xcc2e0102
+#define PS2E_FIO_READ_CMD 0xcc2e0103
+#define PS2E_FIO_WRITE_CMD 0xcc2e0104
+#define PS2E_FIO_LSEEK_CMD 0xcc2e0105
+#define PS2E_FIO_OPENDIR_CMD 0xcc2e0106
+#define PS2E_FIO_CLOSEDIR_CMD 0xcc2e0107
+#define PS2E_FIO_READDIR_CMD 0xcc2e0108
+#define PS2E_FIO_REMOVE_CMD 0xcc2e0109
+#define PS2E_FIO_MKDIR_CMD 0xcc2e010a
+#define PS2E_FIO_RMDIR_CMD 0xcc2e010b
+
+#define PS2E_FIO_PRINTF_CMD 0xcc2e0201
+
+#define PS2E_FIO_MAGIC 'E2SP'
+
+u32 functionId;
+u32 paramsAddress;
+u32 paramsLength;
+u32 returnValue;
+
+#define IOP_RDONLY 0x0001
+#define IOP_WRONLY 0x0002
+#define IOP_RDWR 0x0003
+#define IOP_NBLOCK 0x0010
+#define IOP_APPEND 0x0100
+#define IOP_CREAT 0x0200
+#define IOP_TRUNC 0x0400
+#define IOP_NOWAIT 0x8000
+
+int pcsx2fio_open_file(char *path, int flags)
+{
+ path++;
+ int mode = 0;
+
+ switch(flags&IOP_RDWR)
+ {
+ case IOP_RDONLY:
+ mode = O_RDONLY;
+ break;
+ case IOP_WRONLY:
+ mode = O_WRONLY;
+ break;
+ case IOP_RDWR:
+ mode = O_RDWR;
+ break;
+ }
+ if(flags&IOP_CREAT)
+ mode |= O_CREAT;
+ if(flags&IOP_APPEND)
+ mode |= O_APPEND;
+ if(flags&IOP_TRUNC)
+ mode |= O_TRUNC;
+
+ return open(path,mode);
+}
+
+int pcsx2fio_close_file(int fd)
+{
+ return close(fd);
+}
+
+int pcsx2fio_lseek_file(int fd, unsigned int offset, int whence)
+{
+ return lseek(fd,offset,whence);
+}
+
+int pcsx2fio_write_file(int fd, char *buf, int length)
+{
+ return write(fd,buf,length);
+}
+
+int pcsx2fio_read_file(int fd, char *buf, int length)
+{
+ return read(fd,buf,length);
+}
+
+int pcsx2fio_remove(char *name)
+{
+ return unlink(name);
+}
+
+int pcsx2fio_mkdir(char *name, int mode)
+{
+ return mkdir(name);
+}
+
+int pcsx2fio_rmdir(char *name)
+{
+ return rmdir(name);
+}
+
+int pcsx2fio_open_dir(char *path)
+{
+ return -1;
+}
+
+int pcsx2fio_read_dir(int fd, void *buf)
+{
+ return -1;
+}
+
+int pcsx2fio_close_dir(int fd)
+{
+ return -1;
+}
+
+int pcsx2fio_write_tty(const char* text, int length)
+{
+ wxString s = wxString::FromUTF8(text,length);
+
+ return printf("%s",s.ToAscii());
+}
+
+#define PARAM(offset,type) (*(type*)(buffer+(offset)))
+#define PARAMP(offset,type) (type*)iopPhysMem(PARAM(offset,u32))
+#define PARAMSTR(offset) ((char*)(buffer+(offset)))
+void Pcsx2HostFsExec()
+{
+ u8* buffer = (u8*)iopPhysMem(paramsAddress);
+
+ switch(functionId)
+ {
+ case PS2E_FIO_OPEN_CMD: returnValue = pcsx2fio_open_file(PARAMSTR(4),PARAM(0,s32)); break;
+ case PS2E_FIO_CLOSE_CMD: returnValue = pcsx2fio_close_file(PARAM(0,s32)); break;
+ case PS2E_FIO_READ_CMD: returnValue = pcsx2fio_read_file(PARAM(0,s32),PARAMP(4,char),PARAM(8,s32)); break;
+ case PS2E_FIO_WRITE_CMD: returnValue = pcsx2fio_write_file(PARAM(0,s32),PARAMP(4,char),PARAM(8,s32)); break;
+ case PS2E_FIO_LSEEK_CMD: returnValue = pcsx2fio_lseek_file(PARAM(0,s32),PARAM(4,s32),PARAM(8,s32)); break;
+ case PS2E_FIO_REMOVE_CMD: returnValue = pcsx2fio_remove(PARAMSTR(0)); break;
+ case PS2E_FIO_OPENDIR_CMD: returnValue = pcsx2fio_open_dir(PARAMSTR(0)); break;
+ case PS2E_FIO_CLOSEDIR_CMD: returnValue = pcsx2fio_close_dir(PARAM(0,s32)); break;
+ case PS2E_FIO_READDIR_CMD: returnValue = pcsx2fio_read_dir(PARAM(0,s32),PARAMP(4,void)); break;
+ case PS2E_FIO_MKDIR_CMD: returnValue = pcsx2fio_mkdir(PARAMSTR(4),PARAM(0,s32)); break;
+ case PS2E_FIO_RMDIR_CMD: returnValue = pcsx2fio_rmdir(PARAMSTR(0)); break;
+
+ case PS2E_FIO_PRINTF_CMD: returnValue = pcsx2fio_write_tty(PARAMSTR(0),paramsLength); break;
+ }
+}
+
+void Pcsx2HostFSwrite32(u32 addr, u32 value)
+{
+ switch(addr&0xF)
+ {
+ case 0:
+ if(value==1)
+ Pcsx2HostFsExec();
+ break;
+ case 4:
+ paramsLength = value;
+ break;
+ case 8:
+ paramsAddress = value;
+ break;
+ case 12:
+ functionId = value;
+ break;
+ }
+}
+
+u32 Pcsx2HostFSread32(u32 addr)
+{
+ switch(addr&0xF)
+ {
+ case 0:
+ return PS2E_FIO_MAGIC;
+ break;
+ case 4:
+ break;
+ case 8:
+ break;
+ case 12:
+ return returnValue;
+ break;
+ }
+ return 0;
+}
\ No newline at end of file
diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
index ccd8b7f123..fe3c53837e 100644
--- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
+++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj
@@ -1114,6 +1114,10 @@
RelativePath="..\..\IopSio2.h"
>
+
+
diff --git a/pcsx2hostfs/CHANGELOG b/pcsx2hostfs/CHANGELOG
new file mode 100644
index 0000000000..6a4be6d3db
--- /dev/null
+++ b/pcsx2hostfs/CHANGELOG
@@ -0,0 +1,64 @@
+PS2Link (C) 2003 Tord Lindstrom (pukko@home.se)
+ (C) 2003,2004 adresd (adresd_ps2dev@yahoo.com)
+ (C) 2004 Lukasz Bruun (mail@lukasz.dk)
+ (C) 2006 Drakonite (makeshift_ps2dev@123mail.org)
+------------------------------------------------------------------------
+
+2006-02-18 Version 1.46
+ - Added Cached Config support
+ - Extra config disabled, at least while cached config is enabled
+ - Some code cleanup and reordering
+ - More consistant environment (no longer has sio2man and mcman
+ loaded when booting from MC, assuming cached_cfg enabled)
+ - Boots from essentially anywhere now
+ - Some code uglyfications
+ - Elf in bin/ is now packed using ps2-packer
+ - Lots of version bumping from beta test versions
+ - Other stuff
+
+2006-01-25 Version 1.32
+ - Cleaned up and repaired Makefiles
+ - Disabled 'check' dependency of make dist as it seems to
+ be broken, dist was broken anyways so it doesn't seem like
+ check is being used
+ - Builtin_irx made default out of svn
+ - Bumped version for tag
+
+2004-09-25 Version 1.30
+ - Added IOP exception handling
+ - Changed IPCONFIG.DAT & EXTRA.CNF a little and added better
+ parsing code.
+
+2004-05-24 Version 1.24
+ - Made changes for compiling with ps2sdk, introduction of imports.lst/.h
+ and many changes in IOP part to use ioman.h.
+ - Set default values for irx_mod pointers and sizes for cached modules
+ to ensure they were in .bss and not trashed on pko_reset.
+ - Set default values for ip parameters for the same reason as above.
+ - New command writemem
+ - Can load irx files from a defined file in IPCONFIG.DAT
+ - All-In-One elf (irx's embedded in the elf) build target.
+
+2004-02-08 Version 1.23
+ - Some new commands stop/start vu, dump mem, dump reg, gsexec
+
+2004-02-06 Version 1.22
+ - HOST: getdir support (so ps2 can get filelist from host:, using ioman calls)
+
+2004-01-29 Version 1.21
+ - Fixed Host loading (both IRX and ipconfig) - prob with reset (CLEARSPU), but runs fine.
+ - Added sbv for prefix checking, to remove LMB for mc load.
+ - Added screen/console exception dump selection.
+ - Consistent IOP reset for both HOST and other FS load methods.
+ - Removed DMS specific loading, module loading made more general.
+ - Handles being run from ANY mc dir now.
+ - Cleaned up highloading version.
+
+2003-12-31 Version 1.2
+ - Binary Release Version
+
+2003-12-15 Version 1.1
+ - Made compatible with ps2drv, for eth and HDD access together.
+
+2003-05-12 Version 1.0
+ - First release
diff --git a/pcsx2hostfs/LICENSE b/pcsx2hostfs/LICENSE
new file mode 100644
index 0000000000..d754d0d730
--- /dev/null
+++ b/pcsx2hostfs/LICENSE
@@ -0,0 +1,174 @@
+
+COPYRIGHT FOR PS2LINK
+----------------------------------------------------------------------------
+
+ Copyright (c) 2003 Tord Lindstrom (pukko@home.se)
+ (c) 2003 adresd (adresd_ps2dev@yahoo.com)
+ (c) 2004 Khaled Daham
+ (c) 2004 Nicolas 'Pixel' Noble
+
+ The Academic Free License
+ v. 2.0
+
+This Academic Free License (the "License") applies to any original work
+of authorship (the "Original Work") whose owner (the "Licensor") has
+placed the following notice immediately following the copyright notice
+for the Original Work:
+
+ *Licensed under the Academic Free License version 2.0*
+
+1) *Grant of Copyright License.* Licensor hereby grants You a
+world-wide, royalty-free, non-exclusive, perpetual, sublicenseable
+license to do the following:
+
+ a) to reproduce the Original Work in copies;
+
+ b) to prepare derivative works ("Derivative Works") based upon the
+ Original Work;
+
+ c) to distribute copies of the Original Work and Derivative Works to
+ the public;
+
+ d) to perform the Original Work publicly; and
+
+ e) to display the Original Work publicly.
+
+2) *Grant of Patent License.* Licensor hereby grants You a world-wide,
+royalty-free, non-exclusive, perpetual, sublicenseable license, under
+patent claims owned or controlled by the Licensor that are embodied in
+the Original Work as furnished by the Licensor, to make, use, sell and
+offer for sale the Original Work and Derivative Works.
+
+3) *Grant of Source Code License.* The term "Source Code" means the
+preferred form of the Original Work for making modifications to it and
+all available documentation describing how to modify the Original Work.
+Licensor hereby agrees to provide a machine-readable copy of the Source
+Code of the Original Work along with each copy of the Original Work that
+Licensor distributes. Licensor reserves the right to satisfy this
+obligation by placing a machine-readable copy of the Source Code in an
+information repository reasonably calculated to permit inexpensive and
+convenient access by You for as long as Licensor continues to distribute
+the Original Work, and by publishing the address of that information
+repository in a notice immediately following the copyright notice that
+applies to the Original Work.
+
+4) *Exclusions From License Grant. *Neither the names of Licensor, nor
+the names of any contributors to the Original Work, nor any of their
+trademarks or service marks, may be used to endorse or promote products
+derived from this Original Work without express prior written permission
+of the Licensor. Nothing in this License shall be deemed to grant any
+rights to trademarks, copyrights, patents, trade secrets or any other
+intellectual property of Licensor except as expressly stated herein. No
+patent license is granted to make, use, sell or offer to sell
+embodiments of any patent claims other than the licensed claims defined
+in Section 2. No right is granted to the trademarks of Licensor even if
+such marks are included in the Original Work. Nothing in this License
+shall be interpreted to prohibit Licensor from licensing under different
+terms from this License any Original Work that Licensor otherwise would
+have a right to license.
+
+5) This section intentionally omitted.
+
+6) *Attribution Rights.* You must retain, in the Source Code of any
+Derivative Works that You create, all copyright, patent or trademark
+notices from the Source Code of the Original Work, as well as any
+notices of licensing and any descriptive text identified therein as an
+"Attribution Notice." You must cause the Source Code for any Derivative
+Works that You create to carry a prominent Attribution Notice reasonably
+calculated to inform recipients that You have modified the Original Work.
+
+7) *Warranty of Provenance and Disclaimer of Warranty.* Licensor
+warrants that the copyright in and to the Original Work and the patent
+rights granted herein by Licensor are owned by the Licensor or are
+sublicensed to You under the terms of this License with the permission
+of the contributor(s) of those copyrights and patent rights. Except as
+expressly stated in the immediately proceeding sentence, the Original
+Work is provided under this License on an "AS IS" BASIS and WITHOUT
+WARRANTY, either express or implied, including, without limitation, the
+warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL
+WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential
+part of this License. No license to Original Work is granted hereunder
+except under this disclaimer.
+
+8) *Limitation of Liability.* Under no circumstances and under no legal
+theory, whether in tort (including negligence), contract, or otherwise,
+shall the Licensor be liable to any person for any direct, indirect,
+special, incidental, or consequential damages of any character arising
+as a result of this License or the use of the Original Work including,
+without limitation, damages for loss of goodwill, work stoppage,
+computer failure or malfunction, or any and all other commercial damages
+or losses. This limitation of liability shall not apply to liability for
+death or personal injury resulting from Licensor's negligence to the
+extent applicable law prohibits such limitation. Some jurisdictions do
+not allow the exclusion or limitation of incidental or consequential
+damages, so this exclusion and limitation may not apply to You.
+
+9) *Acceptance and Termination.* If You distribute copies of the
+Original Work or a Derivative Work, You must make a reasonable effort
+under the circumstances to obtain the express assent of recipients to
+the terms of this License. Nothing else but this License (or another
+written agreement between Licensor and You) grants You permission to
+create Derivative Works based upon the Original Work or to exercise any
+of the rights granted in Section 1 herein, and any attempt to do so
+except under the terms of this License (or another written agreement
+between Licensor and You) is expressly prohibited by U.S. copyright law,
+the equivalent laws of other countries, and by international treaty.
+Therefore, by exercising any of the rights granted to You in Section 1
+herein, You indicate Your acceptance of this License and all of its
+terms and conditions.
+
+10) *Termination for Patent Action.* This License shall terminate
+automatically and You may no longer exercise any of the rights granted
+to You by this License as of the date You commence an action, including
+a cross-claim or counterclaim, for patent infringement (i) against
+Licensor with respect to a patent applicable to software or (ii) against
+any entity with respect to a patent applicable to the Original Work (but
+excluding combinations of the Original Work with other software or
+hardware).
+
+11) *Jurisdiction, Venue and Governing Law.* Any action or suit relating
+to this License may be brought only in the courts of a jurisdiction
+wherein the Licensor resides or in which Licensor conducts its primary
+business, and under the laws of that jurisdiction excluding its
+conflict-of-law provisions. The application of the United Nations
+Convention on Contracts for the International Sale of Goods is expressly
+excluded. Any use of the Original Work outside the scope of this License
+or after its termination shall be subject to the requirements and
+penalties of the U.S. Copyright Act, 17 U.S.C. § 101 et seq., the
+equivalent laws of other countries, and international treaty. This
+section shall survive the termination of this License.
+
+12) *Attorneys Fees.* In any action to enforce the terms of this License
+or seeking damages relating thereto, the prevailing party shall be
+entitled to recover its costs and expenses, including, without
+limitation, reasonable attorneys' fees and costs incurred in connection
+with such action, including any appeal of such action. This section
+shall survive the termination of this License.
+
+13) *Miscellaneous.* This License represents the complete agreement
+concerning the subject matter hereof. If any provision of this License
+is held to be unenforceable, such provision shall be reformed only to
+the extent necessary to make it enforceable.
+
+14) *Definition of "You" in This License.* "You" throughout this
+License, whether in upper or lower case, means an individual or a legal
+entity exercising rights under, and complying with all of the terms of,
+this License. For legal entities, "You" includes any entity that
+controls, is controlled by, or is under common control with you. For
+purposes of this definition, "control" means (i) the power, direct or
+indirect, to cause the direction or management of such entity, whether
+by contract or otherwise, or (ii) ownership of fifty percent (50%) or
+more of the outstanding shares, or (iii) beneficial ownership of such
+entity.
+
+15) *Right to Use.* You may use the Original Work in all ways not
+otherwise restricted or conditioned by this License or by law, and
+Licensor promises not to interfere with or be responsible for such uses
+by You.
+
+This license is Copyright (C) 2003 Lawrence E. Rosen. All rights
+reserved. Permission is hereby granted to copy and distribute this
+license without modification. This license may not be modified without
+the express written permission of its copyright owner.
+
diff --git a/pcsx2hostfs/Makefile b/pcsx2hostfs/Makefile
new file mode 100644
index 0000000000..9c3df22c58
--- /dev/null
+++ b/pcsx2hostfs/Makefile
@@ -0,0 +1,134 @@
+# Compilation variables
+
+# Set this to 1 to enable debug mode
+DEBUG = 1
+
+# Set this to 1 to build a highloading version, 0 for normal low version
+LOADHIGH = 0
+
+# Set this to 1 to build ps2link with all the needed IRX builtins
+BUILTIN_IRXS = 1
+
+# Set this to 1 to enable caching of config files
+CACHED_CFG = 1
+
+# Set this to 1 to enable zero-copy on fileio writes.
+ZEROCOPY = 0
+
+# Set this to 1 to power off the ps2 when the reset button is tapped
+# otherwise it will try and reset ps2link
+PWOFFONRESET = 1
+
+# Set this to 1 to hook the kernel CreateThread/DeleteThread calls.
+# Note that this will cause problems when loading PS2LINK.ELF from PS2LINK...
+HOOK_THREADS = 0
+
+# Set this to 1 to enable screenshots.
+# Note that this adds a dependency with libgraph and libdma
+SCREENSHOTS = 0
+
+# Set to the path where ps2eth is located
+PS2ETH = $(PS2DEV)/ps2eth
+
+SHELL=/usr/bin/env bash
+BIN2O=$(PS2SDK)/bin/bin2o
+RM=rm -f
+
+#
+# You shouldn't need to modify anything below this point
+#
+
+include $(PS2SDK)/Defs.make
+
+EEFILES=ee/pcsx2hostfs_ldr.elf
+
+IRXFILES=iop/pcsx2hostfs.irx $(PS2SDK)/iop/irx/ioptrap.irx
+
+VARIABLES=DEBUG=$(DEBUG) LOADHIGH=$(LOADHIGH) BUILTIN_IRXS=$(BUILTIN_IRXS) ZEROCOPY=$(ZEROCOPY) PWOFFONRESET=$(PWOFFONRESET) CACHED_CFG=$(CACHED_CFG) HOOK_THREADS=$(HOOK_THREADS) SCREENSHOTS=$(SCREENSHOTS)
+
+ifeq ($(BUILTIN_IRXS),1)
+TARGETS = iop builtins ee
+else
+TARGETS = ee iop
+endif
+
+all: $(TARGETS)
+ifneq ($(BUILTIN_IRXS),1)
+ @for file in $(IRXFILES); do \
+ new=`echo $${file/*\//}|tr "[:lower:]" "[:upper:]"`; \
+ cp $$file bin/$$new; \
+ done;
+endif
+ @for file in $(EEFILES); do \
+ new=`echo $${file/*\//}|tr "[:lower:]" "[:upper:]"`; \
+ cp $$file bin/$$new; \
+ done;
+
+ee:
+ $(VARIABLES) $(MAKE) -C ee
+
+iop:
+ $(VARIABLES) $(MAKE) -C iop
+
+clean:
+ $(MAKE) -C ee clean
+ $(MAKE) -C iop clean
+
+check:
+ $(VARIABLES) $(MAKE) -C ee check
+
+# Creates a zip from what you have
+dist: all
+ @rm -rf dist
+ @mkdir -p dist/ps2link
+ifneq ($(BUILTIN_IRXS),1)
+ @for file in $(IRXFILES); do \
+ new=`echo $${file/*\//}|tr "[:lower:]" "[:upper:]"`; \
+ cp $$file dist/ps2link/$$new; \
+ done;
+endif
+ @for file in $(EEFILES); do \
+ new=`echo $${file/*\//}|tr "[:lower:]" "[:upper:]"`; \
+ cp $$file dist/ps2link/$$new; \
+ done;
+ cd dist; \
+ tar -jcf ps2link.tar.bz2 ps2link/
+
+RELEASE_FILES=bin/*IRX bin/*DAT bin/*cnf bin/*ELF LICENSE README
+#
+# Creates zip with iso and all necessary files of last release
+release:
+ @rm -rf RELEASE
+ @mkdir -p RELEASE
+ @VERSION=`cvs log Makefile | grep -A 1 symbolic | tail -1 | awk '{print substr($$1, 0, length($$1)-1)}'`; \
+ cd RELEASE; \
+ cvs co -r $$VERSION ps2link; \
+ cd ps2link; \
+ make; \
+ make check; \
+ mkdir -p bin; \
+ for file in $(IRXFILES); do \
+ new=`echo $${file/*\//}|tr "[:lower:]" "[:upper:]"`; \
+ cp $$file bin/$$new; \
+ done; \
+ for file in $(EEFILES); do \
+ new=`echo $${file/*\//}|tr "[:lower:]" "[:upper:]"`; \
+ cp $$file bin/$$new; \
+ done; \
+ dd if=/dev/zero of=bin/dummy bs=1024 count=28672; \
+ ps2mkisofs -o ps2link_$$VERSION.iso bin/; \
+ rm bin/dummy; \
+ tar -jcf ps2link_$$VERSION.tbz $(RELEASE_FILES) ps2link_$$VERSION.iso
+
+docs:
+ doxygen doxy.conf
+
+builtins:
+ @for file in $(IRXFILES); do \
+ basefile=$${file/*\//}; \
+ basefile=$${basefile/\.*/}; \
+ echo "Embedding IRX file $$basefile"; \
+ $(BIN2O) $$file ee/$${basefile}_irx.o _binary_$${basefile}_irx; \
+ done;
+
+.PHONY: iop ee
diff --git a/pcsx2hostfs/README b/pcsx2hostfs/README
new file mode 100644
index 0000000000..ead275d150
--- /dev/null
+++ b/pcsx2hostfs/README
@@ -0,0 +1,46 @@
+PS2Link (C) 2003 Tord Lindstrom (pukko@home.se)
+ (C) 2003,2004 adresd (adresd_ps2dev@yahoo.com)
+ (C) 2003,2004,2005 Khaled (khaled@w-arts.com)
+------------------------------------------------------------------------
+
+Please read the file LICENSE regarding PS2Link licensing.
+
+PS2Link is a 'bootloader' which, used together with an Ethernet driver and
+a TCP/IP stack, enables you to download and execute software on your PS2.
+
+It is designed to run from memory card, cdrom or host drives.
+
+It loads all IRX's at startup and IPCONFIG.DAT for the network settings.
+The IRX's and the IPCONFIG.DAT should be in the directory which PS2LINK is loaded from.
+
+PS2Link requires the following IRX modules:
+PS2LINK.IRX from: ps2link
+PS2DEV9.IRX ps2sdk
+PS2IP.IRX ps2sdk
+IOPTRAP.IRX ps2sdk
+POWEROFF.IRX ps2sdk
+PS2SMAP.IRX ps2eth
+
+Building ps2link requires two projects PS2SDK and PS2ETH.
+
+For building against ps2sdk make sure PS2SDK is set to your ps2sdk release
+dir. If you do not have ps2sdk built, check it out from cvs and set PS2SDK and
+PS2SDKSRC = checked out ps2sdk dir, do 'make' and 'make release'.
+
+Credit for the icon logo goes to Revolt from #ps2dev.
+
+NOTES + WARNINGS:
+ALL IRX FILENAMES SHOULD BE UPPERCASE.
+IPCONFIG.DAT FILENAME SHOULD BE UPPERCASE.
+
+IPCONFIG.DAT uses the following format:
+PS2IPADDRESS NETMASK GATEWAYIP
+seperated by a single space.
+
+You can load addition IRX's by specifying EXTRACNF file in IPCONFIG.DAT. It
+will load the EXTRACNF file and and load all irx's terminated with ';' in the order
+they are listed in the EXTRACNF file. By default the EXTRACNF setting is
+disabled (commented) with '#' in IPCONFIG.DAT, remove the '#' the load the
+EXTRACNF file.
+
+If you have any questions or bugreports about ps2link go to forums.ps2dev.org.
diff --git a/pcsx2hostfs/doxy.conf b/pcsx2hostfs/doxy.conf
new file mode 100644
index 0000000000..f3f3f3c698
--- /dev/null
+++ b/pcsx2hostfs/doxy.conf
@@ -0,0 +1,1098 @@
+# Doxyfile 1.3.5
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = ps2link
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = 1.2
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = ps2link-doc
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch,
+# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en
+# (Japanese with English messages), Korean, Norwegian, Polish, Portuguese,
+# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# This tag can be used to specify the encoding used in the generated output.
+# The encoding is not always determined by the language that is chosen,
+# but also whether or not the output is meant for Windows or non-Windows users.
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
+# forces the Windows encoding (this is the default for the Windows binary),
+# whereas setting the tag to NO uses a Unix-style encoding (the default for
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is used
+# as the annotated text. Otherwise, the brief description is used as-is. If left
+# blank, the following values are used ("$name" is automatically replaced with the
+# name of the entity): "The $name class" "The $name widget" "The $name file"
+# "is" "provides" "specifies" "contains" "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited
+# members of a class in the documentation of that class as if those members were
+# ordinary class members. Constructors, destructors and assignment operators of
+# the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. It is allowed to use relative paths in the argument list.
+
+STRIP_FROM_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
+# only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text.
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE = warn.log
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT =
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
+# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc
+
+FILE_PATTERNS =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories
+# that are symbolic links (a Unix filesystem feature) are excluded from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+
+EXCLUDE_PATTERNS = */samples/*
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command , where
+# is the value of the INPUT_FILTER tag, and is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+
+INPUT_FILTER =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse the
+# parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or
+# super classes. Setting the tag to NO turns the diagrams off. Note that this
+# option is superseded by the HAVE_DOT option below. This is only a fallback. It is
+# recommended to install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_WIDTH = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes that
+# lay further from the root node will be omitted. Note that setting this option to
+# 1 or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that a graph may be further truncated if the graph's image dimensions are
+# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT).
+# If 0 is used for the depth value (the default), the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
diff --git a/pcsx2hostfs/ee/Makefile b/pcsx2hostfs/ee/Makefile
new file mode 100644
index 0000000000..be5e3bd8c6
--- /dev/null
+++ b/pcsx2hostfs/ee/Makefile
@@ -0,0 +1,73 @@
+EE_BIN = pcsx2hostfs_ldr.elf
+EE_OBJS = ps2link.o excepHandler.o exceptions.o
+EE_INCS += -I../include
+
+# This is for the sbv patch
+SBVLITE = $(PS2SDK)/sbv
+EE_INCS += -I$(SBVLITE)/include
+EE_LDFLAGS += -L$(SBVLITE)/lib
+EE_LIBS += -lpatches -ldebug
+ifeq ($(SCREENSHOTS),1)
+EE_LIBS += -lpacket -ldma
+endif
+
+# Normal low loading version
+ifeq ($(BUILTIN_IRXS),1)
+LOADADDR = 0xa8000
+else
+LOADADDR = 0xc0000
+endif
+STACKADDR = 0x100000
+
+# This is to build a highloading version
+ifeq ($(LOADHIGH),1)
+ifeq ($(BUILTIN_IRXS),1)
+LOADADDR = 0x1ee8000
+else
+LOADADDR = 0x1f00000
+endif
+STACKADDR = 0x1f40000
+EE_CFLAGS += -D_LOADHIGHVER
+endif
+
+# This is to builtin the IRXs into ps2link
+ifeq ($(BUILTIN_IRXS),1)
+EE_CFLAGS += -DBUILTIN_IRXS
+EE_LDFLAGS += pcsx2hostfs_irx.o ioptrap_irx.o
+endif
+
+ifeq ($(BUILTIN_IRXS),1)
+ifeq ($(CACHED_CFG),1)
+EE_CFLAGS += -DUSE_CACHED_CFG
+endif
+endif
+
+# This is to enable the debug mode into ps2link
+ifeq ($(DEBUG),1)
+EE_CFLAGS += -DDEBUG -g
+endif
+
+# Enable screenshot functionality
+ifeq ($(SCREENSHOTS),1)
+EE_CFLAGS += -DSCREENSHOTS
+endif
+
+LDPARAMS := -Wl,--defsym -Wl,_stack_size=0x8000 -Wl,--defsym -Wl,_stack=$(STACKADDR)
+EE_LDFLAGS += -Wl,-Ttext -Wl,$(LOADADDR) $(LDPARAMS)
+
+ifeq ($(DEBUG),1)
+EE_LDFLAGS += -g
+else
+EE_LDFLAGS += -s
+endif
+
+all: $(EE_BIN)
+
+clean:
+ -rm -f $(EE_OBJS) $(EE_BIN)
+
+check: $(EE_BIN)
+ @ee-readelf -l $(EE_BIN) | awk ' /LOAD/ { if ((spare = (-($$4 + $$6) + ("'$(STACKADDR)'" - "0x8000"))) <= 0) { printf("PS2Link is too big, %i (0x%x) bytes missing\n", -spare, -spare); exit -1; } else { printf("PS2Link has %i (0x%x) spare bytes\n", spare, spare) } } '
+
+include $(PS2SDK)/Defs.make
+include Rules.make
diff --git a/pcsx2hostfs/ee/Rules.make b/pcsx2hostfs/ee/Rules.make
new file mode 100644
index 0000000000..f3ff43b83f
--- /dev/null
+++ b/pcsx2hostfs/ee/Rules.make
@@ -0,0 +1,45 @@
+
+# Include directories
+EE_INCS := -I$(PS2SDK)/ee/include -I$(PS2SDK)/common/include -I. $(EE_INCS)
+
+# C compiler flags
+EE_CFLAGS := -D_EE -O2 -G0 -Wall $(EE_CFLAGS)
+
+# C++ compiler flags
+EE_CXXFLAGS := -D_EE -O2 -G0 -Wall $(EE_CXXFLAGS)
+
+# Linker flags
+EE_LDFLAGS := -L$(PS2SDK)/ee/lib $(EE_LDFLAGS)
+
+# Assembler flags
+EE_ASFLAGS := -G0 $(EE_ASFLAGS)
+
+# Link with following libraries. This is a special case, and instead of
+# allowing the user to override the library order, we always make sure
+# libkernel is the last library to be linked.
+EE_LIBS += -lc -lkernel
+
+# Externally defined variables: EE_BIN, EE_OBJS, EE_LIB
+
+# These macros can be used to simplify certain build rules.
+EE_C_COMPILE = $(EE_CC) $(EE_CFLAGS) $(EE_INCS)
+EE_CXX_COMPILE = $(EE_CC) $(EE_CXXFLAGS) $(EE_INCS)
+
+%.o : %.c
+ $(EE_CC) $(EE_CFLAGS) $(EE_INCS) -c $< -o $@
+
+%.o : %.cpp
+ $(EE_CXX) $(EE_CXXFLAGS) $(EE_INCS) -c $< -o $@
+
+%.o : %.S
+ $(EE_CC) $(EE_CFLAGS) $(EE_INCS) -c $< -o $@
+
+%.o : %.s
+ $(EE_AS) $(EE_ASFLAGS) $< -o $@
+
+$(EE_BIN) : $(EE_OBJS) $(PS2SDK)/ee/startup/crt0.o
+ $(EE_CC) -nostartfiles -T$(PS2SDK)/ee/startup/linkfile $(EE_LDFLAGS) \
+ -o $(EE_BIN) $(PS2SDK)/ee/startup/crt0.o $(EE_OBJS) $(EE_LIBS)
+
+$(EE_LIB) : $(EE_OBJS)
+ $(EE_AR) cru $(EE_LIB) $(EE_OBJS)
diff --git a/pcsx2hostfs/ee/crt0.s b/pcsx2hostfs/ee/crt0.s
new file mode 100644
index 0000000000..1e3ef51530
--- /dev/null
+++ b/pcsx2hostfs/ee/crt0.s
@@ -0,0 +1,113 @@
+.set noat
+.set noreorder
+
+.global _start
+.global _exit
+
+.text
+ nop
+ nop
+_start:
+ lui $2,%hi(_args_ptr)
+ addiu $2,$2, %lo(_args_ptr)
+ sw $4,($2)
+# Clear bss
+zerobss:
+ lui $2,%hi(_fbss)
+ lui $3,%hi(_end)
+ addiu $2,$2,%lo(_fbss)
+ addiu $3,$3,%lo(_end)
+loop:
+ nop
+ nop
+ sq $0,($2)
+ sltu $1,$2,$3
+ bne $1,$0,loop
+ addiu $2,$2,16
+# Thread
+ lui $4,%hi(_gp)
+ lui $5,%hi(_stack)
+ lui $6,%hi(_stack_size)
+ lui $7,%hi(_args)
+ lui $8,%hi(_exit)
+ addiu $4,$4,%lo(_gp)
+ addiu $5,$5,%lo(_stack)
+ addiu $6,$6,%lo(_stack_size)
+ addiu $7,$7,%lo(_args)
+ addiu $8,$8,%lo(_exit)
+ move $28,$4
+ addiu $3,$0,60
+ syscall
+ move $29, $2
+
+# Heap
+ addiu $3,$0,61
+ lui $4,%hi(_end)
+ addiu $4,$4,%lo(_end)
+ lui $5,%hi(_heap_size)
+ addiu $5,$5,%lo(_heap_size)
+ syscall
+ nop
+
+# Cache
+ li $3, 100
+ move $4,$0
+ syscall
+ nop
+
+# Jump main
+ ei
+
+ # Check if we got args from system
+ lui $2, %hi(_args)
+ addiu $2, %lo(_args)
+ lw $3, 0($2)
+ bnez $3, _gotArgv # Started w (Load)ExecPS2
+ nop
+
+ # Check args via $a0
+ lui $2,%hi(_args_ptr)
+ addiu $2,$2,%lo(_args_ptr)
+ lw $3,0($2)
+
+ beqzl $3, _goMain
+ addu $4, $0, $0
+
+ addiu $2, $3, 4
+ b _gotArgv
+ nop
+
+_gotArgv:
+ lw $4, ($2)
+ addiu $5, $2, 4
+_goMain:
+ jal main
+ nop
+
+ # Check if we got our args in $a0 again
+ la $4, _args_ptr
+ lw $5, 0($4)
+ beqz $5, _exit
+ nop
+_root:
+ lw $6, 0($5)
+ sw $0, 0($6)
+ # Call ExitDeleteThread()
+ addiu $3, $0, 36
+ syscall
+ nop
+_exit:
+# Exit
+ # Should call Exit(retval) if not called by pukklink
+ addiu $3,$0,35
+ syscall
+ move $4, $2
+ nop
+
+ .bss
+ .align 6
+_args: .space 256+16*4+4
+
+ .data
+_args_ptr:
+ .space 4
diff --git a/pcsx2hostfs/ee/excepHandler.c b/pcsx2hostfs/ee/excepHandler.c
new file mode 100644
index 0000000000..307ae3ce8c
--- /dev/null
+++ b/pcsx2hostfs/ee/excepHandler.c
@@ -0,0 +1,170 @@
+/*********************************************************************
+ * Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
+ * Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com)
+ * This file is subject to the terms and conditions of the PS2Link License.
+ * See the file LICENSE in the main directory of this distribution for more
+ * details.
+ */
+
+#include "stdio.h"
+#include
+#include
+#include "excepHandler.h"
+#include "debug.h"
+
+extern int _gp;
+int userThreadID;
+int excepscrdump;
+
+////////////////////////////////////////////////////////////////////////
+typedef union
+{
+ unsigned int uint128 __attribute__(( mode(TI) ));
+ unsigned long uint64[2];
+} eeReg __attribute((packed));
+
+////////////////////////////////////////////////////////////////////////
+// Prototypes
+void pkoDebug(int cause, int badvaddr, int status, int epc, eeReg *regs);
+
+extern void pkoExceptionHandler(void);
+
+////////////////////////////////////////////////////////////////////////
+static const unsigned char regName[32][5] =
+{
+ "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
+ "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
+ "t8", "t9", "s0", "s1", "s2", "s3", "s4", "s5",
+ "s6", "s7", "k0", "k1", "gp", "sp", "fp", "ra"
+};
+
+static char codeTxt[14][24] =
+{
+ "Interrupt", "TLB modification", "TLB load/inst fetch", "TLB store",
+ "Address load/inst fetch", "Address store", "Bus error (instr)",
+ "Bus error (data)", "Syscall", "Breakpoint", "Reserved instruction",
+ "Coprocessor unusable", "Arithmetic overflow", "Trap"
+};
+
+char _exceptionStack[8*1024] __attribute__((aligned(16)));
+eeReg _savedRegs[32+4] __attribute__((aligned(16)));
+
+////////////////////////////////////////////////////////////////////////
+// The 'ee exception handler', only dumps registers to console or screen atm
+void
+pkoDebug(int cause, int badvaddr, int status, int epc, eeReg *regs)
+{
+ int i;
+ int code;
+ // extern void printf(char *, ...);
+ static void (* excpPrintf)(const char *, ...);
+
+ FlushCache(0);
+ FlushCache(2);
+
+#if 1
+ if (userThreadID) {
+ TerminateThread(userThreadID);
+ DeleteThread(userThreadID);
+ }
+#endif
+
+ code = cause & 0x7c;
+
+ if (excepscrdump)
+ {
+ init_scr();
+ excpPrintf = scr_printf;
+ }
+ else excpPrintf = (void*)printf;
+
+ excpPrintf("\n\n EE Exception handler: %s exception\n\n",
+ codeTxt[code>>2]);
+
+ excpPrintf(" Cause %08X BadVAddr %08X Status %08X EPC %08X\n\n",
+ cause, badvaddr, status, epc);
+
+ for(i = 0; i < 32/2; i++) {
+ excpPrintf("%4s: %016lX%016lX %4s: %016lX%016lX\n",
+ regName[i], regs[i].uint64[1], regs[i].uint64[0],
+ regName[i+16], regs[i+16].uint64[1], regs[i+16].uint64[0]);
+ }
+ excpPrintf("\n");
+ SleepThread();
+}
+
+////////////////////////////////////////////////////////////////////////
+// The 'iop exception handler', only dumps registers to console or screen atm
+
+void iopException(int cause, int badvaddr, int status, int epc, u32 *regs, int repc, char* name)
+{
+ int i;
+ int code;
+ // extern void printf(char *, ...);
+ static void (* excpPrintf)(const char *, ...);
+
+ FlushCache(0);
+ FlushCache(2);
+
+#if 1
+ if (userThreadID) {
+ TerminateThread(userThreadID);
+ DeleteThread(userThreadID);
+ }
+#endif
+
+ code = cause & 0x7c;
+
+ if(excepscrdump)
+ {
+ init_scr();
+ excpPrintf = scr_printf;
+ }
+ else excpPrintf = (void*)printf;
+
+ excpPrintf("\n\n IOP Exception handler: %s exception\n\n",
+ codeTxt[code>>2]);
+
+ excpPrintf(" Module Name \"%s\" Relative EPC %08X\n\n",
+ name, repc);
+
+
+ excpPrintf(" Cause %08X BadVAddr %08X Status %08X EPC %08X\n\n",
+ cause, badvaddr, status, epc);
+
+ for(i = 0; i < 32/4; i++)
+ {
+ excpPrintf(" %4s: %08X %4s: %08X %4s: %08X %4s: %08X\n",
+ regName[i], regs[i], regName[i+8], regs[i+8],
+ regName[i+16], regs[i+16], regName[i+24], regs[i+24]);
+ }
+
+ excpPrintf("\n");
+
+
+
+ SleepThread();
+}
+
+
+////////////////////////////////////////////////////////////////////////
+// Installs ee exception handlers for the 'usual' exceptions and iop
+// exception callback
+void
+installExceptionHandlers(void)
+{
+ int i;
+
+ // Skip exception #8 (syscall) & 9 (breakpoint)
+ for (i = 1; i < 4; i++) {
+ SetVTLBRefillHandler(i, pkoExceptionHandler);
+ }
+ for (i = 4; i < 8; i++) {
+ SetVCommonHandler(i, pkoExceptionHandler);
+ }
+ for (i = 10; i < 14; i++) {
+ SetVCommonHandler(i, pkoExceptionHandler);
+ }
+
+}
+
diff --git a/pcsx2hostfs/ee/excepHandler.h b/pcsx2hostfs/ee/excepHandler.h
new file mode 100644
index 0000000000..23bcb6b2f4
--- /dev/null
+++ b/pcsx2hostfs/ee/excepHandler.h
@@ -0,0 +1,14 @@
+/*********************************************************************
+ * Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
+ * This file is subject to the terms and conditions of the PS2Link License.
+ * See the file LICENSE in the main directory of this distribution for more
+ * details.
+ */
+
+#ifndef _EXCEPTION_H_
+#define _EXCEPTION_H_
+
+void installExceptionHandlers(void);
+void iopException(int cause, int badvaddr, int status, int epc, u32 *regs, int repc, char* name);
+
+#endif
diff --git a/pcsx2hostfs/ee/exceptions.S b/pcsx2hostfs/ee/exceptions.S
new file mode 100644
index 0000000000..80b8e21eda
--- /dev/null
+++ b/pcsx2hostfs/ee/exceptions.S
@@ -0,0 +1,225 @@
+/*********************************************************************
+ * Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
+ * This file is subject to the terms and conditions of the PS2Link License.
+ * See the file LICENSE in the main directory of this distribution for more
+ * details.
+ */
+
+# ASM exception handlers
+
+#include "r5900_regs.h"
+
+.set noat
+.set noreorder
+
+
+.text
+.p2align 4
+
+ .global _savedRegs
+
+ .global pkoStepBP
+ .ent pkoStepBP
+pkoStepBP:
+ # Should check for cause in cop0 Cause reg
+ # If Bp, increase EPC (DO NOT PUT 'break' in a branch delay slot!!!)
+ mfc0 k0, EPC # cop0 EPC
+ addiu k0, k0, 4 # Step over breakpoint
+ mtc0 k0, EPC
+ sync.p
+ eret
+ .end pkoStepBP
+
+
+ # Save all user regs
+ # Save HI/LO, SR, BadVAddr, Cause, EPC, ErrorEPC,
+ # ShiftAmount, cop0: $24, $25
+ # Save float regs??
+ # Set EPC to debugger
+ # Set stack to 'exception stack'
+ # eret
+ .global pkoExceptionHandler
+ .ent pkoExceptionHandler
+pkoExceptionHandler:
+ la k0, _savedRegs
+ sq $0, 0x00(k0)
+ sq at, 0x10(k0)
+ sq v0, 0x20(k0)
+ sq v1, 0x30(k0)
+ sq a0, 0x40(k0)
+ sq a1, 0x50(k0)
+ sq a2, 0x60(k0)
+ sq a3, 0x70(k0)
+ sq t0, 0x80(k0)
+ sq t1, 0x90(k0)
+ sq t2, 0xa0(k0)
+ sq t3, 0xb0(k0)
+ sq t4, 0xc0(k0)
+ sq t5, 0xd0(k0)
+ sq t6, 0xe0(k0)
+ sq t7, 0xf0(k0)
+ sq t8, 0x100(k0)
+ sq t9, 0x110(k0)
+ sq s0, 0x120(k0)
+ sq s1, 0x130(k0)
+ sq s2, 0x140(k0)
+ sq s3, 0x150(k0)
+ sq s4, 0x160(k0)
+ sq s5, 0x170(k0)
+ sq s6, 0x180(k0)
+ sq s7, 0x190(k0)
+# sq k0, 0x1a0(k0) # $k0
+ sq zero, 0x1a0(k0) # zero instead
+ sq k1, 0x1b0(k0) # $k1
+ sq gp, 0x1c0(k0)
+ sq sp, 0x1d0(k0) # sp
+ sq fp, 0x1e0(k0)
+ sq ra, 0x1f0(k0) # $ra
+
+ pmfhi t0 # HI
+ pmflo t1 # LO
+ sq t0, 0x200(k0)
+ sq t1, 0x210(k0)
+
+ mfc0 t0, BadVAddr # Cop0 state regs
+ mfc0 t1, Status
+ sw t0, 0x220(k0)
+ sw t1, 0x224(k0)
+
+ mfc0 t0, Cause
+ mfc0 t1, EPC
+ sw t0, 0x228(k0)
+ sw t1, 0x22c(k0)
+
+ # Kernel saves these two also..
+ mfc0 t0, DEPC
+ mfc0 t1, PerfCnt
+ sw t0, 0x230(k0)
+ sw t1, 0x234(k0)
+
+ mfsa t0
+ sw t0, 0x238(k0)
+
+ # Use our own stack..
+ la sp, _exceptionStack+0x2000-16
+ la gp, _gp # Use exception handlers _gp
+
+ # Return from exception and start 'debugger'
+ mfc0 a0, Cause # arg0
+ mfc0 a1, BadVAddr
+ mfc0 a2, Status
+ mfc0 a3, EPC
+ addu t0, zero, k0 # arg4 = registers
+ move t1, sp
+ la k0, pkoDebug
+ mtc0 k0, EPC # eret return address
+ sync.p
+ mfc0 k0, Status # check this out..
+ li v0, 0xfffffffe
+ and k0, v0
+ mtc0 k0, Status
+ sync.p
+ nop
+ nop
+ nop
+ nop
+ eret
+ nop
+ .end pkoExceptionHandler
+
+
+
+ # Put EE in kernel mode
+ # Restore all user regs etc
+ # Restore PC? & Stack ptr
+ # Restore interrupt sources
+ # Jump to EPC
+ .ent pkoReturnFromDebug
+ .global pkoReturnFromDebug
+pkoReturnFromDebug:
+
+ lui t1, 0x1
+_disable:
+ di
+ sync
+ mfc0 t0, Status
+ and t0, t1
+ beqz t0, _disable
+ nop
+
+ la k0, _savedRegs
+
+ lq t0, 0x200(k0)
+ lq t1, 0x210(k0)
+ pmthi t0 # HI
+ pmtlo t1 # LO
+
+ lw t0, 0x220(k0)
+ lw t1, 0x224(k0)
+ mtc0 t0, BadVAddr
+ mtc0 t1, Status
+
+ lw t0, 0x228(k0)
+ lw t1, 0x22c(k0)
+ mtc0 t0, Cause
+ mtc0 t1, EPC
+
+ # Kernel saves these two also..
+ lw t0, 0x230(k0)
+ lw t1, 0x234(k0)
+ mtc0 t0, DEPC
+ mtc0 t1, PerfCnt
+
+ # Shift Amount reg
+ lw t0, 0x238(k0)
+ mtsa t0
+
+
+# ori t2, 0xff
+# sw t2, 0(k1)
+
+ # lq $0, 0x00(k0)
+ lq $1, 0x10(k0)
+ lq $2, 0x20(k0)
+ lq $3, 0x30(k0)
+ lq $4, 0x40(k0)
+ lq $5, 0x50(k0)
+ lq $6, 0x60(k0)
+ lq $7, 0x70(k0)
+ lq $8, 0x80(k0)
+ lq $9, 0x90(k0)
+ lq $10, 0xa0(k0)
+ lq $11, 0xb0(k0)
+ lq $12, 0xc0(k0)
+ lq $13, 0xd0(k0)
+ lq $14, 0xe0(k0)
+ lq $15, 0xf0(k0)
+ lq $16, 0x100(k0)
+ lq $17, 0x110(k0)
+ lq $18, 0x120(k0)
+ lq $19, 0x130(k0)
+ lq $10, 0x140(k0)
+ lq $21, 0x150(k0)
+ lq $22, 0x160(k0)
+ lq $23, 0x170(k0)
+ lq $24, 0x180(k0)
+ lq $25, 0x190(k0)
+# lq $26, 0x1a0(k0) # $k0
+ lq $27, 0x1b0(k0) # $k1
+ lq $28, 0x1c0(k0)
+ lq $29, 0x1d0(k0) # $sp
+ lq $30, 0x1e0(k0)
+# lq $31, 0x1f0(k0) # $ra
+
+ lw ra, 0x22c(k0)
+ # Guess one should have some check here, and only advance PC if
+ # we are going to step over a Breakpoint or something
+ # (i.e. do stuff depending on Cause)
+ addiu ra, 4
+ sync.p
+ ei
+ sync.p
+
+ jr ra
+ nop
+ .end pkoReturnFromDebug
diff --git a/pcsx2hostfs/ee/linkfile.lcf b/pcsx2hostfs/ee/linkfile.lcf
new file mode 100644
index 0000000000..9a1857b303
--- /dev/null
+++ b/pcsx2hostfs/ee/linkfile.lcf
@@ -0,0 +1,53 @@
+_heap_size = 1*1024;
+_stack_size = 0x2000;
+
+ENTRY(_start);
+SECTIONS {
+
+ .text 0xc0000 : {
+ *(.text)
+ *(.rodata)
+ }
+ .reginfo ALIGN(128) : {
+ *(.reginfo)
+ }
+ .data ALIGN(128) : {
+ *(.data)
+ }
+ .rdata ALIGN(128) : {
+ *(.rdata)
+ }
+ _gp = ALIGN(128) + 0x7ff0;
+ .lit4 ALIGN(128) : {
+ *(.lit4)
+ }
+ .lit8 ALIGN(128) : {
+ *(.lit8)
+ }
+ .sdata ALIGN(128) : {
+ *(.sdata)
+ }
+
+ .sbss ALIGN(128) (NOLOAD) : { /* uninitialized data */
+ _fbss = . ;
+ *(.scommon)
+ *(.sbss)
+ }
+ .bss ALIGN(128) (NOLOAD) : { /* uninitialized data */
+ *(.bss)
+ }
+ .COMMON ALIGN(128) (NOLOAD) : { /* uninitialized data */
+ *(COMMON)
+ }
+ _end_bss = .;
+ _end = . ;
+ PROVIDE (end = .);
+ __lc_bh = . ;
+ . += _heap_size ;
+ __lc_eh = .;
+ .stack ALIGN(128) (NOLOAD) : { /* stack space */
+ _stack = .;
+ . += _stack_size;
+ _stack_end = .;
+ }
+}
diff --git a/pcsx2hostfs/ee/pcsx2hostfs_ldr.elf b/pcsx2hostfs/ee/pcsx2hostfs_ldr.elf
new file mode 100644
index 0000000000..1a7a10f4ef
Binary files /dev/null and b/pcsx2hostfs/ee/pcsx2hostfs_ldr.elf differ
diff --git a/pcsx2hostfs/ee/ps2link.c b/pcsx2hostfs/ee/ps2link.c
new file mode 100644
index 0000000000..db0521bdb6
--- /dev/null
+++ b/pcsx2hostfs/ee/ps2link.c
@@ -0,0 +1,809 @@
+/*********************************************************************
+ * Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
+ * Copyright (C) 2003,2004 adresd (adresd_ps2dev@yahoo.com)
+ * This file is subject to the terms and conditions of the PS2Link License.
+ * See the file LICENSE in the main directory of this distribution for more
+ * details.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "debug.h"
+#include "cd.h"
+#include "hostlink.h"
+#include "excepHandler.h"
+#include "stdio.h"
+
+#include
+
+#define WELCOME_STRING "Welcome to pcsx2hostfs v1.52\n"
+
+#ifdef DEBUG
+#define dbgprintf(args...) printf(args)
+#define dbgscr_printf(args...) scr_printf(args)
+#else
+#define dbgprintf(args...) do { } while(0)
+#define dbgscr_printf(args...) do { } while(0)
+#endif
+
+//#define BGCOLOR ((volatile unsigned long*)0x120000e0)
+//#define GS_SET_BGCOLOR(R,G,B) *BGCOLOR = ((u64)(R)<< 0) | ((u64)(G)<< 8) | ((u64)(B)<< 16)
+
+#define IRX_BUFFER_BASE 0x1F80000
+int irx_buffer_addr = 0;
+
+////////////////////////////////////////////////////////////////////////
+// Globals
+extern int userThreadID;
+
+// Argv name+path & just path
+char elfName[256] __attribute__((aligned(16)));
+char elfPath[256];
+
+#ifndef BUILTIN_IRXS
+char ioptrap_path[PKO_MAX_PATH];
+char pcsx2hostfs_path[PKO_MAX_PATH];
+
+void *ioptrap_mod = NULL, *pcsx2hostfs_mod = NULL;
+int ioptrap_size = 0, pcsx2hostfs_size = 0;
+#else
+extern unsigned char _binary_ioptrap_irx_start[], _binary_pcsx2hostfs_irx_start[];
+extern unsigned char _binary_ioptrap_irx_end[], _binary_pcsx2hostfs_irx_end[];
+static unsigned int _binary_ioptrap_irx_size, _binary_pcsx2hostfs_irx_size;
+#endif
+
+char *imgcmd = "rom0:UDNL rom0:EELOADCNF";
+
+// Flags for which type of boot
+#define B_CD 1
+#define B_MC 2
+#define B_HOST 3
+#define B_CC 4
+#define B_UNKN 5
+int boot;
+
+////////////////////////////////////////////////////////////////////////
+// Prototypes
+static void loadModules(void);
+static void pkoLoadModule(char *path, int argc, char *argv);
+static void getIpConfig(void);
+
+////////////////////////////////////////////////////////////////////////
+#define IPCONF_MAX_LEN 1024
+
+char if_conf[IPCONF_MAX_LEN] = "";
+char fExtraConfig[256];
+int load_extra_conf = 0;
+int if_conf_len = 0;
+
+char ip[16] __attribute__((aligned(16))) = "192.168.0.10";
+char netmask[16] __attribute__((aligned(16))) = "255.255.255.0";
+char gw[16] __attribute__((aligned(16))) = "192.168.0.1";
+
+////////////////////////////////////////////////////////////////////////
+// Parse network configuration from IPCONFIG.DAT
+// Note: parsing really should be made more robust...
+
+static int getBufferValue(char* result, char* buffer, u32 buffer_size, char* field)
+{
+ u32 len = strlen(field);
+ u32 i = 0;
+ s32 j = 0;
+ char* start = 0;
+ char* end = 0;
+
+ while(strncmp(&buffer[i], field, len) != 0)
+ {
+ i++;
+ if(i == buffer_size) return -1;
+ }
+
+ // Look for # comment
+ j = i;
+
+ while((j > 0) && (buffer[j] != '\n') && (buffer[j] !='\r'))
+ {
+ j--;
+
+ if(buffer[j] == '#')
+ return -2;
+ }
+
+
+ while(buffer[i] != '=')
+ {
+ i++;
+ if(i == buffer_size) return -3;
+ }
+ i++;
+
+ while(buffer[i] == ' ')
+ {
+ i++;
+ if(i == buffer_size) return -4;
+ }
+ i++;
+
+ if((buffer[i] != '\r') && (buffer[i] != '\n') && (buffer[i] != ';'))
+ {
+ start = &buffer[i];
+ }
+ else
+ {
+ return -5;
+ }
+
+ while(buffer[i] != ';')
+ {
+ i++;
+ if(i == buffer_size) return -5;
+ }
+
+ end = &buffer[i];
+
+ len = end - start;
+
+ if(len > 256) return -6;
+
+ strncpy(result, start, len);
+
+ return 0;
+}
+
+static void
+getIpConfig(void)
+{
+ int fd;
+ int i;
+ int t;
+ int len;
+ char c;
+ char buf[IPCONF_MAX_LEN+256];
+ static char path[256];
+
+ if (boot == B_CD) {
+ sprintf(path, "%s%s;1", elfPath, "IPCONFIG.DAT");
+ }
+ else if (boot == B_CC) {
+ strcpy(path, "mc0:/BOOT/IPCONFIG.DAT");
+ }
+ else {
+ sprintf(path, "%s%s", elfPath, "IPCONFIG.DAT");
+ }
+ fd = fioOpen(path, O_RDONLY);
+
+ if (fd < 0)
+ {
+ scr_printf("Could not find IPCONFIG.DAT, using defaults\n"
+ "Net config: %s %s %s\n", ip, netmask, gw);
+ // Set defaults
+ memset(if_conf, 0x00, IPCONF_MAX_LEN);
+ i = 0;
+ strncpy(&if_conf[i], ip, 15);
+ i += strlen(ip) + 1;
+
+ strncpy(&if_conf[i], netmask, 15);
+ i += strlen(netmask) + 1;
+
+ strncpy(&if_conf[i], gw, 15);
+ i += strlen(gw) + 1;
+
+ if_conf_len = i;
+ dbgscr_printf("conf len %d\n", if_conf_len);
+ return;
+ }
+
+ memset(if_conf, 0x00, IPCONF_MAX_LEN);
+ memset(buf, 0x00, IPCONF_MAX_LEN+256);
+
+ len = fioRead(fd, buf, IPCONF_MAX_LEN + 256 - 1); // Let the last byte be '\0'
+ fioClose(fd);
+
+ if (len < 0) {
+ dbgprintf("Error reading ipconfig.dat\n");
+ return;
+ }
+
+ dbgscr_printf("ipconfig: Read %d bytes\n", len);
+
+ i = 0;
+ // Clear out spaces (and potential ending CR/LF)
+ while ((c = buf[i]) != '\0') {
+ if ((c == ' ') || (c == '\r') || (c == '\n'))
+ buf[i] = '\0';
+ i++;
+ }
+
+ scr_printf("Net config: ");
+ for (t = 0, i = 0; t < 3; t++) {
+ strncpy(&if_conf[i], &buf[i], 15);
+ scr_printf("%s ", &if_conf[i]);
+ i += strlen(&if_conf[i]) + 1;
+ }
+ scr_printf("\n");
+ // get extra config filename
+
+#ifndef USE_CACHED_CFG
+ if(getBufferValue(fExtraConfig, buf, len, "EXTRACNF") == 0)
+ {
+ scr_printf("extra conf: %s\n", fExtraConfig);
+
+ load_extra_conf = 1;
+ }
+ else
+ {
+ load_extra_conf = 0;
+ }
+#else
+ load_extra_conf = 0;
+#endif
+
+ if_conf_len = i;
+}
+
+void
+getExtraConfig()
+{
+ int fd, size, ret;
+ char *buf, *ptr, *ptr2;
+ fd = fioOpen(fExtraConfig, O_RDONLY);
+
+ if ( fd < 0 )
+ {
+ scr_printf("failed to open extra conf file\n");
+ return;
+ }
+
+ size = fioLseek(fd, 0, SEEK_END);
+ fioLseek(fd, 0, SEEK_SET);
+ buf = malloc(size + 1);
+ ret = fioRead(fd, buf, size);
+ buf[size] = 0;
+ fioClose(fd);
+ ptr = buf;
+ ptr2 = buf;
+ while(ptr < buf+size) {
+ ptr2 = strstr(ptr, ";");
+ if ( ptr2 == 0 ) {
+ break;
+ }
+ ptr[ptr2-ptr] = 0;
+ scr_printf("loading %s\n", ptr);
+ pkoLoadModule(ptr, 0, NULL);
+ ptr = ptr2+1;
+ }
+ free(buf);
+ return;
+}
+
+////////////////////////////////////////////////////////////////////////
+// Wrapper to load irx module from disc/rom
+static void
+pkoLoadModule(char *path, int argc, char *argv)
+{
+ int ret;
+
+ ret = SifLoadModule(path, argc, argv);
+ if (ret < 0) {
+ scr_printf("Could not load module %s: %d\n", path, ret);
+ SleepThread();
+ }
+ dbgscr_printf("[%d] returned\n", ret);
+}
+
+#ifndef BUILTIN_IRXS
+/* Load a module into RAM. */
+void * modbuf_load(const char *filename, int *filesize)
+{
+ void *res = NULL;
+ int fd = -1, size;
+
+ if ((fd = fioOpen(filename, O_RDONLY)) < 0)
+ goto out;
+
+ if ((size = fioLseek(fd, 0, SEEK_END)) < 0)
+ goto out;
+
+ fioLseek(fd, 0, SEEK_SET);
+ fioLseek(fd, 0, SEEK_SET);
+
+ res = (void *)irx_buffer_addr;
+ irx_buffer_addr += size + 32 - (size % 16);
+ dbgscr_printf(" modbuf_load : %s , %d (0x%X)\n",filename,size,(int)res);
+
+ if (fioRead(fd, res, size) != size)
+ res = NULL;
+
+ if (filesize)
+ *filesize = size;
+
+out:
+ if (fd >= 0)
+ fioClose(fd);
+
+ return res;
+}
+
+static int loadHostModBuffers()
+{
+ if (irx_buffer_addr == 0)
+ {
+ irx_buffer_addr = IRX_BUFFER_BASE;
+
+ getIpConfig();
+
+ if (!(ioptrap_mod = modbuf_load(ioptrap_path, &ioptrap_size)))
+ {return -1;}
+
+ if (!(pcsx2hostfs_mod = modbuf_load(pcsx2hostfs_path, &pcsx2hostfs_size)))
+ return -1;
+ }
+
+ else
+ {
+ dbgscr_printf("Using Cached Modules\n");
+ }
+ return 0;
+}
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// Load all the irx modules we need, according to 'boot mode'
+static void
+loadModules(void)
+{
+ int ret;
+#ifdef USE_CACHED_CFG
+ int i,t;
+#endif
+
+ dbgscr_printf("loadModules \n");
+
+#ifdef USE_CACHED_CFG
+ if(if_conf_len==0)
+ {
+#endif
+ if ((boot == B_MC) || (boot == B_CC))
+ {
+ pkoLoadModule("rom0:SIO2MAN", 0, NULL);
+ pkoLoadModule("rom0:MCMAN", 0, NULL);
+ pkoLoadModule("rom0:MCSERV", 0, NULL);
+ }
+#ifdef USE_CACHED_CFG
+ return;
+ }
+#endif
+
+#ifdef BUILTIN_IRXS
+ _binary_ioptrap_irx_size = _binary_ioptrap_irx_end - _binary_ioptrap_irx_start;
+ _binary_pcsx2hostfs_irx_size = _binary_pcsx2hostfs_irx_end - _binary_pcsx2hostfs_irx_start;
+
+#ifdef USE_CACHED_CFG
+ if(if_conf_len==0)
+ {
+ getIpConfig();
+ }
+ else
+ {
+ i=0;
+ scr_printf("Net config: ");
+ for (t = 0, i = 0; t < 3; t++) {
+ scr_printf("%s ", &if_conf[i]);
+ i += strlen(&if_conf[i]) + 1;
+ }
+ scr_printf("\n");
+ }
+
+#else
+ getIpConfig();
+#endif
+
+ dbgscr_printf("Exec ioptrap module. (%x,%d) ", (unsigned int)_binary_ioptrap_irx_start, _binary_ioptrap_irx_size);
+ SifExecModuleBuffer(_binary_ioptrap_irx_start, _binary_ioptrap_irx_size, 0, NULL,&ret);
+ dbgscr_printf("[%d] returned\n", ret);
+ dbgscr_printf("Exec pcsx2hostfs module. (%x,%d) ", (unsigned int)_binary_pcsx2hostfs_irx_start, _binary_pcsx2hostfs_irx_size);
+ SifExecModuleBuffer(_binary_pcsx2hostfs_irx_start, _binary_pcsx2hostfs_irx_size, 0, NULL,&ret);
+ dbgscr_printf("[%d] returned\n", ret);
+ dbgscr_printf("All modules loaded on IOP.\n");
+#else
+ if (boot == B_HOST) {
+
+ dbgscr_printf("Exec ioptrap module. (%x,%d) ", (u32)ioptrap_mod, ioptrap_size);
+ SifExecModuleBuffer(ioptrap_mod, ioptrap_size, 0, NULL,&ret);
+ dbgscr_printf("[%d] returned\n", ret);
+ dbgscr_printf("Exec pcsx2hostfs module. (%x,%d) ", (u32)pcsx2hostfs_mod, pcsx2hostfs_size);
+ SifExecModuleBuffer(pcsx2hostfs_mod, pcsx2hostfs_size, 0, NULL,&ret);
+ dbgscr_printf("[%d] returned\n", ret);
+
+
+ dbgscr_printf("All modules loaded on IOP.\n");
+ } else {
+ getIpConfig();
+ dbgscr_printf("Exec ioptrap module. ");
+ pkoLoadModule(ioptrap_path, 0, NULL);
+ dbgscr_printf("Exec pcsx2hostfs module. ");
+ pkoLoadModule(pcsx2hostfs_path, 0, NULL);
+ dbgscr_printf("All modules loaded on IOP. ");
+ }
+#endif
+}
+
+////////////////////////////////////////////////////////////////////////
+// C standard strrchr func..
+char *strrchr(const char *s, int i)
+{
+ const char *last = NULL;
+ char c = i;
+
+ while (*s) {
+ if (*s == c) {
+ last = s;
+ }
+ s++;
+ }
+
+ if (*s == c) {
+ last = s;
+ }
+
+ return (char *) last;
+}
+
+////////////////////////////////////////////////////////////////////////
+// Split path (argv[0]) at the last '/', '\' or ':' and initialise
+// elfName (whole path & name to the elf, for example 'cdrom:\pukklink.elf')
+// elfPath (path to where the elf was started, for example 'cdrom:\')
+static void
+setPathInfo(char *path)
+{
+ char *ptr;
+
+ strncpy(elfName, path, 255);
+ strncpy(elfPath, path, 255);
+ elfName[255] = '\0';
+ elfPath[255] = '\0';
+
+
+ ptr = strrchr(elfPath, '/');
+ if (ptr == NULL) {
+ ptr = strrchr(elfPath, '\\');
+ if (ptr == NULL) {
+ ptr = strrchr(elfPath, ':');
+ if (ptr == NULL) {
+ scr_printf("Did not find path (%s)!\n", path);
+ SleepThread();
+ }
+ }
+ }
+
+ ptr++;
+ *ptr = '\0';
+
+#ifndef BUILTIN_IRXS
+ /* Paths to modules. */
+
+ sprintf(pcsx2hostfs_path, "%s%s", elfPath, "PS2LINK.IRX");
+ sprintf(ioptrap_path, "%s%s", elfPath, "IOPTRAP.IRX");
+
+ if (boot == B_CD) {
+ strcat(ioptrap_path, ";1");
+ strcat(pcsx2hostfs_path, ";1");
+ }
+#endif
+
+ dbgscr_printf("path is %s\n", elfPath);
+}
+
+////////////////////////////////////////////////////////////////////////
+// Clear user memory
+void
+wipeUserMem(void)
+{
+ int i;
+ // Whipe user mem
+ for (i = 0x100000; i < 0x2000000 ; i += 64) {
+ asm (
+ "\tsq $0, 0(%0) \n"
+ "\tsq $0, 16(%0) \n"
+ "\tsq $0, 32(%0) \n"
+ "\tsq $0, 48(%0) \n"
+ :: "r" (i) );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////
+// Clear user memory - Load High and Host version
+void
+wipeUserMemLoadHigh(void)
+{
+ int i;
+ // Whipe user mem, apart from last bit
+ for (i = 0x100000; i < 0x1F00000 ; i += 64) {
+ asm (
+ "\tsq $0, 0(%0) \n"
+ "\tsq $0, 16(%0) \n"
+ "\tsq $0, 32(%0) \n"
+ "\tsq $0, 48(%0) \n"
+ :: "r" (i) );
+ }
+}
+
+
+void
+restartIOP()
+{
+ fioExit();
+ SifExitIopHeap();
+ SifLoadFileExit();
+ SifExitRpc();
+
+ dbgscr_printf("reset iop\n");
+ SifIopReset(imgcmd, 0);
+ while (SifIopSync()) ;
+
+ dbgscr_printf("rpc init\n");
+ SifInitRpc(0);
+
+ scr_printf("Initializing...\n");
+ sio_printf("Initializing...\n");
+ sbv_patch_enable_lmb();
+ sbv_patch_disable_prefix_check();
+
+// SifLoadFileReset();
+ dbgscr_printf("loading modules\n");
+ loadModules();
+}
+
+#if HOOK_THREADS
+
+// we can spare 1k to allow a generous number of threads..
+#define MAX_MONITORED_THREADS 256
+
+int _first_load = 1;
+
+int th_count;
+int active_threads[MAX_MONITORED_THREADS];
+
+void *addr_LoadExecPS2;
+void *addr_CreateThread;
+void *addr_DeleteThread;
+
+void InstallKernelHooks(void)
+{
+ // get the current address of each syscall we want to hook then replace the entry
+ // in the syscall table with that of our hook function.
+
+ addr_LoadExecPS2 = GetSyscall(6);
+ SetSyscall(6, &Hook_LoadExecPS2);
+
+ addr_CreateThread = GetSyscall(32);
+ SetSyscall(32, &Hook_CreateThread);
+
+ addr_DeleteThread = GetSyscall(33);
+ SetSyscall(33, &Hook_DeleteThread);
+}
+
+void RemoveKernelHooks(void)
+{
+ SetSyscall(6, addr_LoadExecPS2);
+ SetSyscall(32, addr_CreateThread);
+ SetSyscall(33, addr_DeleteThread);
+}
+
+int Hook_LoadExecPS2(char *fname, int argc, char *argv[])
+{
+ // kill any active threads
+ KillActiveThreads();
+
+ // remove our kernel hooks
+ RemoveKernelHooks();
+
+ // call the real LoadExecPS2 handler, this will never return
+ return(((int (*)(char *, int, char **)) (addr_LoadExecPS2))(fname, argc, argv));
+}
+
+int Hook_CreateThread(ee_thread_t *thread_p)
+{
+ int i;
+ for(i = 0; i < MAX_MONITORED_THREADS; i++)
+ {
+ if(active_threads[i] < 0) { break; }
+ }
+
+ if(i >= MAX_MONITORED_THREADS) { return(-1); }
+
+ // call the real CreateThread handler, saving the thread id in our list
+ return(active_threads[i] = ((int (*)(ee_thread_t *)) (addr_CreateThread))(thread_p));
+}
+
+int Hook_DeleteThread(int th_id)
+{
+ int i;
+
+ for(i = 0; i < MAX_MONITORED_THREADS; i++)
+ {
+ if(active_threads[i] == th_id)
+ {
+ // remove the entry from the active thread list.
+ active_threads[i] = -1;
+ break;
+ }
+ }
+
+ // call the real DeleteThread handler
+ return(((int (*)(int)) (addr_DeleteThread))(th_id));
+}
+
+// kill all threads created and not deleted since PS2LINK.ELF started except for the calling thread.
+void KillActiveThreads(void)
+{
+ int my_id = GetThreadId();
+ int i;
+
+ for(i = 0; i < MAX_MONITORED_THREADS; i++)
+ {
+ if((active_threads[i] >= 0) && (active_threads[i] != my_id))
+ {
+ TerminateThread(active_threads[i]);
+ DeleteThread(active_threads[i]);
+ active_threads[i] = -1;
+ }
+ }
+}
+
+void ResetActiveThreads(void)
+{
+ int i;
+ for(i = 0; i < MAX_MONITORED_THREADS; i++) { active_threads[i] = -1; }
+}
+#endif
+
+extern void _start(void);
+extern int _end;
+
+////////////////////////////////////////////////////////////////////////
+int
+main(int argc, char *argv[])
+{
+ // int ret;
+ char *bootPath;
+
+ init_scr();
+ scr_printf(WELCOME_STRING);
+#ifdef _LOADHIGHVER
+ scr_printf("Highload version\n");
+#endif
+
+#ifdef SCREENSHOTS
+ scr_printf("Screenshot capable\n");
+#endif
+
+ scr_printf("pcsx2hostfs loaded at 0x%08X-0x%08X\n", ((u32) _start) - 8, (u32) &_end);
+
+ installExceptionHandlers();
+
+#if HOOK_THREADS
+ if(_first_load)
+ {
+ _first_load = 0;
+ InstallKernelHooks();
+ }
+
+ ResetActiveThreads();
+#endif
+
+ // argc == 0 usually means naplink..
+ if (argc == 0) {
+ bootPath = "host:";
+ }
+ // reload1 usually gives an argc > 60000 (yea, this is kinda a hack..)
+ else if (argc != 1) {
+ bootPath = "mc0:/BWLINUX/";
+ }
+ else {
+ bootPath = argv[0];
+ }
+
+ SifInitRpc(0);
+ dbgscr_printf("Checking argv\n");
+ boot = 0;
+
+ setPathInfo(bootPath);
+
+ if(!strncmp(bootPath, "mc", strlen("mc"))) {
+ // Booting from my mc
+ scr_printf("Booting from mc dir (%s)\n", bootPath);
+ boot = B_MC;
+ }
+ else if(!strncmp(bootPath, "host", strlen("host"))) {
+ // Host
+ scr_printf("Booting from host (%s)\n", bootPath);
+ boot = B_HOST;
+ }
+ else if(!strncmp(bootPath, "rom0:OSDSYS", strlen("rom0:OSDSYS"))) {
+ // From CC's firmware
+ scr_printf("Booting as CC firmware\n");
+ boot = B_CC;
+ }
+ else {
+ // Unknown
+ scr_printf("Booting from unrecognized place %s\n", bootPath);
+ boot = B_UNKN;
+ }
+
+#ifdef USE_CACHED_CFG
+ if(if_conf_len==0)
+ {
+ scr_printf("Initial boot, will load config then reset\n");
+ if(boot == B_MC || boot == B_CC)
+ restartIOP();
+
+ getIpConfig();
+
+ }
+ else
+ {
+ scr_printf("Using cached config\n");
+ }
+#endif
+
+ // System initalisation
+#ifndef BUILTIN_IRXS
+ if (boot == B_HOST) {
+ if (loadHostModBuffers() < 0) {
+ dbgscr_printf("Unable to load modules from host:!\n");
+ SleepThread();
+ }
+ }
+#endif
+
+ restartIOP();
+
+// CLEARSPU seems to cause exceptions in the Multi_Thread_Manager module.
+// I suspect this is caused by the interrupt handlers or some such.
+/*
+ dbgscr_printf("clearing spu\n");
+ if (SifLoadModule("rom0:CLEARSPU", 0, NULL)<0)
+ {
+ scr_printf("rom0:CLEARSPU failed\n");
+ sio_printf("rom0:CLEARSPU failed\n");
+ }
+*/
+
+ // get extra config
+ if(load_extra_conf)
+ {
+ dbgscr_printf("getting extra config\n");
+ getExtraConfig();
+ }
+
+ scr_printf("Ready\n");
+ sio_printf("Ready\n");
+ nprintf("Ready\n");
+
+ char test[101];
+ int fd = open("host:/I:/test_atom.xml", O_RDONLY);
+ if(fd>=0)
+ {
+ int rd = read(fd,test,100);
+ close(fd);
+
+ if(rd>0)
+ test[rd]=0;
+ test[100]=0;
+
+ nprintf("Reading returned %d: %s",rd,test);
+ }
+ else printf("Test failed.");
+
+// SleepThread();
+ ExitDeleteThread();
+ return 0;
+}
diff --git a/pcsx2hostfs/ee/ps2regs.h b/pcsx2hostfs/ee/ps2regs.h
new file mode 100644
index 0000000000..02dc534547
--- /dev/null
+++ b/pcsx2hostfs/ee/ps2regs.h
@@ -0,0 +1,286 @@
+/*********************************************************************
+ * Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
+ * This file is subject to the terms and conditions of the PS2Link License.
+ * See the file LICENSE in the main directory of this distribution for more
+ * details.
+ */
+
+#ifndef PS2REGS_H
+#define PS2REGS_H
+
+/* TIMERS */
+#define T0_COUNT *((volatile unsigned int *)0x10000000)
+#define T0_MODE *((volatile unsigned short *)0x10000010)
+#define T0_COMP *((volatile unsigned short *)0x10000020)
+#define T0_HOLD *((volatile unsigned short *)0x10000030)
+
+#define T1_COUNT *((volatile unsigned int *)0x10000800)
+#define T1_MODE *((volatile unsigned short *)0x10000810)
+#define T1_COMP *((volatile unsigned short *)0x10000820)
+#define T1_HOLD *((volatile unsigned short *)0x10000830)
+
+#define T2_COUNT *((volatile unsigned int *)0x10001000)
+#define T2_MODE *((volatile unsigned short *)0x10001010)
+#define T2_COMP *((volatile unsigned short *)0x10001020)
+
+#define T3_COUNT *((volatile unsigned int *)0x10001800)
+#define T3_MODE *((volatile unsigned short *)0x10001810)
+#define T3_COMP *((volatile unsigned short *)0x10001820)
+
+/* IPU */
+#define IPU_CMD *((volatile unsigned long *)0x10002000)
+#define IPU_CTRL *((volatile unsigned int *)0x10002010)
+#define IPU_BP *((volatile unsigned int *)0x10002020)
+#define IPU_TOP *((volatile unsigned long *)0x10002030)
+
+/* GIF */
+#define GIF_CTRL *((volatile unsigned int *)0x10003000)
+#define GIF_MODE *((volatile unsigned int *)0x10003010)
+#define GIF_STAT *((volatile unsigned int *)0x10003020)
+
+#define GIF_TAG0 *((volatile unsigned int *)0x10003040)
+#define GIF_TAG1 *((volatile unsigned int *)0x10003050)
+#define GIF_TAG2 *((volatile unsigned int *)0x10003060)
+#define GIF_TAG3 *((volatile unsigned int *)0x10003070)
+#define GIF_CNT *((volatile unsigned int *)0x10003080)
+#define GIF_P3CNT *((volatile unsigned int *)0x10003090)
+#define GIF_P3TAG *((volatile unsigned int *)0x100030a0)
+
+/* VIF */
+#define VIF0_STAT *((volatile unsigned int *)0x10003800)
+#define VIF0_FBRST *((volatile unsigned int *)0x10003810)
+#define VIF0_ERR *((volatile unsigned int *)0x10003820)
+#define VIF0_MARK *((volatile unsigned int *)0x10003830)
+#define VIF0_CYCLE *((volatile unsigned int *)0x10003840)
+#define VIF0_MODE *((volatile unsigned int *)0x10003850)
+#define VIF0_NUM *((volatile unsigned int *)0x10003860)
+#define VIF0_MASK *((volatile unsigned int *)0x10003870)
+#define VIF0_CODE *((volatile unsigned int *)0x10003880)
+#define VIF0_ITOPS *((volatile unsigned int *)0x10003890)
+
+#define VIF0_ITOP *((volatile unsigned int *)0x100038d0)
+
+#define VIF0_R0 *((volatile unsigned int *)0x10003900)
+#define VIF0_R1 *((volatile unsigned int *)0x10003910)
+#define VIF0_R2 *((volatile unsigned int *)0x10003920)
+#define VIF0_R3 *((volatile unsigned int *)0x10003930)
+#define VIF0_C0 *((volatile unsigned int *)0x10003940)
+#define VIF0_C1 *((volatile unsigned int *)0x10003950)
+#define VIF0_C2 *((volatile unsigned int *)0x10003960)
+#define VIF0_C3 *((volatile unsigned int *)0x10003970)
+
+#define VIF1_STAT *((volatile unsigned int *)0x10003c00)
+#define VIF1_FBRST *((volatile unsigned int *)0x10003c10)
+#define VIF1_ERR *((volatile unsigned int *)0x10003c20)
+#define VIF1_MARK *((volatile unsigned int *)0x10003c30)
+#define VIF1_CYCLE *((volatile unsigned int *)0x10003c40)
+#define VIF1_MODE *((volatile unsigned int *)0x10003c50)
+#define VIF1_NUM *((volatile unsigned int *)0x10003c60)
+#define VIF1_MASK *((volatile unsigned int *)0x10003c70)
+#define VIF1_CODE *((volatile unsigned int *)0x10003c80)
+#define VIF1_ITOPS *((volatile unsigned int *)0x10003c90)
+#define VIF1_BASE *((volatile unsigned int *)0x10003ca0)
+#define VIF1_OFST *((volatile unsigned int *)0x10003cb0)
+#define VIF1_TOPS *((volatile unsigned int *)0x10003cc0)
+#define VIF1_ITOP *((volatile unsigned int *)0x10003cd0)
+#define VIF1_TOP *((volatile unsigned int *)0x10003ce0)
+
+#define VIF1_R0 *((volatile unsigned int *)0x10003d00)
+#define VIF1_R1 *((volatile unsigned int *)0x10003d10)
+#define VIF1_R2 *((volatile unsigned int *)0x10003d20)
+#define VIF1_R3 *((volatile unsigned int *)0x10003d30)
+#define VIF1_C0 *((volatile unsigned int *)0x10003d40)
+#define VIF1_C1 *((volatile unsigned int *)0x10003d50)
+#define VIF1_C2 *((volatile unsigned int *)0x10003d60)
+#define VIF1_C3 *((volatile unsigned int *)0x10003d70)
+
+/* FIFO */
+//#define VIF0_FIFO(write) *((volatile unsigned int128 *)0x10004000)
+//#define VIF1_FIFO(read/write) *((volatile unsigned int128 *)0x10005000)
+//#define GIF_FIFO(write) *((volatile unsigned int128 *)0x10006000)
+//#define IPU_out_FIFO(read) *((volatile unsigned int128 *)0x10007000)
+//#define IPU_in_FIFO(write) *((volatile unsigned int128 *)0x10007010)
+
+/* DMAC */
+#define CHCR 0x00
+#define MADR 0x04
+#define QWC 0x08
+#define TADR 0x0C
+#define ASR0 0x10
+#define ASR1 0x14
+
+#define DMA0 ((volatile unsigned int *)0x10008000)
+#define DMA1 ((volatile unsigned int *)0x10009000)
+#define DMA2 ((volatile unsigned int *)0x1000a000)
+#define DMA3 ((volatile unsigned int *)0x1000b000)
+#define DMA4 ((volatile unsigned int *)0x1000b400)
+#define DMA5 ((volatile unsigned int *)0x1000c000)
+#define DMA6 ((volatile unsigned int *)0x1000c400)
+#define DMA7 ((volatile unsigned int *)0x1000c800)
+#define DMA8 ((volatile unsigned int *)0x1000d000)
+#define DMA9 ((volatile unsigned int *)0x1000d400)
+
+#define D0_CHCR *((volatile unsigned int *)0x10008000)
+#define D0_MADR *((volatile unsigned int *)0x10008010)
+#define D0_QWC *((volatile unsigned int *)0x10008020)
+#define D0_TADR *((volatile unsigned int *)0x10008030)
+#define D0_ASR0 *((volatile unsigned int *)0x10008040)
+#define D0_ASR1 *((volatile unsigned int *)0x10008050)
+
+#define D1_CHCR *((volatile unsigned int *)0x10009000)
+#define D1_MADR *((volatile unsigned int *)0x10009010)
+#define D1_QWC *((volatile unsigned int *)0x10009020)
+#define D1_TADR *((volatile unsigned int *)0x10009030)
+#define D1_ASR0 *((volatile unsigned int *)0x10009040)
+#define D1_ASR1 *((volatile unsigned int *)0x10009050)
+
+#define D2_CHCR *((volatile unsigned int *)0x1000a000)
+#define D2_MADR *((volatile unsigned int *)0x1000a010)
+#define D2_QWC *((volatile unsigned int *)0x1000a020)
+#define D2_TADR *((volatile unsigned int *)0x1000a030)
+#define D2_ASR0 *((volatile unsigned int *)0x1000a040)
+#define D2_ASR1 *((volatile unsigned int *)0x1000a050)
+
+#define D3_CHCR *((volatile unsigned int *)0x1000b000)
+#define D3_MADR *((volatile unsigned int *)0x1000b010)
+#define D3_QWC *((volatile unsigned int *)0x1000b020)
+
+#define D4_CHCR *((volatile unsigned int *)0x1000b400)
+#define D4_MADR *((volatile unsigned int *)0x1000b410)
+#define D4_QWC *((volatile unsigned int *)0x1000b420)
+#define D4_TADR *((volatile unsigned int *)0x1000b430)
+
+#define D5_CHCR *((volatile unsigned int *)0x1000c000)
+#define D5_MADR *((volatile unsigned int *)0x1000c010)
+#define D5_QWC *((volatile unsigned int *)0x1000c020)
+
+#define D6_CHCR *((volatile unsigned int *)0x1000c400)
+#define D6_MADR *((volatile unsigned int *)0x1000c410)
+#define D6_QWC *((volatile unsigned int *)0x1000c420)
+
+#define D7_CHCR *((volatile unsigned int *)0x1000c800)
+#define D7_MADR *((volatile unsigned int *)0x1000c810)
+#define D7_QWC *((volatile unsigned int *)0x1000c820)
+
+#define D8_CHCR *((volatile unsigned int *)0x1000d000)
+#define D8_MADR *((volatile unsigned int *)0x1000d010)
+#define D8_QWC *((volatile unsigned int *)0x1000d020)
+
+#define D8_SADR *((volatile unsigned int *)0x1000d080)
+
+#define D9_CHCR *((volatile unsigned int *)0x1000d400)
+#define D9_MADR *((volatile unsigned int *)0x1000d410)
+#define D9_QWC *((volatile unsigned int *)0x1000d420)
+#define D9_TADR *((volatile unsigned int *)0x1000d430)
+
+#define D9_SADR *((volatile unsigned int *)0x1000d480)
+
+/* DMAC */
+#define D_CTRL *((volatile unsigned int *)0x1000e000)
+#define D_STAT *((volatile unsigned int *)0x1000e010)
+#define D_PCR *((volatile unsigned int *)0x1000e020)
+#define D_SQWC *((volatile unsigned int *)0x1000e030)
+#define D_RBSR *((volatile unsigned int *)0x1000e040)
+#define D_RBOR *((volatile unsigned int *)0x1000e050)
+#define D_STADR *((volatile unsigned int *)0x1000e060)
+/* INTC */
+//#define I_STAT 0x1000f000
+//#define I_MASK 0x1000f010
+
+/* TOOL putchar */
+// .byte KPUTCHAR (0x1000f180)
+/* SIF */
+// #define SB_SMFLG (0x1000f230)
+
+/* DMAC */
+#define D_ENABLER *((volatile unsigned int *)0x1000f520)
+#define D_ENABLEW *((volatile unsigned int *)0x1000f590)
+
+/* VU Mem */
+#define VUMicroMem0 *((volatile unsigned int *)0x11000000)
+#define VUMem0 *((volatile unsigned int *)0x11004000)
+#define VUMicroMem1 *((volatile unsigned int *)0x11008000)
+#define VUMem1 *((volatile unsigned int *)0x1100c000)
+
+/* GS Privileged */
+#define GS_PMODE *((volatile unsigned long *)0x12000000)
+#define GS_SMODE1 *((volatile unsigned long *)0x12000010)
+#define GS_SMODE2 *((volatile unsigned long *)0x12000020)
+#define GS_SRFSH *((volatile unsigned long *)0x12000030)
+#define GS_SYNCH1 *((volatile unsigned long *)0x12000040)
+#define GS_SYNCH2 *((volatile unsigned long *)0x12000050)
+#define GS_SYNCV *((volatile unsigned long *)0x12000060)
+#define GS_DISPFB1 *((volatile unsigned long *)0x12000070)
+#define GS_DISPLAY1 *((volatile unsigned long *)0x12000080)
+#define GS_DISPFB2 *((volatile unsigned long *)0x12000090)
+#define GS_DISPLAY2 *((volatile unsigned long *)0x120000a0)
+#define GS_EXTBUF *((volatile unsigned long *)0x120000b0)
+#define GS_EXTDATA *((volatile unsigned long *)0x120000c0)
+#define GS_EXTWRITE *((volatile unsigned long *)0x120000d0)
+#define GS_BGCOLOR *((volatile unsigned long *)0x120000e0)
+
+#define GS_CSR *((volatile unsigned long *)0x12001000)
+#define GS_IMR *((volatile unsigned long *)0x12001010)
+
+#define GS_BUSDIR *((volatile unsigned long *)0x12001040)
+
+#define GS_SIGLBLID *((volatile unsigned long *)0x12001080)
+
+/* GS General */
+#define GS_PRIM 0x00
+#define GS_RGBAQ 0x01
+#define GS_ST 0x02
+#define GS_UV 0x03
+#define GS_XYZF2 0x04
+#define GS_XYZ2 0x05
+#define GS_TEX0_1 0x06
+#define GS_TEX0_2 0x07
+#define GS_CLAMP_1 0x08
+#define GS_CLAMP_2 0x09
+#define GS_FOG 0x0a
+#define GS_XYZF3 0x0c
+#define GS_XYZ3 0x0d
+#define GS_AD 0x0e
+#define GS_TEX1_1 0x14
+#define GS_TEX1_2 0x15
+#define GS_TEX2_1 0x16
+#define GS_TEX2_2 0x17
+#define GS_XYOFFSET_1 0x18
+#define GS_XYOFFSET_2 0x19
+#define GS_PRMODECONT 0x1a
+#define GS_PRMODE 0x1b
+#define GS_TEXCLUT 0x1c
+#define GS_SCANMSK 0x22
+#define GS_MIPTBP1_1 0x34
+#define GS_MIPTBP1_2 0x35
+#define GS_MIPTBP2_1 0x36
+#define GS_MIPTBP2_2 0x37
+#define GS_TEXA 0x3b
+#define GS_FOGCOL 0x3d
+#define GS_TEXFLUSH 0x3f
+#define GS_SCISSOR_1 0x40
+#define GS_SCISSOR_2 0x41
+#define GS_ALPHA_1 0x42
+#define GS_ALPHA_2 0x43
+#define GS_DIMX 0x44
+#define GS_DTHE 0x45
+#define GS_COLCLAMP 0x46
+#define GS_TEST_1 0x47
+#define GS_TEST_2 0x48
+#define GS_PABE 0x49
+#define GS_FBA_1 0x4a
+#define GS_FBA_2 0x4b
+#define GS_FRAME_1 0x4c
+#define GS_FRAME_2 0x4d
+#define GS_ZBUF_1 0x4e
+#define GS_ZBUF_2 0x4f
+#define GS_BITBLTBUF 0x50
+#define GS_TRXPOS 0x51
+#define GS_TRXREG 0x52
+#define GS_TRXDIR 0x53
+#define GS_HWREG 0x54
+#define GS_SIGNAL 0x60
+#define GS_FINISH 0x61
+#define GS_LABEL 0x62
+
+#endif
diff --git a/pcsx2hostfs/ee/r5900_regs.h b/pcsx2hostfs/ee/r5900_regs.h
new file mode 100644
index 0000000000..79da322ca2
--- /dev/null
+++ b/pcsx2hostfs/ee/r5900_regs.h
@@ -0,0 +1,73 @@
+//------------------------------------------------------------------------
+// File: regs.h
+// Author: Tony Saveski, t_saveski@yahoo.com
+// Notes: Playstation 2 Register Definitions
+//------------------------------------------------------------------------
+#ifndef R5900_REGS_H
+#define R5900_REGS_H
+
+// MIPS CPU Registsers
+#define zero $0 // Always 0
+#define at $1 // Assembler temporary
+#define v0 $2 // Function return
+#define v1 $3 //
+#define a0 $4 // Function arguments
+#define a1 $5
+#define a2 $6
+#define a3 $7
+#define t0 $8 // Temporaries. No need
+#define t1 $9 // to preserve in your
+#define t2 $10 // functions.
+#define t3 $11
+#define t4 $12
+#define t5 $13
+#define t6 $14
+#define t7 $15
+#define s0 $16 // Saved Temporaries.
+#define s1 $17 // Make sure to restore
+#define s2 $18 // to original value
+#define s3 $19 // if your function
+#define s4 $20 // changes their value.
+#define s5 $21
+#define s6 $22
+#define s7 $23
+#define t8 $24 // More Temporaries.
+#define t9 $25
+#define k0 $26 // Reserved for Kernel
+#define k1 $27
+#define gp $28 // Global Pointer
+#define sp $29 // Stack Pointer
+#define fp $30 // Frame Pointer
+#define ra $31 // Function Return Address
+
+// COP0
+#define Index $0 // Index into the TLB array
+#define Random $1 // Randomly generated index into the TLB array
+#define EntryLo0 $2 // Low-order portion of the TLB entry for..
+#define EntryLo1 $3 // Low-order portion of the TLB entry for
+#define Context $4 // Pointer to page table entry in memory
+#define PageMask $5 // Control for variable page size in TLB entries
+#define Wired $6 // Controls the number of fixed ("wired") TLB entries
+#define BadVAddr $8 // Address for the most recent address-related exception
+#define Count $9 // Processor cycle count
+#define EntryHi $10 // High-order portion of the TLB entry
+#define Compare $11 // Timer interrupt control
+#define Status $12 // Processor status and control
+#define Cause $13 // Cause of last general exception
+#define EPC $14 // Program counter at last exception
+#define PRId $15 // Processor identification and revision
+#define Config $16 // Configuration register
+#define LLAddr $17 // Load linked address
+#define WatchLo $18 // Watchpoint address Section 6.25 on
+#define WatchHi $19 // Watchpoint control
+#define Debug $23 // EJTAG Debug register
+#define DEPC $24 // Program counter at last EJTAG debug exception
+#define PerfCnt $25 // Performance counter interface
+#define ErrCtl $26 // Parity/ECC error control and status
+#define CacheErr $27 // Cache parity error control and status
+#define TagLo $28 // Low-order portion of cache tag interface
+#define TagHi $29 // High-order portion of cache tag interface
+#define ErrorPC $30 // Program counter at last error
+#define DEASVE $31 // EJTAG debug exception save register
+
+#endif // R5900_REGS_H
diff --git a/pcsx2hostfs/include/byteorder.h b/pcsx2hostfs/include/byteorder.h
new file mode 100644
index 0000000000..c1a35e0794
--- /dev/null
+++ b/pcsx2hostfs/include/byteorder.h
@@ -0,0 +1,42 @@
+/*********************************************************************
+ * Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
+ * This file is subject to the terms and conditions of the PS2Link License.
+ * See the file LICENSE in the main directory of this distribution for more
+ * details.
+ */
+
+#ifndef BYTEORDER_H
+#define BYTEORDER_H
+
+#include
+
+#ifdef BIG_ENDIAN
+inline unsigned int ntohl(x) { return x; }
+inline unsigned short ntohs(x) { return x; }
+inline unsigned int ntohl(x) { return x; }
+inline unsigned short ntohs(x) { return x; }
+#else
+// LITTLE_ENDIAN
+inline unsigned int
+htonl(unsigned int x)
+{
+ return ((x & 0xff) << 24 ) |
+ ((x & 0xff00) << 8 ) |
+ ((x & 0xff0000) >> 8 ) |
+ ((x & 0xff000000) >> 24 );
+}
+
+inline unsigned short
+htons(unsigned short x)
+{
+ return ((x & 0xff) << 8 ) | ((x & 0xff00) >> 8 );
+}
+
+#define ntohl htonl
+#define ntohs htons
+
+#endif
+
+#define IP4_ADDR(ipaddr, a,b,c,d) (ipaddr)->s_addr = htonl(((u32)(a & 0xff) << 24) | ((u32)(b & 0xff) << 16 ) | ((u32)(c & 0xff) << 8) | (u32)(d & 0xff))
+
+#endif /* BYTEORDER_H */
diff --git a/pcsx2hostfs/include/hostlink.h b/pcsx2hostfs/include/hostlink.h
new file mode 100644
index 0000000000..4d40bd8f98
--- /dev/null
+++ b/pcsx2hostfs/include/hostlink.h
@@ -0,0 +1,22 @@
+/*********************************************************************
+ * Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
+ * This file is subject to the terms and conditions of the PS2Link License.
+ * See the file LICENSE in the main directory of this distribution for more
+ * details.
+ */
+
+#define PS2E_FIO_OPEN_CMD 0xcc2e0101
+#define PS2E_FIO_CLOSE_CMD 0xcc2e0102
+#define PS2E_FIO_READ_CMD 0xcc2e0103
+#define PS2E_FIO_WRITE_CMD 0xcc2e0104
+#define PS2E_FIO_LSEEK_CMD 0xcc2e0105
+#define PS2E_FIO_OPENDIR_CMD 0xcc2e0106
+#define PS2E_FIO_CLOSEDIR_CMD 0xcc2e0107
+#define PS2E_FIO_READDIR_CMD 0xcc2e0108
+#define PS2E_FIO_REMOVE_CMD 0xcc2e0109
+#define PS2E_FIO_MKDIR_CMD 0xcc2e010a
+#define PS2E_FIO_RMDIR_CMD 0xcc2e010b
+
+#define PS2E_FIO_PRINTF_CMD 0xcc2e0201
+
+#define PS2E_FIO_MAX_PATH 256
diff --git a/pcsx2hostfs/iop/Makefile b/pcsx2hostfs/iop/Makefile
new file mode 100644
index 0000000000..1ecfe2a038
--- /dev/null
+++ b/pcsx2hostfs/iop/Makefile
@@ -0,0 +1,43 @@
+# _____ ___ ____
+# ____| | ____| PSX2 OpenSource Project
+# | ___| |____ (C)2002, David Ryan ( Oobles@hotmail.com )
+# ------------------------------------------------------------------------
+
+# Generated automatically from Makefile.in by configure.
+#.SUFFIXES: .S .c .o .s .elf .irx
+
+IOP_BIN = pcsx2hostfs.irx
+IOP_OBJS = net_fsys.o net_fio.o ps2link.o tty.o nprintf.o excepHandler.o imports.o
+
+IOP_INCS += -I../include
+IOP_LIBS +=
+IOP_LDFLAGS +=
+IOP_CFLAGS += -Wall
+
+# Enable zero-copy on fileio writes.
+ifeq ($(ZEROCOPY),1)
+IOP_CFLAGS += -DZEROCOPY
+endif
+
+# Enable debug mode
+ifeq ($(DEBUG),1)
+IOP_CFLAGS += -DDEBUG
+endif
+
+ifeq ($(PWOFFONRESET),1)
+IOP_CFLAGS += -DPWOFFONRESET
+endif
+
+# Enable screenshot functionality
+ifeq ($(SCREENSHOTS),1)
+IOP_CFLAGS += -DSCREENSHOTS
+endif
+
+
+all: $(IOP_BIN)
+
+clean:
+ -rm -f $(IOP_OBJS) $(IOP_BIN)
+
+include $(PS2SDK)/Defs.make
+include Rules.make
diff --git a/pcsx2hostfs/iop/Rules.make b/pcsx2hostfs/iop/Rules.make
new file mode 100644
index 0000000000..d3be71609d
--- /dev/null
+++ b/pcsx2hostfs/iop/Rules.make
@@ -0,0 +1,54 @@
+# _____ ___ ____ ___ ____
+# ____| | ____| | | |____|
+# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
+#-----------------------------------------------------------------------
+# Copyright 2001-2004.
+# Licenced under Academic Free License version 2.0
+# Review ps2sdk README & LICENSE files for further details.
+
+
+IOP_CC_VERSION := $(shell $(IOP_CC) -v 2>&1 | sed -n 's/^.*version //p')
+
+ASFLAGS_TARGET = -mcpu=r3000
+
+ifeq ($(IOP_CC_VERSION),3.2.2)
+CFLAGS_TARGET = -miop
+ASFLAGS_TARGET = -march=r3000
+LDFLAGS_TARGET = -miop
+endif
+
+IOP_INCS := $(IOP_INCS) -I$(PS2SDK)/iop/include -I$(PS2SDK)/common/include
+
+IOP_CFLAGS := $(CFLAGS_TARGET) -O2 -G0 -c $(IOP_INCS) $(IOP_CFLAGS)
+IOP_ASFLAGS := $(ASFLAGS_TARGET) -EL -G0 $(IOP_ASFLAGS)
+IOP_LDFLAGS := $(LDFLAGS_TARGET) -nostdlib $(IOP_LDFLAGS)
+
+# Externally defined variables: IOP_BIN, IOP_OBJS, IOP_LIB
+
+%.o : %.c
+ $(IOP_CC) $(IOP_CFLAGS) $< -o $@
+
+%.o : %.s
+ $(IOP_AS) $(IOP_ASFLAGS) $< -o $@
+
+# A rule to build imports.lst.
+%.o : %.lst
+ echo "#include \"irx_imports.h\"" > build-imports.c
+ cat $< >> build-imports.c
+ $(IOP_CC) $(IOP_CFLAGS) build-imports.c -o $@
+ -rm -f build-imports.c
+
+# A rule to build exports.tab.
+%.o : %.tab
+ echo "#include \"irx.h\"" > build-exports.c
+ cat $< >> build-exports.c
+ $(IOP_CC) $(IOP_CFLAGS) build-exports.c -o $@
+ -rm -f build-exports.c
+
+
+$(IOP_BIN) : $(IOP_OBJS)
+ $(IOP_CC) $(IOP_LDFLAGS) -o $(IOP_BIN) $(IOP_OBJS) $(IOP_LIBS)
+
+$(IOP_LIB) : $(IOP_OBJS)
+ $(IOP_AR) cru $(IOP_LIB) $(IOP_OBJS)
+
diff --git a/pcsx2hostfs/iop/excepHandler.c b/pcsx2hostfs/iop/excepHandler.c
new file mode 100644
index 0000000000..a3a7044da2
--- /dev/null
+++ b/pcsx2hostfs/iop/excepHandler.c
@@ -0,0 +1,119 @@
+/*********************************************************************
+ * Copyright (C) 2004 Lukasz Bruun (mail@lukasz.dk)
+ * This file is subject to the terms and conditions of the PS2Link License.
+ * See the file LICENSE in the main directory of this distribution for more
+ * details.
+ */
+
+#include
+#include "irx_imports.h"
+#include "hostlink.h"
+
+#define BUFFER_SIZE sizeof(exception_frame_t)+4+4+128
+
+u32 excep_buffer[BUFFER_SIZE/4] __attribute__ ((aligned(16)));
+
+extern unsigned int pcsx2fioSendSifCmd(unsigned int cmd, void *src, unsigned int len); // lazy fix :)
+extern int excepscrdump;
+
+#define PKO_RPC_IOPEXCEP 12
+
+// taken from smod by mrbrown, only use one function, didn't wanna include another irx.
+
+/* Module info entry. */
+typedef struct _smod_mod_info {
+ struct _smod_mod_info *next;
+ u8 *name;
+ u16 version;
+ u16 newflags; /* For modload shipped with games. */
+ u16 id;
+ u16 flags; /* I believe this is where flags are kept for BIOS versions. */
+ u32 entry; /* _start */
+ u32 gp;
+ u32 text_start;
+ u32 text_size;
+ u32 data_size;
+ u32 bss_size;
+ u32 unused1;
+ u32 unused2;
+} smod_mod_info_t;
+
+
+smod_mod_info_t *smod_get_next_mod(smod_mod_info_t *cur_mod)
+{
+ /* If cur_mod is 0, return the head of the list (IOP address 0x800). */
+ if (!cur_mod) {
+ return (smod_mod_info_t *)0x800;
+ } else {
+ if (!cur_mod->next)
+ return 0;
+ else
+ return cur_mod->next;
+ }
+ return 0;
+}
+
+char* ExceptionGetModuleName(u32 epc, u32* r_epc)
+{
+ smod_mod_info_t *mod_info = 0;
+
+ while((mod_info = smod_get_next_mod(mod_info)) != 0)
+ {
+ if((epc >= mod_info->text_start) && (epc <= (mod_info->text_start+mod_info->text_size)))
+ {
+ if(r_epc)
+ *r_epc = epc - mod_info->text_start;
+
+ return mod_info->name;
+ }
+ }
+
+ return 0;
+}
+
+static void excep_handler2(exception_frame_t *frame)
+{
+ u32 r_epc; // relative epc
+ char *module_name;
+ u32 len;
+ u32* buffer = excep_buffer;
+
+ module_name = ExceptionGetModuleName(frame->epc, &r_epc);
+
+ len = strlen(module_name);
+
+
+ buffer[0] = 0x0d02beba; // reverse engineering..
+ buffer++;
+
+ memcpy(buffer, frame, BUFFER_SIZE);
+ buffer+= (sizeof(exception_frame_t)/4);
+
+ buffer[0] = r_epc;
+ buffer[1] = len;
+ buffer+=2;
+ memcpy(buffer, module_name, len+1);
+
+ //pcsx2fioSendSifCmd(PKO_RPC_IOPEXCEP, excep_buffer, BUFFER_SIZE);
+}
+
+
+static void excep_handler(exception_type_t type, exception_frame_t *frame)
+{
+ excep_handler2(frame); // Don't know why this works, but keeps iop alive.
+}
+
+
+////////////////////////////////////////////////////////////////////////
+// Installs iop exception handlers for the 'usual' exceptions..
+void installExceptionHandlers(void)
+{
+ s32 i;
+
+ for(i=1; i < 8; i++)
+ set_exception_handler(i, excep_handler);
+
+ for(i=10; i < 13; i++)
+ set_exception_handler(i, excep_handler);
+
+}
diff --git a/pcsx2hostfs/iop/excepHandler.h b/pcsx2hostfs/iop/excepHandler.h
new file mode 100644
index 0000000000..603bff8a53
--- /dev/null
+++ b/pcsx2hostfs/iop/excepHandler.h
@@ -0,0 +1,13 @@
+/*********************************************************************
+ * Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
+ * This file is subject to the terms and conditions of the PS2Link License.
+ * See the file LICENSE in the main directory of this distribution for more
+ * details.
+ */
+
+#ifndef _EXCEPTION_H_
+#define _EXCEPTION_H_
+
+void installExceptionHandlers(void);
+
+#endif
diff --git a/pcsx2hostfs/iop/imports.lst b/pcsx2hostfs/iop/imports.lst
new file mode 100644
index 0000000000..5b34397438
--- /dev/null
+++ b/pcsx2hostfs/iop/imports.lst
@@ -0,0 +1,63 @@
+
+stdio_IMPORTS_start
+I_printf
+stdio_IMPORTS_end
+
+sysclib_IMPORTS_start
+I_memset
+I_memcpy
+I_strlen
+I_strncpy
+I_strncmp
+sysclib_IMPORTS_end
+
+thsemap_IMPORTS_start
+I_CreateSema
+I_SignalSema
+I_WaitSema
+I_DeleteSema
+thsemap_IMPORTS_end
+
+thbase_IMPORTS_start
+I_CreateThread
+I_DeleteThread
+I_StartThread
+I_GetThreadId
+I_ExitDeleteThread
+thbase_IMPORTS_end
+
+ioman_IMPORTS_start
+I_open
+I_close
+I_AddDrv
+I_DelDrv
+ioman_IMPORTS_end
+
+sifcmd_IMPORTS_start
+I_sceSifInitRpc
+I_sceSifSetRpcQueue
+I_sceSifRegisterRpc
+I_sceSifRpcLoop
+sifcmd_IMPORTS_end
+
+sifman_IMPORTS_start
+I_sceSifSetDma
+sifman_IMPORTS_end
+
+intrman_IMPORTS_start
+I_CpuEnableIntr
+I_CpuSuspendIntr
+I_CpuResumeIntr
+intrman_IMPORTS_end
+
+loadcore_IMPORTS_start
+I_FlushDcache
+loadcore_IMPORTS_end
+
+modload_IMPORTS_start
+I_LoadStartModule
+modload_IMPORTS_end
+
+ioptrap_IMPORTS_start
+I_set_exception_handler
+ioptrap_IMPORTS_end
diff --git a/pcsx2hostfs/iop/irx_imports.h b/pcsx2hostfs/iop/irx_imports.h
new file mode 100644
index 0000000000..d40030c993
--- /dev/null
+++ b/pcsx2hostfs/iop/irx_imports.h
@@ -0,0 +1,28 @@
+/*
+ * irx_imports.h - Defines all IRX imports.
+ *
+ * Copyright (c) 2003 Marcus R. Brown
+ *
+ * See the file LICENSE included with this distribution for licensing terms.
+ */
+
+#ifndef IOP_IRX_IMPORTS_H
+#define IOP_IRX_IMPORTS_H
+
+#include "irx.h"
+
+
+/* Please keep these in alphabetical order! */
+#include "intrman.h"
+#include "ioman.h"
+#include "ioptrap.h"
+#include "loadcore.h"
+#include "modload.h"
+#include "sifcmd.h"
+#include "sifman.h"
+#include "stdio.h"
+#include "sysclib.h"
+#include "thbase.h"
+#include "thsemap.h"
+
+#endif /* IOP_IRX_IMPORTS_H */
diff --git a/pcsx2hostfs/iop/mipsirx.x b/pcsx2hostfs/iop/mipsirx.x
new file mode 100644
index 0000000000..d358cca6f6
--- /dev/null
+++ b/pcsx2hostfs/iop/mipsirx.x
@@ -0,0 +1,80 @@
+/* Link script for PlayStation 2 IRXs
+ * Written by Douglas C. Knight
+ */
+OUTPUT_FORMAT("elf32-littlemips")
+ SEARCH_DIR(/home/karmix/local/iop/lib);
+ENTRY(_start)
+SECTIONS
+{
+ /* This is the .iopmod section for the IRX, it contains
+ information that the IOP uses when loading the IRX.
+ This section is placed in its own segment. */
+ .iopmod : {
+ /* The linker will replace this first LONG with a pointer
+ to _irx_id if the symbol has been defined. */
+ LONG (0xffffffff) ;
+ LONG (_start) ;
+ LONG (_gp) ;
+ LONG (_text_size) ;
+ LONG (_data_size) ;
+ LONG (_bss_size) ;
+ /* The linker will put a SHORT here with the version of
+ the IRX (or zero if there is no version). */
+ /* The linker will put a null terminated string here
+ containing the name of the IRX (or an empty string if
+ the name is not known). */
+ }
+ . = 0x0 ;
+ _ftext = . ;
+ .text : {
+ CREATE_OBJECT_SYMBOLS
+ * ( .text )
+ * ( .text.* )
+ * ( .init )
+ * ( .fini )
+ } = 0
+ _etext = . ;
+ . = . ;
+ _fdata = . ;
+ .rodata : {
+ * ( .rdata )
+ * ( .rodata )
+ * ( .rodata1 )
+ * ( .rodata.* )
+ } = 0
+ .data : {
+ * ( .data )
+ * ( .data1 )
+ * ( .data.* )
+ CONSTRUCTORS
+ }
+ . = ALIGN(16) ;
+ _gp = . + 0x8000 ;
+ .sdata : {
+ * ( .lit8 )
+ * ( .lit4 )
+ * ( .sdata )
+ * ( .sdata.* )
+ }
+ _edata = . ;
+ . = ALIGN(4) ;
+ _fbss = . ;
+ .sbss : {
+ * ( .sbss )
+ * ( .scommon )
+ }
+ _bss_start = . ;
+ .bss : {
+ * ( .bss )
+ * ( COMMON )
+ . = ALIGN(4) ;
+ }
+ _end = . ;
+ _text_size = _etext - _ftext ;
+ _data_size = _edata - _fdata ;
+ _bss_size = _end - _fbss ;
+ /* This is the stuff that we don't want to be put in an IRX. */
+ /DISCARD/ : {
+ * ( .reginfo )
+ }
+}
diff --git a/pcsx2hostfs/iop/net_fio.c b/pcsx2hostfs/iop/net_fio.c
new file mode 100644
index 0000000000..9b9cb9665d
--- /dev/null
+++ b/pcsx2hostfs/iop/net_fio.c
@@ -0,0 +1,230 @@
+/*********************************************************************
+ * Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
+ * Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com)
+ * This file is subject to the terms and conditions of the PS2Link License.
+ * See the file LICENSE in the main directory of this distribution for more
+ * details.
+ */
+
+// Fu*k knows why net_fio & net_fsys are separated..
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include "net_fio.h"
+#include "hostlink.h"
+
+#define PACKET_MAXSIZE 1024
+static int send_packet[PACKET_MAXSIZE] __attribute__((aligned(16)));
+
+#ifdef DEBUG
+#define dbgprintf(args...) printf(args)
+#else
+#define dbgprintf(args...) do { } while(0)
+#endif
+
+//----------------------------------------------------------------------
+//
+#define PCSX2_FIO_BASE ((volatile unsigned int*)0x1d000800)
+#define PCSX2_FIO_RDID (PCSX2_FIO_BASE + 0) // [f0] on read: returns the FIO magic number 'E2SP'
+#define PCSX2_FIO_WCMD (PCSX2_FIO_BASE + 0) // [f0] on write: executes a command (usually "call function")
+#define PCSX2_FIO_DLEN (PCSX2_FIO_BASE + 1) // [f4] write only: length of params data
+#define PCSX2_FIO_DPTR (PCSX2_FIO_BASE + 2) // [f8] write only: mem address of params data
+#define PCSX2_FIO_WFID (PCSX2_FIO_BASE + 3) // [fc] on write: function ID
+#define PCSX2_FIO_RRET (PCSX2_FIO_BASE + 3) // [fc] on read: return value of the function
+
+#define PCSX2_FIO_CMD_CALL 1
+
+int pcsx2fio_device_exists()
+{
+ return (*PCSX2_FIO_RDID == 'E2SP'); // PS2E
+}
+
+int pcsx2fio_set_call(unsigned int func_id, void* params, int params_length)
+{
+ *PCSX2_FIO_DLEN = params_length;
+ *PCSX2_FIO_DPTR = (int)params;
+ *PCSX2_FIO_WFID = func_id;
+ *PCSX2_FIO_WCMD = PCSX2_FIO_CMD_CALL;
+ return *PCSX2_FIO_RRET;
+}
+
+char *strcpy(char *dest, const char *src)
+{
+ while(*src)
+ {
+ *(dest++) = *(src++);
+ }
+ *(dest) = 0;
+ return dest;
+}
+
+//----------------------------------------------------------------------
+//
+void
+pcsx2fio_close_fsys(void)
+{
+}
+
+//----------------------------------------------------------------------
+//
+int pcsx2fio_open_file(char *path, int flags)
+{
+ send_packet[0] = flags;
+ strcpy((char*)(send_packet+1),path);
+
+ int length = strlen(path) + 4;
+
+ int ret = pcsx2fio_set_call(PS2E_FIO_OPEN_CMD, send_packet, length);
+
+ return ret;
+}
+
+
+//----------------------------------------------------------------------
+//
+int pcsx2fio_close_file(int fd)
+{
+ send_packet[0] = fd;
+
+ int length = 4;
+
+ int ret = pcsx2fio_set_call(PS2E_FIO_CLOSE_CMD, send_packet, length);
+
+ return ret;
+}
+
+//----------------------------------------------------------------------
+//
+int pcsx2fio_lseek_file(int fd, unsigned int offset, int whence)
+{
+ send_packet[0] = fd;
+ send_packet[1] = offset;
+ send_packet[2] = whence;
+ send_packet[3] = 0;
+
+ int length = 12;
+
+ int ret = pcsx2fio_set_call(PS2E_FIO_LSEEK_CMD, send_packet, length);
+
+ return ret;
+}
+
+
+//----------------------------------------------------------------------
+//
+int pcsx2fio_write_file(int fd, char *buf, int _length)
+{
+ send_packet[0] = fd;
+ send_packet[1] = (int)buf;
+ send_packet[2] = _length;
+ send_packet[3] = 0;
+
+ int length = 12;
+
+ int ret = pcsx2fio_set_call(PS2E_FIO_WRITE_CMD, send_packet, length);
+
+ return ret;
+}
+
+//----------------------------------------------------------------------
+//
+int pcsx2fio_read_file(int fd, char *buf, int _length)
+{
+ send_packet[0] = fd;
+ send_packet[1] = (int)buf;
+ send_packet[2] = _length;
+ send_packet[3] = 0;
+
+ int length = 12;
+
+ int ret = pcsx2fio_set_call(PS2E_FIO_READ_CMD, send_packet, length);
+
+ return ret;
+}
+
+//----------------------------------------------------------------------
+//
+int pcsx2fio_remove(char *name)
+{
+ strcpy((char*)(send_packet+0),name);
+
+ int length = strlen(name);
+
+ int ret = pcsx2fio_set_call(PS2E_FIO_REMOVE_CMD, send_packet, length);
+
+ return ret;
+}
+
+//----------------------------------------------------------------------
+//
+int pcsx2fio_mkdir(char *name, int mode)
+{
+ send_packet[0] = mode;
+ strcpy((char*)(send_packet+1),name);
+
+ int length = strlen(name) + 4;
+
+ int ret = pcsx2fio_set_call(PS2E_FIO_MKDIR_CMD, send_packet, length);
+
+ return ret;
+}
+
+//----------------------------------------------------------------------
+//
+int pcsx2fio_rmdir(char *name)
+{
+ strcpy((char*)(send_packet+0),name);
+
+ int length = strlen(name);
+
+ int ret = pcsx2fio_set_call(PS2E_FIO_RMDIR_CMD, send_packet, length);
+
+ return ret;
+}
+
+//----------------------------------------------------------------------
+//
+int pcsx2fio_open_dir(char *path)
+{
+ strcpy((char*)(send_packet+0),path);
+
+ int length = strlen(path);
+
+ int ret = pcsx2fio_set_call(PS2E_FIO_OPENDIR_CMD, send_packet, length);
+
+ return ret;
+}
+
+//----------------------------------------------------------------------
+//
+int pcsx2fio_read_dir(int fd, void *buf)
+{
+ send_packet[0] = fd;
+ send_packet[1] = (int)buf;
+
+ int length = 8;
+
+ int ret = pcsx2fio_set_call(PS2E_FIO_READDIR_CMD, send_packet, length);
+
+ return ret;
+}
+
+
+//----------------------------------------------------------------------
+//
+int pcsx2fio_close_dir(int fd)
+{
+ send_packet[0] = fd;
+
+ int length = 4;
+
+ int ret = pcsx2fio_set_call(PS2E_FIO_CLOSEDIR_CMD, send_packet, length);
+
+ return ret;
+}
diff --git a/pcsx2hostfs/iop/net_fio.h b/pcsx2hostfs/iop/net_fio.h
new file mode 100644
index 0000000000..d136530ad9
--- /dev/null
+++ b/pcsx2hostfs/iop/net_fio.h
@@ -0,0 +1,33 @@
+/*********************************************************************
+ * Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
+ * Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com)
+ * This file is subject to the terms and conditions of the PS2Link License.
+ * See the file LICENSE in the main directory of this distribution for more
+ * details.
+ */
+
+#ifndef _NETFIO_H_
+#define _NETFIO_H_
+
+int pcsx2fio_device_exists();
+
+int pcsx2fio_set_call(unsigned int func_id, void* params, int params_length);
+
+int pcsx2fio_file_serv(void *arg);
+int pcsx2fio_recv_bytes(int fd, char *buf, int bytes);
+int pcsx2fio_accept_pkt(int fd, char *buf, int len, int pkt_type);
+int pcsx2fio_open_file(char *path, int flags);
+int pcsx2fio_close_file(int fd);
+int pcsx2fio_read_file(int fd, char *buf, int length);
+int pcsx2fio_write_file(int fd, char *buf, int length);
+int pcsx2fio_lseek_file(int fd, unsigned int offset, int whence);
+void pcsx2fio_close_socket(void);
+void pcsx2fio_close_fsys(void);
+int pcsx2fio_remove(char *name);
+int pcsx2fio_mkdir(char *name, int mode);
+int pcsx2fio_rmdir(char *name);
+int pcsx2fio_open_dir(char *path);
+int pcsx2fio_read_dir(int fd, void *buf);
+int pcsx2fio_close_dir(int fd);
+
+#endif
diff --git a/pcsx2hostfs/iop/net_fsys.c b/pcsx2hostfs/iop/net_fsys.c
new file mode 100644
index 0000000000..6941838ee7
--- /dev/null
+++ b/pcsx2hostfs/iop/net_fsys.c
@@ -0,0 +1,306 @@
+/*********************************************************************
+ * Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
+ * Copyright (C) 2004 adresd (adresd_ps2dev@yahoo.com)
+ * This file is subject to the terms and conditions of the PS2Link License.
+ * See the file LICENSE in the main directory of this distribution for more
+ * details.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "net_fio.h"
+
+#ifdef DEBUG
+#define dbgprintf(args...) printf(args)
+#else
+#define dbgprintf(args...) do { } while(0)
+#endif
+
+static char fsname[] = "host";
+
+////////////////////////////////////////////////////////////////////////
+//static iop_device_t fsys_driver;
+
+/* File desc struct is probably larger than this, but we only
+ * need to access the word @ offset 0x0C (in which we put our identifier)
+ */
+struct filedesc_info
+{
+ int unkn0;
+ int unkn4;
+ int device_id; // the X in hostX
+ int own_fd;
+};
+
+////////////////////////////////////////////////////////////////////////
+/* We need(?) to protect the net access, so the server doesn't get
+ * confused if two processes calls a fsys func at the same time
+ */
+static int fsys_sema;
+static int fsys_pid = 0;
+//static iop_device_t fsys_driver;
+
+////////////////////////////////////////////////////////////////////////
+static int dummy5()
+{
+ printf("dummy function called\n");
+ return -5;
+}
+
+////////////////////////////////////////////////////////////////////////
+static void fsysInit(iop_device_t *driver)
+{
+
+}
+
+////////////////////////////////////////////////////////////////////////
+static int fsysDestroy(void)
+{
+ WaitSema(fsys_sema);
+ pcsx2fio_close_fsys();
+ // ExitDeleteThread(fsys_pid);
+ SignalSema(fsys_sema);
+ DeleteSema(fsys_sema);
+ return 0;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+static int fsysOpen( int fd, char *name, int mode)
+{
+ struct filedesc_info *fd_info;
+ int fsys_fd;
+
+ dbgprintf("fsysOpen..\n");
+ dbgprintf(" fd: %x, name: %s, mode: %d\n\n", fd, name, mode);
+
+ fd_info = (struct filedesc_info *)fd;
+
+ WaitSema(fsys_sema);
+ fsys_fd = pcsx2fio_open_file(name, mode);
+ SignalSema(fsys_sema);
+ fd_info->own_fd = fsys_fd;
+
+ return fsys_fd;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+static int fsysClose( int fd)
+{
+ struct filedesc_info *fd_info;
+ int ret;
+
+ dbgprintf("fsys_close..\n"
+ " fd: %x\n\n", fd);
+
+ fd_info = (struct filedesc_info *)fd;
+ WaitSema(fsys_sema);
+ ret = pcsx2fio_close_file(fd_info->own_fd);
+ SignalSema(fsys_sema);
+
+ return ret;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+static int fsysRead( int fd, char *buf, int size)
+{
+ struct filedesc_info *fd_info;
+ int ret;
+
+ fd_info = (struct filedesc_info *)fd;
+
+ dbgprintf("fsysRead..."
+ " fd: %x\n"
+ " bf: %x\n"
+ " sz: %d\n"
+ " ow: %d\n\n", fd, (int)buf, size, fd_info->own_fd);
+
+ WaitSema(fsys_sema);
+ ret = pcsx2fio_read_file(fd_info->own_fd, buf, size);
+ SignalSema(fsys_sema);
+
+ return ret;
+}
+
+
+
+
+////////////////////////////////////////////////////////////////////////
+static int fsysWrite( int fd, char *buf, int size)
+{
+ struct filedesc_info *fd_info;
+ int ret;
+
+ dbgprintf("fsysWrite..."
+ " fd: %x\n", fd);
+
+ fd_info = (struct filedesc_info *)fd;
+ WaitSema(fsys_sema);
+ ret = pcsx2fio_write_file(fd_info->own_fd, buf, size);
+ SignalSema(fsys_sema);
+ return ret;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+static int fsysLseek( int fd, unsigned int offset, int whence)
+{
+ struct filedesc_info *fd_info;
+ int ret;
+
+ dbgprintf("fsysLseek..\n"
+ " fd: %x\n"
+ " of: %x\n"
+ " wh: %x\n\n", fd, offset, whence);
+
+ fd_info = (struct filedesc_info *)fd;
+ WaitSema(fsys_sema);
+ ret = pcsx2fio_lseek_file(fd_info->own_fd, offset, whence);
+ SignalSema(fsys_sema);
+ return ret;
+}
+
+////////////////////////////////////////////////////////////////////////
+static int fsysRemove(iop_file_t* file, char *name)
+{
+ int ret;
+ dbgprintf("fsysRemove..\n");
+ dbgprintf(" name: %s\n\n", name);
+
+ WaitSema(fsys_sema);
+ ret = pcsx2fio_remove(name);
+ SignalSema(fsys_sema);
+
+ return ret;
+}
+
+////////////////////////////////////////////////////////////////////////
+static int fsysMkdir(iop_file_t* file, char *name, int mode)
+{
+ int ret;
+ dbgprintf("fsysMkdir..\n");
+ dbgprintf(" name: '%s'\n\n", name);
+
+ WaitSema(fsys_sema);
+ ret = pcsx2fio_mkdir(name, mode);
+ SignalSema(fsys_sema);
+
+ return ret;
+}
+
+////////////////////////////////////////////////////////////////////////
+static int fsysRmdir(iop_file_t* file, char *name)
+{
+ int ret;
+ dbgprintf("fsysRmdir..\n");
+ dbgprintf(" name: %s\n\n", name);
+
+ WaitSema(fsys_sema);
+ ret = pcsx2fio_rmdir(name);
+ SignalSema(fsys_sema);
+
+ return ret;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+static int fsysDopen(int fd, char *name)
+{
+ struct filedesc_info *fd_info;
+ int fsys_fd;
+
+ dbgprintf("fsysDopen..\n");
+ dbgprintf(" fd: %x, name: %s\n\n", fd, name);
+
+ fd_info = (struct filedesc_info *)fd;
+
+ WaitSema(fsys_sema);
+ fsys_fd = pcsx2fio_open_dir(name);
+ SignalSema(fsys_sema);
+ fd_info->own_fd = fsys_fd;
+
+ return fsys_fd;
+}
+
+////////////////////////////////////////////////////////////////////////
+static int fsysDread(int fd, void *buf)
+{
+ struct filedesc_info *fd_info;
+ int ret;
+
+ fd_info = (struct filedesc_info *)fd;
+
+ dbgprintf("fsysDread..."
+ " fd: %x\n"
+ " bf: %x\n"
+ " ow: %d\n\n", fd, (int)buf, fd_info->own_fd);
+
+ WaitSema(fsys_sema);
+ ret = pcsx2fio_read_dir(fd_info->own_fd, buf);
+ SignalSema(fsys_sema);
+
+ return ret;
+
+}
+
+////////////////////////////////////////////////////////////////////////
+static int fsysDclose(int fd)
+{
+ struct filedesc_info *fd_info;
+ int ret;
+
+ dbgprintf("fsys_dclose..\n"
+ " fd: %x\n\n", fd);
+
+ fd_info = (struct filedesc_info *)fd;
+ WaitSema(fsys_sema);
+ ret = pcsx2fio_close_dir(fd_info->own_fd);
+ SignalSema(fsys_sema);
+
+ return ret;
+}
+
+iop_device_ops_t fsys_functarray = { (void *)fsysInit, (void *)fsysDestroy, (void *)dummy5,
+ (void *)fsysOpen, (void *)fsysClose, (void *)fsysRead,
+ (void *)fsysWrite, (void *)fsysLseek, (void *)dummy5,
+ (void *)fsysRemove, (void *)fsysMkdir, (void *)fsysRmdir,
+ (void *)fsysDopen, (void *)fsysDclose, (void *)fsysDread,
+ (void *)dummy5, (void *)dummy5 };
+
+iop_device_t fsys_driver = { fsname, 16, 1, "fsys driver",
+ &fsys_functarray };
+////////////////////////////////////////////////////////////////////////
+// Entry point for mounting the file system
+int fsysMount(void)
+{
+ iop_sema_t sema_info;
+
+ sema_info.attr = 1;
+ sema_info.option = 0;
+ sema_info.initial = 1;
+ sema_info.max = 1;
+ fsys_sema = CreateSema(&sema_info);
+
+ DelDrv(fsname);
+ AddDrv(&fsys_driver);
+
+ return 0;
+}
+
+int fsysUnmount(void)
+{
+ DelDrv(fsname);
+ return 0;
+}
diff --git a/pcsx2hostfs/iop/nprintf.c b/pcsx2hostfs/iop/nprintf.c
new file mode 100644
index 0000000000..449c15e898
--- /dev/null
+++ b/pcsx2hostfs/iop/nprintf.c
@@ -0,0 +1,82 @@
+/*********************************************************************
+ * Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
+ * This file is subject to the terms and conditions of the PS2Link License.
+ * See the file LICENSE in the main directory of this distribution for more
+ * details.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+////////////////////////////////////////////////////////////////////////
+#define NPM_PUTS 0x01
+#define RPC_NPM_USER 0x014d704e
+
+////////////////////////////////////////////////////////////////////////
+static void *
+naplinkRpcHandler(int cmd, void *buffer, int size)
+{
+ // Only supports npmPrintf of course
+ switch(cmd) {
+ case NPM_PUTS:
+ printf(buffer);
+ break;
+ default:
+ printf("unknown npm rpc call\n");
+ }
+
+ return buffer;
+}
+
+////////////////////////////////////////////////////////////////////////
+static SifRpcServerData_t server __attribute((aligned(16)));
+static SifRpcDataQueue_t queue __attribute((aligned(16)));
+static unsigned char rpc_buffer[512] __attribute((aligned(16)));
+
+static void
+napThread(void *arg)
+{
+ int pid;
+
+ SifInitRpc(0);
+ pid = GetThreadId();
+ SifSetRpcQueue(&queue, pid);
+ SifRegisterRpc(&server, RPC_NPM_USER, naplinkRpcHandler,
+ rpc_buffer, 0, 0, &queue);
+ SifRpcLoop(&queue); // Never exits
+ ExitDeleteThread();
+}
+////////////////////////////////////////////////////////////////////////
+int
+naplinkRpcInit(void)
+{
+ struct _iop_thread th_attr;
+ int ret;
+ int pid;
+
+ th_attr.attr = 0x02000000;
+ th_attr.option = 0;
+ th_attr.thread = napThread;
+ th_attr.stacksize = 0x800;
+ th_attr.priority = 79;
+
+ pid = CreateThread(&th_attr);
+ if (pid < 0) {
+ printf("IOP: napRpc createThread failed %d\n", pid);
+ return -1;
+ }
+
+ ret = StartThread(pid, 0);
+ if (ret < 0) {
+ printf("IOP: napRpc startThread failed %d\n", ret);
+ DeleteThread(pid);
+ return -1;
+ }
+ return 0;
+}
diff --git a/pcsx2hostfs/iop/pcsx2hostfs.irx b/pcsx2hostfs/iop/pcsx2hostfs.irx
new file mode 100644
index 0000000000..0ff777f2eb
Binary files /dev/null and b/pcsx2hostfs/iop/pcsx2hostfs.irx differ
diff --git a/pcsx2hostfs/iop/ps2link.c b/pcsx2hostfs/iop/ps2link.c
new file mode 100644
index 0000000000..f556e3663a
--- /dev/null
+++ b/pcsx2hostfs/iop/ps2link.c
@@ -0,0 +1,55 @@
+/*********************************************************************
+ * Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
+ * This file is subject to the terms and conditions of the PS2Link License.
+ * See the file LICENSE in the main directory of this distribution for more
+ * details.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "excepHandler.h"
+
+// Entry points
+extern int fsysMount(void);
+extern int cmdHandlerInit(void);
+extern int ttyMount(void);
+extern int naplinkRpcInit(void);
+////////////////////////////////////////////////////////////////////////
+// main
+// start threads & init rpc & filesys
+int
+_start( int argc, char **argv)
+{
+ ttyWrite(NULL,"TEST",4);
+
+ FlushDcache();
+ CpuEnableIntr(0);
+
+ SifInitRpc(0);
+
+ pcsx2fio_device_exists();
+
+ if ((argc < 2) || (strncmp(argv[1], "-notty", 6))) {
+ ttyMount();
+ // Oh well.. There's a bug in either smapif or lwip's etharp
+ // that thrashes udp msgs which are queued while waiting for arp
+ // request
+ // alas, this msg will probably not be displayed
+ printf("tty mounted\n");
+ }
+
+ fsysMount();
+ printf("host: mounted\n");
+ naplinkRpcInit();
+ printf("Naplink thread started\n");
+
+ installExceptionHandlers();
+
+ return 0;
+}
+
diff --git a/pcsx2hostfs/iop/tty.c b/pcsx2hostfs/iop/tty.c
new file mode 100644
index 0000000000..a7364d84c2
--- /dev/null
+++ b/pcsx2hostfs/iop/tty.c
@@ -0,0 +1,105 @@
+/*********************************************************************
+ * Copyright (C) 2003 Tord Lindstrom (pukko@home.se)
+ * This file is subject to the terms and conditions of the PS2Link License.
+ * See the file LICENSE in the main directory of this distribution for more
+ * details.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "net_fio.h"
+#include "hostlink.h"
+
+////////////////////////////////////////////////////////////////////////
+
+static int tty_socket = 0;
+static int tty_sema = -1;
+
+static char ttyname[] = "tty";
+
+////////////////////////////////////////////////////////////////////////
+static int dummy()
+{
+ return -5;
+}
+
+////////////////////////////////////////////////////////////////////////
+static int dummy0()
+{
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////
+static int ttyInit(iop_device_t *driver)
+{
+ iop_sema_t sema_info;
+
+ sema_info.attr = 0;
+ sema_info.initial = 1; /* Unlocked. */
+ sema_info.max = 1;
+ if ((tty_sema = CreateSema(&sema_info)) < 0)
+ return -1;
+
+
+ if(!pcsx2fio_device_exists())
+ return -1;
+
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+static int ttyOpen( int fd, char *name, int mode)
+{
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////////////
+static int ttyClose( int fd)
+{
+ return 1;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+int ttyWrite(iop_file_t *file, char *buf, int size)
+{
+ int res;
+
+ WaitSema(tty_sema);
+
+ res = pcsx2fio_set_call(PS2E_FIO_PRINTF_CMD,buf,size);
+
+ SignalSema(tty_sema);
+ return res;
+}
+
+iop_device_ops_t tty_functarray = { ttyInit, dummy0, (void *)dummy,
+ (void *)ttyOpen, (void *)ttyClose, (void *)dummy,
+ (void *)ttyWrite, (void *)dummy, (void *)dummy,
+ (void *)dummy, (void *)dummy, (void *)dummy,
+ (void *)dummy, (void *)dummy, (void *)dummy,
+ (void *)dummy, (void *)dummy };
+
+iop_device_t tty_driver = { ttyname, 3, 1, "Fast TTY for pcsx2",
+ &tty_functarray };
+
+////////////////////////////////////////////////////////////////////////
+// Entry point for mounting the file system
+int ttyMount(void)
+{
+ close(0);
+ close(1);
+ DelDrv(ttyname);
+ AddDrv(&tty_driver);
+ if(open("tty00:", O_RDONLY) != 0) while(1);
+ if(open("tty00:", O_WRONLY) != 1) while(1);
+
+ return 0;
+}
diff --git a/pcsx2hostfs/pcsx2hostfs.sln b/pcsx2hostfs/pcsx2hostfs.sln
new file mode 100644
index 0000000000..075f4870ca
--- /dev/null
+++ b/pcsx2hostfs/pcsx2hostfs.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcsx2hostfs", "pcsx2hostfs.vcproj", "{9728FF5E-4EC6-4D47-995A-05629DCDE23F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {9728FF5E-4EC6-4D47-995A-05629DCDE23F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9728FF5E-4EC6-4D47-995A-05629DCDE23F}.Debug|Win32.Build.0 = Debug|Win32
+ {9728FF5E-4EC6-4D47-995A-05629DCDE23F}.Release|Win32.ActiveCfg = Release|Win32
+ {9728FF5E-4EC6-4D47-995A-05629DCDE23F}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/pcsx2hostfs/pcsx2hostfs.vcproj b/pcsx2hostfs/pcsx2hostfs.vcproj
new file mode 100644
index 0000000000..aff9c57583
--- /dev/null
+++ b/pcsx2hostfs/pcsx2hostfs.vcproj
@@ -0,0 +1,265 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+