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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +