From 60c1003845035ad4cd0e9ea50862bad7626faf0e Mon Sep 17 00:00:00 2001 From: Pixel Date: Sat, 21 Sep 2002 18:47:46 +0000 Subject: Added the Pcsx source. --- PcsxSrc/CdRom.c | 1049 ++++++++++++++ PcsxSrc/CdRom.h | 88 ++ PcsxSrc/Coff.h | 37 + PcsxSrc/Debug.h | 53 + PcsxSrc/Decode_XA.c | 305 ++++ PcsxSrc/Decode_XA.h | 26 + PcsxSrc/DisR3000A.c | 318 +++++ PcsxSrc/Docs/ChangeLog.txt | 255 ++++ PcsxSrc/Docs/CodingStyle.txt | 29 + PcsxSrc/Docs/License.txt | 342 +++++ PcsxSrc/Docs/Readme.txt | 189 +++ PcsxSrc/Docs/ToDo.txt | 8 + PcsxSrc/Gte.c | 2846 ++++++++++++++++++++++++++++++++++++++ PcsxSrc/Gte.h | 52 + PcsxSrc/Linux/Config.c | 125 ++ PcsxSrc/Linux/GladeCalls.c | 477 +++++++ PcsxSrc/Linux/GladeCalls.h | 239 ++++ PcsxSrc/Linux/GladeFuncs.c | 162 +++ PcsxSrc/Linux/GladeFuncs.h | 38 + PcsxSrc/Linux/GladeGui.c | 1562 +++++++++++++++++++++ PcsxSrc/Linux/GladeGui.h | 9 + PcsxSrc/Linux/GtkGui.c | 1305 +++++++++++++++++ PcsxSrc/Linux/Linux.h | 39 + PcsxSrc/Linux/LnxMain.c | 197 +++ PcsxSrc/Linux/Makefile | 62 + PcsxSrc/Linux/Plugin.c | 208 +++ PcsxSrc/Linux/Plugin.h | 38 + PcsxSrc/Linux/pcsx.glade | 2215 +++++++++++++++++++++++++++++ PcsxSrc/Mdec.c | 587 ++++++++ PcsxSrc/Mdec.h | 31 + PcsxSrc/Misc.c | 451 ++++++ PcsxSrc/Misc.h | 31 + PcsxSrc/PSEmu_Plugin_Defs.h | 247 ++++ PcsxSrc/PsxBios.c | 2164 +++++++++++++++++++++++++++++ PcsxSrc/PsxBios.h | 35 + PcsxSrc/PsxCommon.h | 131 ++ PcsxSrc/PsxCounters.c | 202 +++ PcsxSrc/PsxCounters.h | 41 + PcsxSrc/PsxDma.c | 96 ++ PcsxSrc/PsxDma.h | 27 + PcsxSrc/PsxHLE.c | 91 ++ PcsxSrc/PsxHLE.h | 24 + PcsxSrc/PsxHw.c | 756 ++++++++++ PcsxSrc/PsxHw.h | 31 + PcsxSrc/PsxInterpreter.c | 471 +++++++ PcsxSrc/PsxMem.c | 250 ++++ PcsxSrc/PsxMem.h | 75 + PcsxSrc/R3000A.c | 168 +++ PcsxSrc/R3000A.h | 186 +++ PcsxSrc/Sio.c | 577 ++++++++ PcsxSrc/Sio.h | 76 + PcsxSrc/Spu.c | 23 + PcsxSrc/Spu.h | 36 + PcsxSrc/System.h | 34 + PcsxSrc/Win32/AboutDlg.c | 44 + PcsxSrc/Win32/AboutDlg.h | 24 + PcsxSrc/Win32/Cdrom02.ico | Bin 0 -> 1078 bytes PcsxSrc/Win32/ConfigurePlugins.c | 471 +++++++ PcsxSrc/Win32/Win32.h | 48 + PcsxSrc/Win32/WndMain.c | 1044 ++++++++++++++ PcsxSrc/Win32/pcsx.dsp | 350 +++++ PcsxSrc/Win32/pcsx.dsw | 29 + PcsxSrc/Win32/pcsx.rc | 402 ++++++ PcsxSrc/Win32/plugin.c | 191 +++ PcsxSrc/Win32/plugin.h | 29 + PcsxSrc/Win32/resource.h | 266 ++++ PcsxSrc/ix86/iR3000A.c | 1236 +++++++++++++++++ PcsxSrc/ix86/ix86.c | 966 +++++++++++++ PcsxSrc/ix86/ix86.h | 397 ++++++ PcsxSrc/pcsxAbout.bmp | Bin 0 -> 105270 bytes PcsxSrc/plugins.c | 678 +++++++++ PcsxSrc/plugins.h | 269 ++++ 72 files changed, 25558 insertions(+) create mode 100644 PcsxSrc/CdRom.c create mode 100644 PcsxSrc/CdRom.h create mode 100644 PcsxSrc/Coff.h create mode 100644 PcsxSrc/Debug.h create mode 100644 PcsxSrc/Decode_XA.c create mode 100644 PcsxSrc/Decode_XA.h create mode 100644 PcsxSrc/DisR3000A.c create mode 100644 PcsxSrc/Docs/ChangeLog.txt create mode 100644 PcsxSrc/Docs/CodingStyle.txt create mode 100644 PcsxSrc/Docs/License.txt create mode 100644 PcsxSrc/Docs/Readme.txt create mode 100644 PcsxSrc/Docs/ToDo.txt create mode 100644 PcsxSrc/Gte.c create mode 100644 PcsxSrc/Gte.h create mode 100644 PcsxSrc/Linux/Config.c create mode 100644 PcsxSrc/Linux/GladeCalls.c create mode 100644 PcsxSrc/Linux/GladeCalls.h create mode 100644 PcsxSrc/Linux/GladeFuncs.c create mode 100644 PcsxSrc/Linux/GladeFuncs.h create mode 100644 PcsxSrc/Linux/GladeGui.c create mode 100644 PcsxSrc/Linux/GladeGui.h create mode 100644 PcsxSrc/Linux/GtkGui.c create mode 100644 PcsxSrc/Linux/Linux.h create mode 100644 PcsxSrc/Linux/LnxMain.c create mode 100644 PcsxSrc/Linux/Makefile create mode 100644 PcsxSrc/Linux/Plugin.c create mode 100644 PcsxSrc/Linux/Plugin.h create mode 100644 PcsxSrc/Linux/pcsx.glade create mode 100644 PcsxSrc/Mdec.c create mode 100644 PcsxSrc/Mdec.h create mode 100644 PcsxSrc/Misc.c create mode 100644 PcsxSrc/Misc.h create mode 100644 PcsxSrc/PSEmu_Plugin_Defs.h create mode 100644 PcsxSrc/PsxBios.c create mode 100644 PcsxSrc/PsxBios.h create mode 100644 PcsxSrc/PsxCommon.h create mode 100644 PcsxSrc/PsxCounters.c create mode 100644 PcsxSrc/PsxCounters.h create mode 100644 PcsxSrc/PsxDma.c create mode 100644 PcsxSrc/PsxDma.h create mode 100644 PcsxSrc/PsxHLE.c create mode 100644 PcsxSrc/PsxHLE.h create mode 100644 PcsxSrc/PsxHw.c create mode 100644 PcsxSrc/PsxHw.h create mode 100644 PcsxSrc/PsxInterpreter.c create mode 100644 PcsxSrc/PsxMem.c create mode 100644 PcsxSrc/PsxMem.h create mode 100644 PcsxSrc/R3000A.c create mode 100644 PcsxSrc/R3000A.h create mode 100644 PcsxSrc/Sio.c create mode 100644 PcsxSrc/Sio.h create mode 100644 PcsxSrc/Spu.c create mode 100644 PcsxSrc/Spu.h create mode 100644 PcsxSrc/System.h create mode 100644 PcsxSrc/Win32/AboutDlg.c create mode 100644 PcsxSrc/Win32/AboutDlg.h create mode 100644 PcsxSrc/Win32/Cdrom02.ico create mode 100644 PcsxSrc/Win32/ConfigurePlugins.c create mode 100644 PcsxSrc/Win32/Win32.h create mode 100644 PcsxSrc/Win32/WndMain.c create mode 100644 PcsxSrc/Win32/pcsx.dsp create mode 100644 PcsxSrc/Win32/pcsx.dsw create mode 100644 PcsxSrc/Win32/pcsx.rc create mode 100644 PcsxSrc/Win32/plugin.c create mode 100644 PcsxSrc/Win32/plugin.h create mode 100644 PcsxSrc/Win32/resource.h create mode 100644 PcsxSrc/ix86/iR3000A.c create mode 100644 PcsxSrc/ix86/ix86.c create mode 100644 PcsxSrc/ix86/ix86.h create mode 100644 PcsxSrc/pcsxAbout.bmp create mode 100644 PcsxSrc/plugins.c create mode 100644 PcsxSrc/plugins.h diff --git a/PcsxSrc/CdRom.c b/PcsxSrc/CdRom.c new file mode 100644 index 0000000..795cdce --- /dev/null +++ b/PcsxSrc/CdRom.c @@ -0,0 +1,1049 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +//THIS ALL IS FOR THE CDROM REGISTERS HANDLING +#include "PsxCommon.h" + +#define CdlSync 0 +#define CdlNop 1 +#define CdlSetloc 2 +#define CdlPlay 3 +#define CdlForward 4 +#define CdlBackward 5 +#define CdlReadN 6 +#define CdlStandby 7 +#define CdlStop 8 +#define CdlPause 9 +#define CdlInit 10 +#define CdlMute 11 +#define CdlDemute 12 +#define CdlSetfilter 13 +#define CdlSetmode 14 +#define CdlGetmode 15 +#define CdlGetlocL 16 +#define CdlGetlocP 17 +#define Cdl18 18 +#define CdlGetTN 19 +#define CdlGetTD 20 +#define CdlSeekL 21 +#define CdlSeekP 22 +#define CdlTest 25 +#define CdlID 26 +#define CdlReadS 27 +#define CdlReset 28 +#define CdlReadToc 30 + +#define AUTOPAUSE 249 +#define READ_ACK 250 +#define READ 251 +#define REPPLAY_ACK 252 +#define REPPLAY 253 +#define ASYNC 254 +/* don't set 255, it's reserved */ + +char *CmdName[0x100]= { + "CdlSync", "CdlNop", "CdlSetloc", "CdlPlay", + "CdlForward", "CdlBackward", "CdlReadN", "CdlStandby", + "CdlStop", "CdlPause", "CdlInit", "CdlMute", + "CdlDemute", "CdlSetfilter", "CdlSetmode", "CdlGetmode", + "CdlGetlocL", "CdlGetlocP", "Cdl18", "CdlGetTN", + "CdlGetTD", "CdlSeekL", "CdlSeekP", NULL, + NULL, "CdlTest", "CdlID", "CdlReadS", + "CdlReset", NULL, "CDlReadToc", NULL +}; + +unsigned char Test04[] = { 0 }; +unsigned char Test05[] = { 0 }; +unsigned char Test20[] = { 0x98, 0x06, 0x10, 0xC3 }; +unsigned char Test22[] = { 0x66, 0x6F, 0x72, 0x20, 0x45, 0x75, 0x72, 0x6F }; +unsigned char Test23[] = { 0x43, 0x58, 0x44, 0x32, 0x39 ,0x34, 0x30, 0x51 }; + +// 1x = 75 sectors per second +// PSXCLK = 1 sec in the ps +// so (PSXCLK / 75) / BIAS = cdr read time (linuzappz) +//#define cdReadTime ((PSXCLK / 75) / BIAS) +unsigned long cdReadTime = ((PSXCLK / 75) / BIAS); + +#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */ +#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */ + +static struct CdrStat stat; +static struct SubQ *subq; + +#define CDR_INT(eCycle) { \ + psxRegs.interrupt|= 0x4; \ + psxRegs.intCycle[2+1] = eCycle; \ + psxRegs.intCycle[2] = psxRegs.cycle; } + +#define CDREAD_INT(eCycle) { \ + psxRegs.interrupt|= 0x40000; \ + psxRegs.intCycle[2+16+1] = eCycle; \ + psxRegs.intCycle[2+16] = psxRegs.cycle; } + +#define StartReading(type) { \ + cdr.Reading = type; \ + cdr.FirstSector = 1; \ + cdr.Readed = 0xff; \ + AddIrqQueue(READ_ACK, 0x800); \ +} + +#define StopReading() { \ + if (cdr.Reading) { \ + cdr.Reading = 0; \ + psxRegs.interrupt&=~0x40000; \ + } \ +} + +#define StopCdda() { \ + if (cdr.Play) { \ + if (!Config.Cdda) CDR_stop(); \ + cdr.StatP&=~0x80; \ + cdr.Play = 0; \ + } \ +} + +#define SetResultSize(size) { \ + cdr.ResultP = 0; \ + cdr.ResultC = size; \ + cdr.ResultReady = 1; \ +} + +void ReadTrack() { + + cdr.Prev[0] = itob(cdr.SetSector[0]); + cdr.Prev[1] = itob(cdr.SetSector[1]); + cdr.Prev[2] = itob(cdr.SetSector[2]); + +#ifdef CDR_LOG + CDR_LOG("KEY *** %x:%x:%x\n", cdr.Prev[0], cdr.Prev[1], cdr.Prev[2]); +#endif + cdr.RErr = CDR_readTrack(cdr.Prev); +} + +// cdr.Stat: +#define NoIntr 0 +#define DataReady 1 +#define Complete 2 +#define Acknowledge 3 +#define DataEnd 4 +#define DiskError 5 + +void AddIrqQueue(unsigned char irq, unsigned long ecycle) { + cdr.Irq = irq; + if (cdr.Stat) { + cdr.eCycle = ecycle; + } else { + CDR_INT(ecycle); + } +} + +void cdrInterrupt() { + int i; + unsigned char Irq = cdr.Irq; + + if (cdr.Stat) { + CDR_INT(0x800); + return; + } + + cdr.Irq = 0xff; + cdr.Ctrl&=~0x80; + + switch (Irq) { + case CdlSync: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + break; + + case CdlNop: + SetResultSize(1); + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + i = stat.Status; + if (CDR_getStatus(&stat) != -1) { + if (stat.Type == 0xff) cdr.Stat = DiskError; + if (stat.Status & 0x10) { + cdr.Stat = DiskError; + cdr.Result[0]|= 0x11; + cdr.Result[0]&=~0x02; + } + else if (i & 0x10) { + cdr.StatP |= 0x2; + cdr.Result[0]|= 0x2; + CheckCdrom(); + } + } + break; + + case CdlSetloc: + cdr.CmdProcess = 0; + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + break; + + case CdlPlay: + cdr.CmdProcess = 0; + SetResultSize(1); + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + cdr.StatP|= 0x82; +// if ((cdr.Mode & 0x5) == 0x5) AddIrqQueue(REPPLAY, cdReadTime); + break; + + case CdlForward: + cdr.CmdProcess = 0; + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Complete; + break; + + case CdlBackward: + cdr.CmdProcess = 0; + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Complete; + break; + + case CdlStandby: + cdr.CmdProcess = 0; + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Complete; + break; + + case CdlStop: + cdr.CmdProcess = 0; + SetResultSize(1); + cdr.StatP&=~0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Complete; +// cdr.Stat = Acknowledge; + break; + + case CdlPause: + SetResultSize(1); + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + AddIrqQueue(CdlPause + 0x20, 0x800); + break; + + case CdlPause + 0x20: + SetResultSize(1); + cdr.StatP&=~0x20; + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Complete; + break; + + case CdlInit: + SetResultSize(1); + cdr.StatP = 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; +// if (!cdr.Init) { + AddIrqQueue(CdlInit + 0x20, 0x800); +// } + break; + + case CdlInit + 0x20: + SetResultSize(1); + cdr.Result[0] = cdr.StatP; + cdr.Stat = Complete; + cdr.Init = 1; + break; + + case CdlMute: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + break; + + case CdlDemute: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + break; + + case CdlSetfilter: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + break; + + case CdlSetmode: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + break; + + case CdlGetmode: + SetResultSize(6); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Result[1] = cdr.Mode; + cdr.Result[2] = cdr.File; + cdr.Result[3] = cdr.Channel; + cdr.Result[4] = 0; + cdr.Result[5] = 0; + cdr.Stat = Acknowledge; + break; + + case CdlGetlocL: + SetResultSize(8); +// for (i=0; i<8; i++) cdr.Result[i] = itob(cdr.Transfer[i]); + for (i=0; i<8; i++) cdr.Result[i] = cdr.Transfer[i]; + cdr.Stat = Acknowledge; + break; + + case CdlGetlocP: + SetResultSize(8); + subq = (struct SubQ*) CDR_getBufferSub(); + if (subq != NULL) { + cdr.Result[0] = subq->TrackNumber; + cdr.Result[1] = subq->IndexNumber; + memcpy(cdr.Result+2, subq->TrackRelativeAddress, 3); + memcpy(cdr.Result+5, subq->AbsoluteAddress, 3); + } else { + cdr.Result[0] = 1; + cdr.Result[1] = 1; + cdr.Result[2] = cdr.Prev[0]; + cdr.Result[3] = itob((btoi(cdr.Prev[1])) - 2); + cdr.Result[4] = cdr.Prev[2]; + memcpy(cdr.Result+5, cdr.Prev, 3); + } + cdr.Stat = Acknowledge; + break; + + case CdlGetTN: + cdr.CmdProcess = 0; + SetResultSize(3); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + if (CDR_getTN(cdr.ResultTN) == -1) { + cdr.Stat = DiskError; + cdr.Result[0]|= 0x01; + } else { + cdr.Stat = Acknowledge; + cdr.Result[1] = itob(cdr.ResultTN[0]); + cdr.Result[2] = itob(cdr.ResultTN[1]); + } + break; + + case CdlGetTD: + cdr.CmdProcess = 0; + cdr.Track = btoi(cdr.Param[0]); + SetResultSize(4); + cdr.StatP|= 0x2; + if (CDR_getTD(cdr.Track, cdr.ResultTD) == -1) { + cdr.Stat = DiskError; + cdr.Result[0]|= 0x01; + } else { + cdr.Stat = Acknowledge; + cdr.Result[0] = cdr.StatP; + cdr.Result[1] = itob(cdr.ResultTD[2]); + cdr.Result[2] = itob(cdr.ResultTD[1]); + cdr.Result[3] = itob(cdr.ResultTD[0]); + } + break; + + case CdlSeekL: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + AddIrqQueue(CdlSeekL + 0x20, 0x800); + break; + + case CdlSeekL + 0x20: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Complete; + break; + + case CdlSeekP: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + AddIrqQueue(CdlSeekP + 0x20, 0x800); + break; + + case CdlSeekP + 0x20: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Complete; + break; + + case CdlTest: + cdr.Stat = Acknowledge; + switch (cdr.Param[0]) { + case 0x20: // System Controller ROM Version + SetResultSize(4); + memcpy(cdr.Result, Test20, 4); + break; + case 0x22: + SetResultSize(8); + memcpy(cdr.Result, Test22, 4); + break; + case 0x23: case 0x24: + SetResultSize(8); + memcpy(cdr.Result, Test23, 4); + break; + } + break; + + case CdlID: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + AddIrqQueue(CdlID + 0x20, 0x800); + break; + + case CdlID + 0x20: + SetResultSize(8); + if (CDR_getStatus(&stat) == -1) { + cdr.Result[0] = 0x00; // 0x08 and cdr.Result[1]|0x10 : audio cd, enters cd player + cdr.Result[1] = 0x00; // 0x80 leads to the menu in the bios, else loads CD + } + else { + if (stat.Type == 2) { + cdr.Result[0] = 0x08; + cdr.Result[1] = 0x10; + } + else { + cdr.Result[0] = 0x00; + cdr.Result[1] = 0x00; + } + } + if (!LoadCdBios) cdr.Result[1] |= 0x80; + + cdr.Result[2] = 0x00; + cdr.Result[3] = 0x00; + strncpy((char *)&cdr.Result[4], "PCSX", 4); + cdr.Stat = Complete; + break; + + case CdlReset: + SetResultSize(1); + cdr.StatP = 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + break; + + case CdlReadToc: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + AddIrqQueue(CdlReadToc + 0x20, 0x800); + break; + + case CdlReadToc + 0x20: + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Complete; + break; + + case AUTOPAUSE: + cdr.OCUP = 0; +/* SetResultSize(1); + StopCdda(); + StopReading(); + cdr.OCUP = 0; + cdr.StatP&=~0x20; + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = DataEnd; +*/ AddIrqQueue(CdlPause, 0x400); + break; + + case READ_ACK: + if (!cdr.Reading) return; + + SetResultSize(1); + cdr.StatP|= 0x2; + cdr.Result[0] = cdr.StatP; + cdr.Stat = Acknowledge; + + ReadTrack(); + + CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); + + break; + + case REPPLAY_ACK: + cdr.Stat = Acknowledge; + cdr.Result[0] = cdr.StatP; + SetResultSize(1); + AddIrqQueue(REPPLAY, cdReadTime); + break; + + case REPPLAY: + if ((cdr.Mode & 5) != 5) break; +/* if (CDR_getStatus(&stat) == -1) { + cdr.Result[0] = 0; + cdr.Result[1] = 0; + cdr.Result[2] = 0; + cdr.Result[3] = 0; + cdr.Result[4] = 0; + cdr.Result[5] = 0; + cdr.Result[6] = 0; + cdr.Result[7] = 0; + } else memcpy(cdr.Result, &stat.Track, 8); + cdr.Stat = 1; + SetResultSize(8); + AddIrqQueue(REPPLAY_ACK, cdReadTime); +*/ break; + + case 0xff: + return; + + default: + cdr.Stat = Complete; + break; + } + + if (cdr.Stat != NoIntr && cdr.Reg2 != 0x18) psxHu32(0x1070)|=0x4; + +#ifdef CDR_LOG + CDR_LOG("Cdr Interrupt %x\n", Irq); +#endif +} + +void cdrReadInterrupt() { + unsigned char *buf; + + if (!cdr.Reading) return; + + if (cdr.Stat) { + CDREAD_INT(0x800); + return; + } + +#ifdef CDR_LOG + CDR_LOG("KEY END"); +#endif + + cdr.OCUP = 1; + SetResultSize(1); + cdr.StatP|= 0x22; + cdr.Result[0] = cdr.StatP; + + buf = CDR_getBuffer(); + if (buf == NULL) cdr.RErr = -1; + + if (cdr.RErr == -1) { +#ifdef CDR_LOG + fprintf(emuLog, " err\n"); +#endif + memset(cdr.Transfer, 0, 2340); + cdr.Stat = DiskError; + cdr.Result[0]|= 0x01; + ReadTrack(); + CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); + return; + } + + memcpy(cdr.Transfer, buf, 2340); + cdr.Stat = DataReady; + +#ifdef CDR_LOG + fprintf(emuLog, " %x:%x:%x\n", cdr.Transfer[0], cdr.Transfer[1], cdr.Transfer[2]); +#endif + + if ((cdr.Muted == 1) && (cdr.Mode & 0x40) && (!Config.Xa) && (cdr.FirstSector != -1)) { // CD-XA + if ((cdr.Transfer[4+2] & 0x4) && + ((cdr.Mode&0x8) ? (cdr.Transfer[4+1] == cdr.Channel) : 1) && + (cdr.Transfer[4+0] == cdr.File)) { + int ret = xa_decode_sector(&cdr.Xa, cdr.Transfer+4, cdr.FirstSector); + + if (!ret) { + SPU_playADPCMchannel(&cdr.Xa); + cdr.FirstSector = 0; + } + else cdr.FirstSector = -1; + } + } + + cdr.SetSector[2]++; + if (cdr.SetSector[2] == 75) { + cdr.SetSector[2] = 0; + cdr.SetSector[1]++; + if (cdr.SetSector[1] == 60) { + cdr.SetSector[1] = 0; + cdr.SetSector[0]++; + } + } + + cdr.Readed = 0; + + if ((cdr.Transfer[4+2] & 0x80) && (cdr.Mode & 0x2)) { // EOF +#ifdef CDR_LOG + CDR_LOG("AutoPausing Read\n"); +#endif +// AddIrqQueue(AUTOPAUSE, 0x800); + AddIrqQueue(CdlPause, 0x800); + } + else { + ReadTrack(); + CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); + } + psxHu32(0x1070)|=0x4; +} + +/* +cdrRead0: + bit 0 - 0 REG1 command send / 1 REG1 data read + bit 1 - 0 data transfer finish / 1 data transfer ready/in progress + bit 2 - unknown + bit 3 - unknown + bit 4 - unknown + bit 5 - 1 result ready + bit 6 - 1 dma ready + bit 7 - 1 command being processed +*/ + +unsigned char cdrRead0(void) { + if (cdr.ResultReady) cdr.Ctrl|= 0x20; + else cdr.Ctrl&=~0x20; + + if (cdr.OCUP) cdr.Ctrl|= 0x40; + else cdr.Ctrl&=~0x40; + + // what means the 0x10 and the 0x08 bits? i only saw it used by the bios + cdr.Ctrl|=0x18; + +#ifdef CDR_LOG + CDR_LOG("CD0 Read: %x\n", cdr.Ctrl); +#endif + return psxHu8(0x1800) = cdr.Ctrl; +} + +/* +cdrWrite0: + 0 - to send a command / 1 - to get the result +*/ + +void cdrWrite0(unsigned char rt) { +#ifdef CDR_LOG + CDR_LOG("CD0 write: %x\n", rt); +#endif + cdr.Ctrl = rt | (cdr.Ctrl & ~0x3); + + if (rt == 0) { + cdr.ParamP = 0; + cdr.ParamC = 0; + cdr.ResultReady = 0; + } +} + +unsigned char cdrRead1(void) { + if (cdr.ResultReady && cdr.Ctrl & 0x1) { + psxHu8(0x1801) = cdr.Result[cdr.ResultP++]; + if (cdr.ResultP == cdr.ResultC) cdr.ResultReady = 0; + } else psxHu8(0x1801) = 0; +#ifdef CDR_LOG + CDR_LOG("CD1 Read: %x\n", psxHu8(0x1801)); +#endif + return psxHu8(0x1801); +} + +void cdrWrite1(unsigned char rt) { + int i; + +#ifdef CDR_LOG + CDR_LOG("CD1 write: %x (%s)\n", rt, CmdName[rt]); +#endif +// psxHu8(0x1801) = rt; + cdr.Cmd = rt; + cdr.OCUP = 0; + +#ifdef CDRCMD_DEBUG + SysPrintf("CD1 write: %x (%s)", rt, CmdName[rt]); + if (cdr.ParamC) { + SysPrintf(" Param[%d] = {", cdr.ParamC); + for (i=0;i cdr.ResultTN[1]) cdr.CurTrack = cdr.ResultTN[1]; + if (CDR_getTD((unsigned char)(cdr.CurTrack), cdr.ResultTD) != -1) { + int tmp = cdr.ResultTD[2]; + cdr.ResultTD[2] = cdr.ResultTD[0]; + cdr.ResultTD[0] = tmp; + if (!Config.Cdda) CDR_play(cdr.ResultTD); + } + } + } + else if (!Config.Cdda) CDR_play(cdr.SetSector); + cdr.Play = 1; + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlForward: + if (cdr.CurTrack < 0xaa) cdr.CurTrack++; + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlBackward: + if (cdr.CurTrack > 1) cdr.CurTrack--; + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlReadN: + cdr.Irq = 0; + StopReading(); + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + StartReading(1); + break; + + case CdlStandby: + StopCdda(); + StopReading(); + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlStop: + StopCdda(); + StopReading(); + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlPause: + StopCdda(); + StopReading(); + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x40000); + break; + + case CdlReset: + case CdlInit: + StopCdda(); + StopReading(); + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlMute: + cdr.Muted = 0; + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlDemute: + cdr.Muted = 1; + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlSetfilter: + cdr.File = cdr.Param[0]; + cdr.Channel = cdr.Param[1]; + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlSetmode: +#ifdef CDR_LOG + CDR_LOG("Setmode %x\n", cdr.Param[0]); +#endif + cdr.Mode = cdr.Param[0]; + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlGetmode: + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlGetlocL: + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlGetlocP: + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlGetTN: + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlGetTD: + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlSeekL: + ((unsigned long *)cdr.SetSectorSeek)[0] = ((unsigned long *)cdr.SetSector)[0]; + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlSeekP: + ((unsigned long *)cdr.SetSectorSeek)[0] = ((unsigned long *)cdr.SetSector)[0]; + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlTest: + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlID: + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + case CdlReadS: + cdr.Irq = 0; + StopReading(); + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + StartReading(2); + break; + + case CdlReadToc: + cdr.Ctrl|= 0x80; + cdr.Stat = NoIntr; + AddIrqQueue(cdr.Cmd, 0x800); + break; + + default: +#ifdef CDR_LOG + CDR_LOG("Unknown Cmd: %x\n", cdr.Cmd); +#endif + return; + } + if (cdr.Stat != NoIntr) psxHu32(0x1070)|=0x4; +} + +unsigned char cdrRead2(void) { + unsigned char ret; + + if (cdr.Readed == 0) { + ret = 0; + } else { + ret = *cdr.pTransfer++; + } + +#ifdef CDR_LOG + CDR_LOG("CD2 Read: %x\n", ret); +#endif + return ret; +} + +void cdrWrite2(unsigned char rt) { +#ifdef CDR_LOG + CDR_LOG("CD2 write: %x\n", rt); +#endif + if (cdr.Ctrl & 0x1) { + switch (rt) { + case 0x07: + cdr.ParamP = 0; + cdr.ParamC = 0; + cdr.ResultReady = 0; + cdr.Ctrl = 0; + break; + + default: + cdr.Reg2 = rt; + break; + } + } else if (!(cdr.Ctrl & 0x1) && cdr.ParamP < 8) { + cdr.Param[cdr.ParamP++] = rt; + cdr.ParamC++; + } +} + +unsigned char cdrRead3(void) { + if (cdr.Stat) { + if (cdr.Ctrl & 0x1) psxHu8(0x1803) = cdr.Stat | 0xE0; + else psxHu8(0x1803) = 0xff; + } else psxHu8(0x1803) = 0; +#ifdef CDR_LOG + CDR_LOG("CD3 Read: %x\n", psxHu8(0x1803)); +#endif + return psxHu8(0x1803); +} + +void cdrWrite3(unsigned char rt) { +#ifdef CDR_LOG + CDR_LOG("CD3 write: %x\n", rt); +#endif + if (rt == 0x07 && cdr.Ctrl & 0x1) { + cdr.Stat = 0; + + if (cdr.Irq == 0xff) { cdr.Irq = 0; return; } + if (cdr.Irq) CDR_INT(cdr.eCycle); + if (cdr.Reading && !cdr.ResultReady) + CDREAD_INT((cdr.Mode & 0x80) ? (cdReadTime / 2) : cdReadTime); + + return; + } + if (rt == 0x80 && !(cdr.Ctrl & 0x1) && cdr.Readed == 0) { + cdr.Readed = 1; + cdr.pTransfer = cdr.Transfer; + + switch (cdr.Mode&0x30) { + case 0x10: + case 0x00: cdr.pTransfer+=12; break; + default: break; + } + } +} + +void psxDma3(u32 madr, u32 bcr, u32 chcr) { + u32 cdsize; + +#ifdef CDR_LOG + CDR_LOG("*** DMA 3 *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); +#endif + + switch (chcr) { + case 0x11000000: + case 0x11400100: + if (cdr.Readed == 0) { +#ifdef CDR_LOG + CDR_LOG("*** DMA 3 *** NOT READY\n"); +#endif + return; + } + + cdsize = (bcr & 0xffff) * 4; + + memcpy((u8*)PSXM(madr), cdr.pTransfer, cdsize); + psxCpu->Clear(madr, cdsize/4); + cdr.pTransfer+=cdsize; + + break; + default: +#ifdef CDR_LOG + CDR_LOG("Unknown cddma %lx\n", chcr); +#endif + break; + } +} + +void cdrReset() { + memset(&cdr, 0, sizeof(cdr)); + cdr.CurTrack=1; + cdr.File=1; cdr.Channel=1; + // with the timing set to 60 Gran Turismo works + // anybody knows why it doesn't with 75? + // 75 is the correct cdrom timing + if (Config.CdTiming) + cdReadTime = (PSXCLK / 60) / BIAS; + // this seems to be the most compatible + // let's leave like this until we know why + // 75 is buggy with some games + else cdReadTime = (PSXCLK / 65) / BIAS; +// else cdReadTime = (PSXCLK / 75) / BIAS; +} + +int cdrFreeze(gzFile f, int Mode) { + int tmp; + + gzfreeze(&cdr, sizeof(cdr)); + + if (Mode == 1) tmp = cdr.pTransfer - cdr.Transfer; + gzfreezel(&tmp); + if (Mode == 0) cdr.pTransfer = cdr.Transfer + tmp; + + return 0; +} + diff --git a/PcsxSrc/CdRom.h b/PcsxSrc/CdRom.h new file mode 100644 index 0000000..66aca78 --- /dev/null +++ b/PcsxSrc/CdRom.h @@ -0,0 +1,88 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __CDROM_H__ +#define __CDROM_H__ + +#include "PsxCommon.h" +#include "Decode_XA.h" + +typedef struct { + unsigned char OCUP; + unsigned char Reg1Mode; + unsigned char Reg2; + unsigned char CmdProcess; + unsigned char Ctrl; + unsigned char Stat; + + unsigned char StatP; + + unsigned char Transfer[2352]; + unsigned char *pTransfer; + + unsigned char Prev[4]; + unsigned char Param[8]; + unsigned char Result[8]; + + unsigned char ParamC; + unsigned char ParamP; + unsigned char ResultC; + unsigned char ResultP; + unsigned char ResultReady; + unsigned char Cmd; + unsigned char Readed; + unsigned long Reading; + + unsigned char ResultTN[6]; + unsigned char ResultTD[4]; + unsigned char SetSector[4]; + unsigned char SetSectorSeek[4]; + unsigned char Track; + int Play; + int CurTrack; + int Mode, File, Channel, Muted; + int Reset; + int RErr; + int FirstSector; + + xa_decode_t Xa; + + int Init; + + unsigned char Irq; + unsigned long eCycle; + + char Unused[4087]; +} cdrStruct; + +cdrStruct cdr; + +void cdrReset(); +void cdrInterrupt(); +void cdrReadInterrupt(); +unsigned char cdrRead0(void); +unsigned char cdrRead1(void); +unsigned char cdrRead2(void); +unsigned char cdrRead3(void); +void cdrWrite0(unsigned char rt); +void cdrWrite1(unsigned char rt); +void cdrWrite2(unsigned char rt); +void cdrWrite3(unsigned char rt); +int cdrFreeze(gzFile f, int Mode); + +#endif /* __CDROM_H__ */ diff --git a/PcsxSrc/Coff.h b/PcsxSrc/Coff.h new file mode 100644 index 0000000..c725aa7 --- /dev/null +++ b/PcsxSrc/Coff.h @@ -0,0 +1,37 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __COFF_H__ +#define __COFF_H__ + +/********************** FILE HEADER **********************/ + +struct external_filehdr { + unsigned short f_magic; /* magic number */ + unsigned short f_nscns; /* number of sections */ + unsigned long f_timdat; /* time & date stamp */ + unsigned long f_symptr; /* file pointer to symtab */ + unsigned long f_nsyms; /* number of symtab entries */ + unsigned short f_opthdr; /* sizeof(optional hdr) */ + unsigned short f_flags; /* flags */ +}; + +#define FILHDR struct external_filehdr +#define FILHSZ sizeof(FILHDR) + +#endif /* __COFF_H__ */ diff --git a/PcsxSrc/Debug.h b/PcsxSrc/Debug.h new file mode 100644 index 0000000..14f94cb --- /dev/null +++ b/PcsxSrc/Debug.h @@ -0,0 +1,53 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __DEBUG_H__ +#define __DEBUG_H__ + +#include "PsxCommon.h" + +char* disR3000AF(u32 code, u32 pc); + +FILE *emuLog; + +//#define GTE_DUMP + +#ifdef GTE_DUMP +FILE *gteLog; +#endif + +//#define LOG_STDOUT + +//#define PAD_LOG __Log +//#define GTE_LOG __Log +//#define CDR_LOG __Log("%8.8lx %8.8lx: ", psxRegs.pc, psxRegs.cycle); __Log + +//#define PSXHW_LOG __Log("%8.8lx %8.8lx: ", psxRegs.pc, psxRegs.cycle); __Log +//#define PSXBIOS_LOG __Log("%8.8lx %8.8lx: ", psxRegs.pc, psxRegs.cycle); __Log +//#define PSXDMA_LOG __Log +//#define PSXMEM_LOG __Log("%8.8lx %8.8lx: ", psxRegs.pc, psxRegs.cycle); __Log +//#define PSXCPU_LOG __Log + +//#define CDRCMD_DEBUG + +#if defined (PSXCPU_LOG) || defined(PSXDMA_LOG) || defined(CDR_LOG) || defined(PSXHW_LOG) || \ + defined(PSXBIOS_LOG) || defined(GTE_LOG) || defined(PAD_LOG) +#define EMU_LOG __Log +#endif + +#endif /* __DEBUG_H__ */ diff --git a/PcsxSrc/Decode_XA.c b/PcsxSrc/Decode_XA.c new file mode 100644 index 0000000..3bd53f4 --- /dev/null +++ b/PcsxSrc/Decode_XA.c @@ -0,0 +1,305 @@ +//============================================ +//=== Audio XA decoding +//=== Kazzuya +//============================================ +//=== Modified by linuzappz +//============================================ + +#include + +#include "Decode_XA.h" + +#ifdef __WIN32__ +#pragma warning(disable:4244) +#endif + +typedef unsigned char U8; +typedef unsigned short U16; +typedef unsigned long U32; + +#define NOT(_X_) (!(_X_)) +#define CLAMP(_X_,_MI_,_MA_) {if(_X_<_MI_)_X_=_MI_;if(_X_>_MA_)_X_=_MA_;} + +//============================================ +//=== ADPCM DECODING ROUTINES +//============================================ + +static double K0[4] = { + 0.0, + 0.9375, + 1.796875, + 1.53125 +}; + +static double K1[4] = { + 0.0, + 0.0, + -0.8125, + -0.859375 +}; + +#define BLKSIZ 28 /* block size (32 - 4 nibbles) */ + +//=========================================== +void ADPCM_InitDecode( ADPCM_Decode_t *decp ) +{ + decp->y0 = 0; + decp->y1 = 0; +} + +//=========================================== +#define SH 4 +#define SHC 10 + +#define IK0(fid) ((int)((-K0[fid]) * (1<> 4) & 0x0f; + range = (filter_range >> 0) & 0x0f; + + fy0 = decp->y0; + fy1 = decp->y1; + + for (i = BLKSIZ/4; i; --i) { + long y; + long x0, x1, x2, x3; + + y = *blockp++; + x3 = (short)( y & 0xf000) >> range; x3 <<= SH; + x2 = (short)((y << 4) & 0xf000) >> range; x2 <<= SH; + x1 = (short)((y << 8) & 0xf000) >> range; x1 <<= SH; + x0 = (short)((y << 12) & 0xf000) >> range; x0 <<= SH; + + x0 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x0; + x1 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x1; + x2 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x2; + x3 -= (IK0(filterid) * fy0 + (IK1(filterid) * fy1)) >> SHC; fy1 = fy0; fy0 = x3; + + CLAMP( x0, -32768<> SH; destp += inc; + CLAMP( x1, -32768<> SH; destp += inc; + CLAMP( x2, -32768<> SH; destp += inc; + CLAMP( x3, -32768<> SH; destp += inc; + } + decp->y0 = fy0; + decp->y1 = fy1; +} + +static int headtable[4] = {0,2,8,10}; + +//=========================================== +static void xa_decode_data( xa_decode_t *xdp, unsigned char *srcp ) { + const U8 *sound_groupsp; + const U8 *sound_datap, *sound_datap2; + int i, j, k, nbits; + U16 data[4096], *datap; + short *destp; + + destp = xdp->pcm; + nbits = xdp->nbits == 4 ? 4 : 2; + + if (xdp->stereo) { // stereo + for (j=0; j < 18; j++) { + sound_groupsp = srcp + j * 128; // sound groups header + sound_datap = sound_groupsp + 16; // sound data just after the header + + for (i=0; i < nbits; i++) { + datap = data; + sound_datap2 = sound_datap + i; + if ((xdp->nbits == 8) && (xdp->freq == 37800)) { // level A + for (k=0; k < 14; k++, sound_datap2 += 8) { + *(datap++) = (U16)sound_datap2[0] | + (U16)(sound_datap2[4] << 8); + } + } else { // level B/C + for (k=0; k < 7; k++, sound_datap2 += 16) { + *(datap++) = (U16)(sound_datap2[ 0] & 0x0f) | + ((U16)(sound_datap2[ 4] & 0x0f) << 4) | + ((U16)(sound_datap2[ 8] & 0x0f) << 8) | + ((U16)(sound_datap2[12] & 0x0f) << 12); + } + } + ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+0], data, + destp+0, 2 ); + + datap = data; + sound_datap2 = sound_datap + i; + if ((xdp->nbits == 8) && (xdp->freq == 37800)) { // level A + for (k=0; k < 14; k++, sound_datap2 += 8) { + *(datap++) = (U16)sound_datap2[0] | + (U16)(sound_datap2[4] << 8); + } + } else { // level B/C + for (k=0; k < 7; k++, sound_datap2 += 16) { + *(datap++) = (U16)(sound_datap2[ 0] >> 4) | + ((U16)(sound_datap2[ 4] >> 4) << 4) | + ((U16)(sound_datap2[ 8] >> 4) << 8) | + ((U16)(sound_datap2[12] >> 4) << 12); + } + } + ADPCM_DecodeBlock16( &xdp->right, sound_groupsp[headtable[i]+1], data, + destp+1, 2 ); + + destp += 28*2; + } + } + } + else { // mono + for (j=0; j < 18; j++) { + sound_groupsp = srcp + j * 128; // sound groups header + sound_datap = sound_groupsp + 16; // sound data just after the header + + for (i=0; i < nbits; i++) { + datap = data; + sound_datap2 = sound_datap + i; + if ((xdp->nbits == 8) && (xdp->freq == 37800)) { // level A + for (k=0; k < 14; k++, sound_datap2 += 8) { + *(datap++) = (U16)sound_datap2[0] | + (U16)(sound_datap2[4] << 8); + } + } else { // level B/C + for (k=0; k < 7; k++, sound_datap2 += 16) { + *(datap++) = (U16)(sound_datap2[ 0] & 0x0f) | + ((U16)(sound_datap2[ 4] & 0x0f) << 4) | + ((U16)(sound_datap2[ 8] & 0x0f) << 8) | + ((U16)(sound_datap2[12] & 0x0f) << 12); + } + } + ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+0], data, + destp, 1 ); + + destp += 28; + + datap = data; + sound_datap2 = sound_datap + i; + if ((xdp->nbits == 8) && (xdp->freq == 37800)) { // level A + for (k=0; k < 14; k++, sound_datap2 += 8) { + *(datap++) = (U16)sound_datap2[0] | + (U16)(sound_datap2[4] << 8); + } + } else { // level B/C + for (k=0; k < 7; k++, sound_datap2 += 16) { + *(datap++) = (U16)(sound_datap2[ 0] >> 4) | + ((U16)(sound_datap2[ 4] >> 4) << 4) | + ((U16)(sound_datap2[ 8] >> 4) << 8) | + ((U16)(sound_datap2[12] >> 4) << 12); + } + } + ADPCM_DecodeBlock16( &xdp->left, sound_groupsp[headtable[i]+1], data, + destp, 1 ); + + destp += 28; + } + } + } +} + +//============================================ +//=== XA SPECIFIC ROUTINES +//============================================ +typedef struct { +U8 filenum; +U8 channum; +U8 submode; +U8 coding; + +U8 filenum2; +U8 channum2; +U8 submode2; +U8 coding2; +} xa_subheader_t; + +#define SUB_SUB_EOF (1<<7) // end of file +#define SUB_SUB_RT (1<<6) // real-time sector +#define SUB_SUB_FORM (1<<5) // 0 form1 1 form2 +#define SUB_SUB_TRIGGER (1<<4) // used for interrupt +#define SUB_SUB_DATA (1<<3) // contains data +#define SUB_SUB_AUDIO (1<<2) // contains audio +#define SUB_SUB_VIDEO (1<<1) // contains video +#define SUB_SUB_EOR (1<<0) // end of record + +#define AUDIO_CODING_GET_STEREO(_X_) ( (_X_) & 3) +#define AUDIO_CODING_GET_FREQ(_X_) (((_X_) >> 2) & 3) +#define AUDIO_CODING_GET_BPS(_X_) (((_X_) >> 4) & 3) +#define AUDIO_CODING_GET_EMPHASIS(_X_) (((_X_) >> 6) & 1) + +#define SUB_UNKNOWN 0 +#define SUB_VIDEO 1 +#define SUB_AUDIO 2 + +//============================================ +static int parse_xa_audio_sector( xa_decode_t *xdp, + xa_subheader_t *subheadp, + unsigned char *sectorp, + int is_first_sector ) { + if ( is_first_sector ) { + switch ( AUDIO_CODING_GET_FREQ(subheadp->coding) ) { + case 0: xdp->freq = 37800; break; + case 1: xdp->freq = 18900; break; + default: xdp->freq = 0; break; + } + switch ( AUDIO_CODING_GET_BPS(subheadp->coding) ) { + case 0: xdp->nbits = 4; break; + case 1: xdp->nbits = 8; break; + default: xdp->nbits = 0; break; + } + switch ( AUDIO_CODING_GET_STEREO(subheadp->coding) ) { + case 0: xdp->stereo = 0; break; + case 1: xdp->stereo = 1; break; + default: xdp->stereo = 0; break; + } + + if ( xdp->freq == 0 ) + return -1; + + ADPCM_InitDecode( &xdp->left ); + ADPCM_InitDecode( &xdp->right ); + + xdp->nsamples = 18 * 28 * 8; + if (xdp->stereo == 1) xdp->nsamples /= 2; + } + xa_decode_data( xdp, sectorp ); + + return 0; +} + +//================================================================ +//=== THIS IS WHAT YOU HAVE TO CALL +//=== xdp - structure were all important data are returned +//=== sectorp - data in input +//=== pcmp - data in output +//=== is_first_sector - 1 if it's the 1st sector of the stream +//=== - 0 for any other successive sector +//=== return -1 if error +//================================================================ +long xa_decode_sector( xa_decode_t *xdp, + unsigned char *sectorp, int is_first_sector ) { + if (parse_xa_audio_sector(xdp, (xa_subheader_t *)sectorp, sectorp + sizeof(xa_subheader_t), is_first_sector)) + return -1; + + return 0; +} + +/* EXAMPLE: +"nsamples" is the number of 16 bit samples +every sample is 2 bytes in mono and 4 bytes in stereo + +xa_decode_t xa; + + sectorp = read_first_sector(); + xa_decode_sector( &xa, sectorp, 1 ); + play_wave( xa.pcm, xa.freq, xa.nsamples ); + + while ( --n_sectors ) + { + sectorp = read_next_sector(); + xa_decode_sector( &xa, sectorp, 0 ); + play_wave( xa.pcm, xa.freq, xa.nsamples ); + } +*/ diff --git a/PcsxSrc/Decode_XA.h b/PcsxSrc/Decode_XA.h new file mode 100644 index 0000000..d363fb4 --- /dev/null +++ b/PcsxSrc/Decode_XA.h @@ -0,0 +1,26 @@ +//============================================ +//=== Audio XA decoding +//=== Kazzuya +//============================================ + +#ifndef DECODEXA_H +#define DECODEXA_H + +typedef struct { + long y0, y1; +} ADPCM_Decode_t; + +typedef struct { + int freq; + int nbits; + int stereo; + int nsamples; + ADPCM_Decode_t left, right; + short pcm[16384]; +} xa_decode_t; + +long xa_decode_sector( xa_decode_t *xdp, + unsigned char *sectorp, + int is_first_sector ); + +#endif diff --git a/PcsxSrc/DisR3000A.c b/PcsxSrc/DisR3000A.c new file mode 100644 index 0000000..d23da72 --- /dev/null +++ b/PcsxSrc/DisR3000A.c @@ -0,0 +1,318 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "Debug.h" + +char ostr[256]; + +// Names of registers +static char *disRNameGPR[] = { + "r0", "at", "v0", "v1", "a0", "a1","a2", "a3", + "t0", "t1", "t2", "t3", "t4", "t5","t6", "t7", + "s0", "s1", "s2", "s3", "s4", "s5","s6", "s7", + "t8", "t9", "k0", "k1", "gp", "sp","fp", "ra"}; + +static char *disRNameCP0[] = { + "Index" , "Random" , "EntryLo0", "EntryLo1", "Context" , "PageMask" , "Wired" , "*Check me*", + "BadVAddr" , "Count" , "EntryHi" , "Compare" , "Status" , "Cause" , "ExceptPC" , "PRevID" , + "Config" , "LLAddr" , "WatchLo" , "WatchHi" , "XContext", "*RES*" , "*RES*" , "*RES*" , + "*RES*" , "*RES* " , "PErr" , "CacheErr", "TagLo" , "TagHi" , "ErrorEPC" , "*RES*" }; + + +// Type deffinition of our functions + +typedef char* (*TdisR3000AF)(u32 code, u32 pc); + +// These macros are used to assemble the disassembler functions +#define MakeDisFg(fn, b) char* fn(u32 code, u32 pc) { b; return ostr; } +#define MakeDisF(fn, b) \ + static char* fn(u32 code, u32 pc) { \ + sprintf (ostr, "%8.8lx %8.8lx:", pc, code); \ + b; /*ostr[(strlen(ostr) - 1)] = 0;*/ return ostr; \ + } + + +#include "R3000A.h" + +#undef _Funct_ +#undef _Rd_ +#undef _Rt_ +#undef _Rs_ +#undef _Sa_ +#undef _Im_ +#undef _Target_ + +#define _Funct_ ((code ) & 0x3F) // The funct part of the instruction register +#define _Rd_ ((code >> 11) & 0x1F) // The rd part of the instruction register +#define _Rt_ ((code >> 16) & 0x1F) // The rt part of the instruction register +#define _Rs_ ((code >> 21) & 0x1F) // The rs part of the instruction register +#define _Sa_ ((code >> 6) & 0x1F) // The sa part of the instruction register +#define _Im_ ( code & 0xFFFF) // The immediate part of the instruction register + +#define _Target_ ((pc & 0xf0000000) + ((code & 0x03ffffff) * 4)) +#define _Branch_ (pc + 4 + ((short)_Im_ * 4)) +#define _OfB_ _Im_, _nRs_ + +#define dName(i) sprintf(ostr, "%s %-7s,", ostr, i) +#define dGPR(i) sprintf(ostr, "%s %8.8lx (%s),", ostr, psxRegs.GPR.r[i], disRNameGPR[i]) +#define dCP0(i) sprintf(ostr, "%s %8.8lx (%s),", ostr, psxRegs.CP0.r[i], disRNameCP0[i]) +#define dHI() sprintf(ostr, "%s %8.8lx (%s),", ostr, psxRegs.GPR.n.hi, "hi") +#define dLO() sprintf(ostr, "%s %8.8lx (%s),", ostr, psxRegs.GPR.n.lo, "lo") +#define dImm() sprintf(ostr, "%s %4.4lx (%ld),", ostr, _Im_, _Im_) +#define dTarget() sprintf(ostr, "%s %8.8lx,", ostr, _Target_) +#define dSa() sprintf(ostr, "%s %2.2lx (%ld),", ostr, _Sa_, _Sa_) +#define dOfB() sprintf(ostr, "%s %4.4lx (%8.8lx (%s)),", ostr, _Im_, psxRegs.GPR.r[_Rs_], disRNameGPR[_Rs_]) +#define dOffset() sprintf(ostr, "%s %8.8lx,", ostr, _Branch_) +#define dCode() sprintf(ostr, "%s %8.8lx,", ostr, (code >> 6) & 0xffffff) + +/********************************************************* +* Arithmetic with immediate operand * +* Format: OP rt, rs, immediate * +*********************************************************/ +MakeDisF(disADDI, dName("ADDI"); dGPR(_Rt_); dGPR(_Rs_); dImm();) +MakeDisF(disADDIU, dName("ADDIU"); dGPR(_Rt_); dGPR(_Rs_); dImm();) +MakeDisF(disANDI, dName("ANDI"); dGPR(_Rt_); dGPR(_Rs_); dImm();) +MakeDisF(disORI, dName("ORI"); dGPR(_Rt_); dGPR(_Rs_); dImm();) +MakeDisF(disSLTI, dName("SLTI"); dGPR(_Rt_); dGPR(_Rs_); dImm();) +MakeDisF(disSLTIU, dName("SLTIU"); dGPR(_Rt_); dGPR(_Rs_); dImm();) +MakeDisF(disXORI, dName("XORI"); dGPR(_Rt_); dGPR(_Rs_); dImm();) + +/********************************************************* +* Register arithmetic * +* Format: OP rd, rs, rt * +*********************************************************/ +MakeDisF(disADD, dName("ADD"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);) +MakeDisF(disADDU, dName("ADDU"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);) +MakeDisF(disAND, dName("AND"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);) +MakeDisF(disNOR, dName("NOR"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);) +MakeDisF(disOR, dName("OR"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);) +MakeDisF(disSLT, dName("SLT"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);) +MakeDisF(disSLTU, dName("SLTU"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);) +MakeDisF(disSUB, dName("SUB"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);) +MakeDisF(disSUBU, dName("SUBU"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);) +MakeDisF(disXOR, dName("XOR"); dGPR(_Rd_); dGPR(_Rs_); dGPR(_Rt_);) + +/********************************************************* +* Register arithmetic & Register trap logic * +* Format: OP rs, rt * +*********************************************************/ +MakeDisF(disDIV, dName("DIV"); dGPR(_Rs_); dGPR(_Rt_);) +MakeDisF(disDIVU, dName("DIVU"); dGPR(_Rs_); dGPR(_Rt_);) +MakeDisF(disMULT, dName("MULT"); dGPR(_Rs_); dGPR(_Rt_);) +MakeDisF(disMULTU, dName("MULTU"); dGPR(_Rs_); dGPR(_Rt_);) + +/********************************************************* +* Register branch logic * +* Format: OP rs, offset * +*********************************************************/ +MakeDisF(disBGEZ, dName("BGEZ"); dGPR(_Rs_); dOffset();) +MakeDisF(disBGEZAL, dName("BGEZAL"); dGPR(_Rs_); dOffset();) +MakeDisF(disBGTZ, dName("BGTZ"); dGPR(_Rs_); dOffset();) +MakeDisF(disBLEZ, dName("BLEZ"); dGPR(_Rs_); dOffset();) +MakeDisF(disBLTZ, dName("BLTZ"); dGPR(_Rs_); dOffset();) +MakeDisF(disBLTZAL, dName("BLTZAL"); dGPR(_Rs_); dOffset();) + +/********************************************************* +* Shift arithmetic with constant shift * +* Format: OP rd, rt, sa * +*********************************************************/ +MakeDisF(disSLL, if (code) { dName("SLL"); dGPR(_Rd_); dGPR(_Rt_); dSa(); } else { dName("NOP"); }) +MakeDisF(disSRA, dName("SRA"); dGPR(_Rd_); dGPR(_Rt_); dSa();) +MakeDisF(disSRL, dName("SRL"); dGPR(_Rd_); dGPR(_Rt_); dSa();) + +/********************************************************* +* Shift arithmetic with variant register shift * +* Format: OP rd, rt, rs * +*********************************************************/ +MakeDisF(disSLLV, dName("SLLV"); dGPR(_Rd_); dGPR(_Rt_); dGPR(_Rs_);) +MakeDisF(disSRAV, dName("SRAV"); dGPR(_Rd_); dGPR(_Rt_); dGPR(_Rs_);) +MakeDisF(disSRLV, dName("SRLV"); dGPR(_Rd_); dGPR(_Rt_); dGPR(_Rs_);) + +/********************************************************* +* Load higher 16 bits of the first word in GPR with imm * +* Format: OP rt, immediate * +*********************************************************/ +MakeDisF(disLUI, dName("LUI"); dGPR(_Rt_); dImm();) + +/********************************************************* +* Move from HI/LO to GPR * +* Format: OP rd * +*********************************************************/ +MakeDisF(disMFHI, dName("MFHI"); dGPR(_Rd_); dHI();) +MakeDisF(disMFLO, dName("MFLO"); dGPR(_Rd_); dLO();) + +/********************************************************* +* Move from GPR to HI/LO * +* Format: OP rd * +*********************************************************/ +MakeDisF(disMTHI, dName("MTHI"); dHI(); dGPR(_Rs_);) +MakeDisF(disMTLO, dName("MTLO"); dLO(); dGPR(_Rs_);) + +/********************************************************* +* Special purpose instructions * +* Format: OP * +*********************************************************/ +MakeDisF(disBREAK, dName("BREAK")) +MakeDisF(disRFE, dName("RFE")) +MakeDisF(disSYSCALL, dName("SYSCALL")) +MakeDisF(disHLE, dName("HLE")) + + +MakeDisF(disRTPS, dName("RTPS")) +MakeDisF(disOP , dName("OP")) +MakeDisF(disNCLIP, dName("NCLIP")) +MakeDisF(disDPCS, dName("DPCS")) +MakeDisF(disINTPL, dName("INTPL")) +MakeDisF(disMVMVA, dName("MVMVA")) +MakeDisF(disNCDS , dName("NCDS")) +MakeDisF(disCDP , dName("CDP")) +MakeDisF(disNCDT , dName("NCDT")) +MakeDisF(disNCCS , dName("NCCS")) +MakeDisF(disCC , dName("CC")) +MakeDisF(disNCS , dName("NCS")) +MakeDisF(disNCT , dName("NCT")) +MakeDisF(disSQR , dName("SQR")) +MakeDisF(disDCPL , dName("DCPL")) +MakeDisF(disDPCT , dName("DPCT")) +MakeDisF(disAVSZ3, dName("AVSZ3")) +MakeDisF(disAVSZ4, dName("AVSZ4")) +MakeDisF(disRTPT , dName("RTPT")) +MakeDisF(disGPF , dName("GPF")) +MakeDisF(disGPL , dName("GPL")) +MakeDisF(disNCCT , dName("NCCT")) + +MakeDisF(disMFC2, dName("MFC2")) +MakeDisF(disCFC2, dName("CFC2")) +MakeDisF(disMTC2, dName("MTC2")) +MakeDisF(disCTC2, dName("CTC2")) + +/********************************************************* +* Register branch logic * +* Format: OP rs, rt, offset * +*********************************************************/ +MakeDisF(disBEQ, dName("BEQ"); dGPR(_Rs_); dGPR(_Rt_); dOffset();) +MakeDisF(disBNE, dName("BNE"); dGPR(_Rs_); dGPR(_Rt_); dOffset();) + +/********************************************************* +* Jump to target * +* Format: OP target * +*********************************************************/ +MakeDisF(disJ, dName("J"); dTarget();) +MakeDisF(disJAL, dName("JAL"); dTarget(); dGPR(31);) + +/********************************************************* +* Register jump * +* Format: OP rs, rd * +*********************************************************/ +MakeDisF(disJR, dName("JR"); dGPR(_Rs_);) +MakeDisF(disJALR, dName("JALR"); dGPR(_Rs_); dGPR(_Rd_)) + +/********************************************************* +* Load and store for GPR * +* Format: OP rt, offset(base) * +*********************************************************/ +MakeDisF(disLB, dName("LB"); dGPR(_Rt_); dOfB();) +MakeDisF(disLBU, dName("LBU"); dGPR(_Rt_); dOfB();) +MakeDisF(disLH, dName("LH"); dGPR(_Rt_); dOfB();) +MakeDisF(disLHU, dName("LHU"); dGPR(_Rt_); dOfB();) +MakeDisF(disLW, dName("LW"); dGPR(_Rt_); dOfB();) +MakeDisF(disLWL, dName("LWL"); dGPR(_Rt_); dOfB();) +MakeDisF(disLWR, dName("LWR"); dGPR(_Rt_); dOfB();) +MakeDisF(disLWC2, dName("LWC2"); dGPR(_Rt_); dOfB();) +MakeDisF(disSB, dName("SB"); dGPR(_Rt_); dOfB();) +MakeDisF(disSH, dName("SH"); dGPR(_Rt_); dOfB();) +MakeDisF(disSW, dName("SW"); dGPR(_Rt_); dOfB();) +MakeDisF(disSWL, dName("SWL"); dGPR(_Rt_); dOfB();) +MakeDisF(disSWR, dName("SWR"); dGPR(_Rt_); dOfB();) +MakeDisF(disSWC2, dName("SWC2"); dGPR(_Rt_); dOfB();) + +/********************************************************* +* Moves between GPR and COPx * +* Format: OP rt, fs * +*********************************************************/ +MakeDisF(disMFC0, dName("MFC0"); dGPR(_Rt_); dCP0(_Rd_);) +MakeDisF(disMTC0, dName("MTC0"); dCP0(_Rd_); dGPR(_Rt_);) +MakeDisF(disCFC0, dName("CFC0"); dGPR(_Rt_); dCP0(_Rd_);) +MakeDisF(disCTC0, dName("CTC0"); dCP0(_Rd_); dGPR(_Rt_);) + +/********************************************************* +* Unknow instruction (would generate an exception) * +* Format: ? * +*********************************************************/ +MakeDisF(disNULL, dName("*** Bad OP ***");) + + +TdisR3000AF disR3000A_SPECIAL[] = { // Subset of disSPECIAL + disSLL , disNULL , disSRL , disSRA , disSLLV , disNULL , disSRLV , disSRAV , + disJR , disJALR , disNULL, disNULL, disSYSCALL, disBREAK , disNULL , disNULL , + disMFHI, disMTHI , disMFLO, disMTLO, disNULL , disNULL , disNULL , disNULL , + disMULT, disMULTU, disDIV , disDIVU, disNULL , disNULL , disNULL , disNULL , + disADD , disADDU , disSUB , disSUBU, disAND , disOR , disXOR , disNOR , + disNULL, disNULL , disSLT , disSLTU, disNULL , disNULL , disNULL , disNULL , + disNULL, disNULL , disNULL, disNULL, disNULL , disNULL , disNULL , disNULL , + disNULL, disNULL , disNULL, disNULL, disNULL , disNULL , disNULL , disNULL}; + +MakeDisF(disSPECIAL, disR3000A_SPECIAL[_Funct_](code, pc)) + +TdisR3000AF disR3000A_BCOND[] = { // Subset of disBCOND + disBLTZ , disBGEZ , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, + disNULL , disNULL , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, + disBLTZAL, disBGEZAL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, + disNULL , disNULL , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL}; + +MakeDisF(disBCOND, disR3000A_BCOND[_Rt_](code, pc)) + +TdisR3000AF disR3000A_COP0[] = { // Subset of disCOP0 + disMFC0, disNULL, disCFC0, disNULL, disMTC0, disNULL, disCTC0, disNULL, + disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, + disRFE , disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, + disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL}; + +MakeDisF(disCOP0, disR3000A_COP0[_Rs_](code, pc)) + +TdisR3000AF disR3000A_BASIC[] = { // Subset of disBASIC (based on rs) + disMFC2, disNULL, disCFC2, disNULL, disMTC2, disNULL, disCTC2, disNULL, + disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, + disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, + disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL, disNULL}; + +MakeDisF(disBASIC, disR3000A_BASIC[_Rs_](code, pc)) + +TdisR3000AF disR3000A_COP2[] = { // Subset of disR3000F_COP2 (based on funct) + disBASIC, disRTPS , disNULL , disNULL , disNULL, disNULL , disNCLIP, disNULL, + disNULL , disNULL , disNULL , disNULL , disOP , disNULL , disNULL , disNULL, + disDPCS , disINTPL, disMVMVA, disNCDS , disCDP , disNULL , disNCDT , disNULL, + disNULL , disNULL , disNULL , disNCCS , disCC , disNULL , disNCS , disNULL, + disNCT , disNULL , disNULL , disNULL , disNULL, disNULL , disNULL , disNULL, + disSQR , disDCPL , disDPCT , disNULL , disNULL, disAVSZ3, disAVSZ4, disNULL, + disRTPT , disNULL , disNULL , disNULL , disNULL, disNULL , disNULL , disNULL, + disNULL , disNULL , disNULL , disNULL , disNULL, disGPF , disGPL , disNCCT }; + +MakeDisF(disCOP2, disR3000A_COP2[_Funct_](code, pc)) + +TdisR3000AF disR3000A[] = { + disSPECIAL , disBCOND , disJ , disJAL , disBEQ , disBNE , disBLEZ , disBGTZ , + disADDI , disADDIU , disSLTI , disSLTIU, disANDI, disORI , disXORI , disLUI , + disCOP0 , disNULL , disCOP2 , disNULL , disNULL, disNULL, disNULL , disNULL , + disNULL , disNULL , disNULL , disNULL , disNULL, disNULL, disNULL , disNULL , + disLB , disLH , disLWL , disLW , disLBU , disLHU , disLWR , disNULL , + disSB , disSH , disSWL , disSW , disNULL, disNULL, disSWR , disNULL , + disNULL , disNULL , disLWC2 , disNULL , disNULL, disNULL, disNULL , disNULL , + disNULL , disNULL , disSWC2 , disHLE , disNULL, disNULL, disNULL , disNULL }; + +MakeDisFg(disR3000AF, disR3000A[code >> 26](code, pc)) diff --git a/PcsxSrc/Docs/ChangeLog.txt b/PcsxSrc/Docs/ChangeLog.txt new file mode 100644 index 0000000..4bd94cd --- /dev/null +++ b/PcsxSrc/Docs/ChangeLog.txt @@ -0,0 +1,255 @@ +ChageLog: + v1.3: + * Fixed icon colors for 15/16bits, thanks to jang2k (linuzappz) + + * Fix silly bug on PsxCounters.c for SPUasync (linuzappz) + + * Refixed the mdecs, more correct. PsxHw.c, Mdec.c, and small fixes on + WndMain.c/Plugin.c, thanks to jang2k (linuzappz) + + * Fix for some mdecs on MdecWrite1, Mdec.c, thanks to psychojak (linuzappz) + + * CVGS Mcds now are detected by file size, also fixes to SaveMcd, + and added support for .gme mcds, Sio.c, thanks to jang2k (linuzappz) + + * Fixed Pcsx title for some win32, small fix in Gte.c, and added + icons for win32 mcd dlg (still unanimated), WndMain.c, + thanks to jang2k (linuzappz) + + * Added rename syscall, PsxBios.c (linuzappz) + + * Fixed bug in MTC2 in linux define, Gte.c (linuzappz) + + * Minor fixes to GtkGui.c (linuzappz) + + * More to PsxBios.c (linuzappz) + + * Fixed bug when S_addr == 0 in Misc.c (linuzappz) + + * Now won't close the plugins if the user press escape more than once, + WinMain.c, plugin.c (linuzappz) + + * Added SPUasync support, thanks to Andy and Iori (linuzappz) + + * Removed the BREAK code, since the bios rom doens't handles it, + thanks to psychojak (linuzappz) + + * Some bugfixes to Gte.c, thanks to jang2k (linuzappz) + + * "hokuto no ken" / "Crash Bandicot 2" ... fix, thanks to Taka (linuzappz) + + * Renamed/rewrote some stuff for pcsx2 compat ;) (linuzappz) + + * Small speedups for Mdec.c (linuzappz) + + * Rewrote DisR3000A.c (linuzappz) + + * Improved and rewrote partially HLE stuff (linuzappz) + + * Rewrote the way we call syscalls (linuzappz) + + * Added in Gte.c SUM_FLAG to opcodes that didn't have it, thanks to Taka (linuzappz) + + * CdlPause Acknowledge irq timing changed to 0x40000, thanks to Taka (linuzappz) + + * Fixed bug in recBLTZAL and recBGEZAL, thanks to Taka (linuzappz) + + * Fixed bug in Sio.c, thanks to gunshinn (linuzappz) + + * Fixed bug in Hw.c, thanks to bilgerat (linuzappz) + + * Fixes to Gte.c, thanks to roor (shadow) + + v1.2: + * Added Reg2 to cdrStruct, for Reg2 == 0x18 (non-interrupted cmds) (linuzappz) + + * Fixed one bug in Counters, count < 0 (linuzappz) + + * Now the cursor will be hidden in Win32 after OpenPlugins. (linuzappz) + + * Refixed Getlocl (linuzappz) + + * Fixed recJALR, 31 for _Rd_ (linuzappz) + + * Fixes to Gte.c (linuzappz) + + * Optimized iR3000A.c for speed (linuzappz) + + * Rewritten branch opcodes on iR3000A.c and removed cache stuff (linuzappz) + + * PRevID changed to 0x2, thanks to shadow (linuzappz) + + * Added PADstartPoll and PADpoll support, thanks to gunshinn (linuzappz) + + * Speed improvements to iR3000A.c (linuzappz) + + * Rewrote the cycles tests stuff, removed the workaround that reseted to 0x80000000 + (linuzappz) + + * CDRgetBufferSub and fixes to CDREAD stuff, CdRom.c, plugins.c/h (linuzappz + + * Correct Mouse, AnalogJoystick and AnalogPad emulation, contributed by + gunshinn (linuzappz) + + * MOVZX and MOVSX to ix86.h and iR3000A.h (linuzappz) + + * Improved Memcard Dialog on Linux (linuzappz) + + * Counters again use BIAS (linuzappz) + + * Autodetect psx type should be fine now, Misc.c (linuzappz) + + * Removed nasm stuff (linuzappz) + + * Fixed VK_F10 in Plugin.c, WndMain.c (linuzappz) + + * LWC2/SWC2 now in Gte.c/h, Interpreter.c, iR3000A.c (linuzappz) + + * Fixed gte_Cxx in MVMVA, Gte.c (linuzappz) + + * Fixed a bug within PIC stuff, Plugin.c (win32 and linux) (linuzappz) + + * Rewrote bios_printf, Bios.c (linuzappz) + + * gtk_widget_hide changed for gtk_widget_destroy, thanks to lu_zero (linuzappz) + + * Fix for cpuIrq.cycle, now it won't freeze when reaching 0xffffffff, since + we now reset when reaches 0x80000000, Counters.c (linuzappz) + + * Counters 1 and 2 (in mode 0x100) should be a little more accurate now (linuzappz) + + * Made workaround for Gran Turismo, WndMain.c, ConfigurePlugins.c, LnxMain.c, + Config.c, GtkGui.c (linuzappz) + + * cp2NCLIP added in iGte.asm (linuzappz) + + * Fixed some bugs on Memory.c (memset to memLUT) and ConfigurePlugins.c + (strlen("HLE") + 1), thanks to Taka (linuzappz) + + * Refixed XA quality, now should be perfect always, Decode_XA.c, and a bug on + the spu dma is now fixed, Dma.c, thanks to Iori for this (linuzappz) + + * Fixed a bug in cp2MTC2 in iGte.asm, movsx now used (linuzappz) + + * cdReadTime is now divided by 75, thanks to calb, and the CDREAD_INT is set + on a irq reset, CdRom.c/h (linuzappz) + + v1.1: + * Fixed a bug in R3000A.c, hwReset() after the cpuIrq reset (linuzappz) + + * Refixed RootCounters, still need to clean, Counters.c (linuzappz) + + * Fixed XA quality, still in some games quality is not perfect (maybe cdrom bug) + Decode_XA.c (linuzappz) + + * Reset var is now unused in CdRom.c, instead cdr.Ctrl is now used (linuzappz) + + * Small speedup for Hw.c, Sio.c/h (linuzappz) + + * Added cdrRead2 handling and fixed cddma, thanks to shunt, CdRom.c (linuzappz) + + * Cleaned a bit Memory.c, R3000A.c and Hw.c (linuzappz) + + * Support for VGS Memory Card Format (*.mem), Sio.c (linuzappz) + + * Rewrote cdirq handling, CdRom.c/h, R3000A.c (linuzappz) + + * Speed up on iR3000A.c code for cop2 (linuzappz) + + * Improved cdrom decoder and cdirq handling, CdRom.c/h (linuzappz) + + * Cleaned error checking on plugins.c/h (linuzappz) + + * Improved SysPrintf as SysMessage, System.h, LnxMain.c, WndMain.c (linuzappz) + + * Added sioInterrupt call, for cleaner code, Sio.c/h, R3000A.c (linuzappz) + + * Cleaned a little initial regs, R3000A.c (linuzappz) + + * Fixes to Dma stuff (HW_DMA_PCR is now used), hwDma3 set now only to + (chcr) 0x11000000 and 0x11400100, Hw.c, CdRom.c (linuzappz) + + * Added status seek flag to SeekL and SeekP, CdRom.c (linuzappz) + + * Icon animated support for McdDlg, GtkGui.c, Sio.c/h (linuzappz) + + * Gettd now returns frame too, CdRom.c (linuzappz) + + * Fixed bug in CdlPlay, CdRom.c (linuzappz) + + * SPUupdate interface support Counters.c/h, plugins.c/h (linuzappz) + + * Added CDRCMD_DEBUG flag in Debug.h, for CdRom.c cmd debug only (linuzappz) + + * AUTOPAUSE stuff improved on Cdrom.c (linuzappz) + + * Icon stuff and more on McdDlg, WndMain.c/GtkGui.c, Sio.c/h (linuzappz) + + * Fixed PsxAuto buf in Misc.c (linuzappz) + + * Memory Card Manager improved to handle blocks, still need + lotta work, WndMain.c/GtkGui.c, Sio.c/h (linuzappz) + + * Fixed in LoadCdrom the System.cnf a bit more (linuzappz) + + * Added Unused data to freeze functions and fixed LoadState to fail only for + STvX (linuzappz) + + * More fixes to Gte.c, added another gte debug in Debug.h/WndMain.c + + * Fixed a bug in RemoveCmdQueue, CdRom.c (linuzappz) + + * Fixed Registry compatibility between versions in Win32, ConfigurePlugins.c + (linuzappz) + + * Gte.c: total rewrite. Rage racer,Ridge racer,Bloady roar,Ridge racer 4 + now WORKS!!! (some small problems still althought ;p) + Bios.c: some more comment opcodes to biosInit.(i think that all exists now) + (shadow) + + * Bios.c: fixed ResetEntryInt & HookEntryInt (hex was opposite) + add some names to BiosInit (commented) + A0:3b, A0:3c, A0:4a, A0:4c, added (shadow) + + * Added LoadCdrom(), for HLE cdrom support, Misc.c, LnxMain.c, GtkGui.c, + WndMain.c (linuzappz) + + * More to Bios.c: longjmp, mem2vram (thought that might fix some demos + but not. Maybe need a recheck..), InitPAD + biosInterrupt (some changes.. + Not seems to work okay.. but dunno..), bios_GPU_dw (probably buggy need a + recheck), bios_atoi, bios_atol, bios_index, bios_rindex, bios_strchr, + bios_strrchr, bios_strpbrk, bios_strspn, bios_strcspn, bios_strtok, + bios_strstr. + And add some names of bios opcodes to the table.(commentted) (shadow) + + * Bios.c, added: SendGPU, StartPAD, GPU_SendPackets, GPU_GetGPUStatus, + toupper, tolower, bcopy, bzero, bcmp (shadow) + + * Now you can change Bios and Plugins Path, in both Win32/Linux, + ConfigurePlugins.c, Config.c, plugins.c, Wnd/LnxMain.c, Memory.c, (linuzappz) + + * StatesC in Linux same as Win32, Plugin.c (linuzappz) + + * Fixed rcntRcount, removed one BIAS, Counters.c (linuzappz) + + * Added CheckCdrom() after you change a cdrom, Cdrom.c (linuzappz) + + * Fixed iMdec.asm, still need to fix colours, they aren't 100% right (linuzappz) + + * F8 now set to make a snapshot (linuzappz) + + * Added bios syscalls names in Bios.c/R3000A.c (linuzappz) + + * GetTD and GetTN cmds are now non-blocking and added error code, + CdRom.c (linuzappz) + + * Simplified queuing code and now reads are done like cmds (instead of + using the synk stuff), CdRom.c/R3000A.c (linuzappz) + + * Made a workaround for iso cdrom plugins, when they changed the dir, + Plugin.c/WndMain.c (linuzappz) + + * Fixed bug in CdRom.c (gcc3 support) (linuzappz) + + v1.0: + * First source code public release. \ No newline at end of file diff --git a/PcsxSrc/Docs/CodingStyle.txt b/PcsxSrc/Docs/CodingStyle.txt new file mode 100644 index 0000000..4b44c97 --- /dev/null +++ b/PcsxSrc/Docs/CodingStyle.txt @@ -0,0 +1,29 @@ +## PCSX CODING STYLE + +typedef struct { // { within struct + int i; +} name; + +void func(int i) { // { within func declaration + if () { // same + switch () { // same + default: + printf(); // 1 tab per level (considering the default and the code in it + // as diferent ones + } + } + + for (;;) { // same for while + } +} + +Also try to align the code: + Something = x; + AnotherThing = x; +but not always: + i = x; + Something = x; + +tab = 4 +indent = 4 + diff --git a/PcsxSrc/Docs/License.txt b/PcsxSrc/Docs/License.txt new file mode 100644 index 0000000..7d1f860 --- /dev/null +++ b/PcsxSrc/Docs/License.txt @@ -0,0 +1,342 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + + diff --git a/PcsxSrc/Docs/Readme.txt b/PcsxSrc/Docs/Readme.txt new file mode 100644 index 0000000..a8deded --- /dev/null +++ b/PcsxSrc/Docs/Readme.txt @@ -0,0 +1,189 @@ + Pcsx - Pc Psx Emulator + ---------------------- + +Contents +-------- + +1) General +2) How it works +3) Supported games +4) TroubleShoot +5) Credits + +-------------------------------------------------------------------------------- + +1) General + ------- + +Pcsx is a PSX emulator. What that really means? It means that it emulates the +way that a PSX works and tries to translate PSX machine language to PC language. +That is very hard to be done and we can't speak for 100% success in any time. +The hardware would always be better than the software so if you wanna play games +then better get a real PSX. Pcsx is capable to run many games, but may others +don't. We are working on it ;). The members of the team are very advanced coders +and they will continue the work on the Pcsx as far as they have enough time to +work on it. Real life comes first and sometimes it is much more demanding. + +The team of Pcsx + +-------------------------------------------------------------------------------- + +2) How it works + ------------ + +Steps: +------ + 1) Put a bios on bios directory (recommended: scph1001.bin) (optional) + 2) Put plugins in plugin directory + 3) Open the emu + 4) Configure plugins from configuration menu and Memcards from Mcd Manager + 5) Restart + 6) Put a cd in your cdrom drive + 7) Press Run CD and the game might work ;P + +Quick Keys: +---------- + F1: Save State + F2: Increase State Num + F3: Load State + F4: Show State-Pic + F5: Sio Irq Dis/Enable + F6: Black&White Mdecs Dis/Enable + F7: Dis/Enable Xa + F8: Makes a Snapshot + The 2 next keys are only implemented if the cdrom plugin doesn't support + the CDRgetStatus interface. + F9: Press to simulate an open case (to change cdroms in game) + F10: And this to close it + +Cpu Options: +----------- + * Disable Xa Decoding: + Disables xa sound, if you don't want sound this might + speed up a little movies (mostly) and the game itself. + + * Sio Irq Always Enabled: + Enable this only when pads or memcards doesn't works, + but usually brokes compatibility with them. + + * Spu Irq Always Enabled: + May help your game to work, but usually doesn't helps. + + * Black & White Movies: + Speed up for slow machines on movies. + + * Disable CD-DA: + Will disable CD audio. + + * Enable Console Output: + Displays the psx text output. + + * Enable Interpreter Cpu: + Enables interpretive emulation (recomiler by default), + it may be more compatible, but it's slower. + + * Psx System Type: + Autodetect: Try to autodetect the system. + NSTC/PAL: Specify it for yourself. + +Internal HLE Bios: +----------------- + If you select this instead of a regular bios (ie. "scph1001.bin") + Pcsx will emulate the bios (this might not work in all cases but it is + quite advanced), you can try it and see which one works better, notice + that the HLE bios might be faster than a regular one and may make some + games work better. + +-------------------------------------------------------------------------------- + +3) Supported Games + --------------- + +Here is a small list with games that pcsx support. Notice that it might have +some glitches on sound or gfx but it is considered playable. :) + + Crash Bandicoot 1 + Time crisis + Mickey Wild adventure + Coolboarders 3 + Street fighter EX+a + Street fighter EX2 plus + Breath of fire 3 + Breath of fire 4 + Quake II + Alone in the Dark 4 + Tekken 3 + +and probably lots more. +Check www.psxfanatics.com or www.ngemu.com for compatibility lists. + +------------------------------------------------------------------------------------------------ + +4) Troubleshoot + ------------ + + -QUE: My favourite game doesn't work + -AN: Wait for the next release, or get another emu ;) + -QUE: Can I have a bios image? + -AN : No + -QUE: CD audio is crappy... + -AN : If it doesn't work then disable it :) + +------------------------------------------------------------------------------------------------ + +5) Credits + ------- + +PCSX is the work of the following people: + +main coder: + Linuzappz , e-mail: linuzappz@pcsx.net +co-coders: + Shadow , e-mail: shadow@pcsx.net +ex-coders: + Pete Bernett, e-mail: psswitch@online.de + NoComp , e-mail: NoComp@mailcity.com + Nik3d , e-mail: +webmaster: + Akumax , e-mail: akumax@pcsx.net + +Team would like to thanks: +-------------------------- +Ancient :Shadow's small bother for beta testing pcsx and bothering me to correct it :P +Roor :for his help on cd-rom decoding routine :) +Duddie, +Tratax, +Kazzuya :for the great work on psemu,and for the XA decoder :) +Calb :for nice chats and coding hits ;) We love you calb ;) +Twin :for the bot to #pcsx on efnet, for coding hints and and :) +Lewpy :Man this plugin is quite fast! +Psychojak :For beta testing Pcsx and donating a great amount of games to Shadow ;) +JNS :For adding PEC support to Pcsx +Antiloop :Great coder :) +Segu :He knows what for :) +Null :He also knows :) +Bobbi +cdburnout :For putting Pcsx news to their site and for hosting.. +D[j] :For hosting us ;) +Now3d :For nice chats,info and blabla :) +Ricardo Diaz:Linux version may never have been released without his help +Nuno felicio:Beta testing, suggestions and a portugues readme +Shunt :Coding hints and nice chats :) +Taka :Many fixes to Pcsx +jang2k :Lots of fixes to Pcsx :) + +and last but not least: +----------------------- +James : for all the friendly support +Dimitris: for being good friend to me.. +Joan: The woman that make me nuts the last couple months... + +------------------------------------------------------------------------------------------------ + +Official website: http:/www.pcsx.net + +If I forgot someone beat me :P +"What you feel is what you are,and what you are is beatiful." +Log off +Shadow/ Linuzappz + diff --git a/PcsxSrc/Docs/ToDo.txt b/PcsxSrc/Docs/ToDo.txt new file mode 100644 index 0000000..9555b72 --- /dev/null +++ b/PcsxSrc/Docs/ToDo.txt @@ -0,0 +1,8 @@ +To do for Pcsx: + * Continue Bios emulation. (linuzappz) + * Fix CdRom code. (linuzappz) + * Fix Gte and speed it up, convert it to fixed point. + * Check Sio in games that don't work. + * Port to other platforms and cpus. + * NetPlay support. + * Finish the Memory Card Manager (only last for win32). diff --git a/PcsxSrc/Gte.c b/PcsxSrc/Gte.c new file mode 100644 index 0000000..4278161 --- /dev/null +++ b/PcsxSrc/Gte.c @@ -0,0 +1,2846 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include "Gte.h" +#include "R3000A.h" + +#ifdef GTE_DUMP +#define G_OP(name,delay) fprintf(gteLog, "* : %08X : %02d : %s\n", psxRegs.code, delay, name); +#define G_SD(reg) fprintf(gteLog, "+D%02d : %08X\n", reg, psxRegs.CP2D.r[reg]); +#define G_SC(reg) fprintf(gteLog, "+C%02d : %08X\n", reg, psxRegs.CP2C.r[reg]); +#define G_GD(reg) fprintf(gteLog, "-D%02d : %08X\n", reg, psxRegs.CP2D.r[reg]); +#define G_GC(reg) fprintf(gteLog, "-C%02d : %08X\n", reg, psxRegs.CP2C.r[reg]); +#else +#define G_OP(name,delay) +#define G_SD(reg) +#define G_SC(reg) +#define G_GD(reg) +#define G_GC(reg) +#endif + +#define SUM_FLAG if(gteFLAG & 0x7F87E000) gteFLAG |= 0x80000000; + +#ifdef __WIN32__ +#pragma warning(disable:4244) +#endif + +#define gteVX0 ((s16*)psxRegs.CP2D.r)[0] +#define gteVY0 ((s16*)psxRegs.CP2D.r)[1] +#define gteVZ0 ((s16*)psxRegs.CP2D.r)[2] +#define gteVX1 ((s16*)psxRegs.CP2D.r)[4] +#define gteVY1 ((s16*)psxRegs.CP2D.r)[5] +#define gteVZ1 ((s16*)psxRegs.CP2D.r)[6] +#define gteVX2 ((s16*)psxRegs.CP2D.r)[8] +#define gteVY2 ((s16*)psxRegs.CP2D.r)[9] +#define gteVZ2 ((s16*)psxRegs.CP2D.r)[10] +#define gteRGB psxRegs.CP2D.r[6] +#define gteOTZ ((s16*)psxRegs.CP2D.r)[7*2] +#define gteIR0 ((s32*)psxRegs.CP2D.r)[8] +#define gteIR1 ((s32*)psxRegs.CP2D.r)[9] +#define gteIR2 ((s32*)psxRegs.CP2D.r)[10] +#define gteIR3 ((s32*)psxRegs.CP2D.r)[11] +#define gteSX0 ((s16*)psxRegs.CP2D.r)[12*2] +#define gteSY0 ((s16*)psxRegs.CP2D.r)[12*2+1] +#define gteSX1 ((s16*)psxRegs.CP2D.r)[13*2] +#define gteSY1 ((s16*)psxRegs.CP2D.r)[13*2+1] +#define gteSX2 ((s16*)psxRegs.CP2D.r)[14*2] +#define gteSY2 ((s16*)psxRegs.CP2D.r)[14*2+1] +#define gteSXP ((s16*)psxRegs.CP2D.r)[15*2] +#define gteSYP ((s16*)psxRegs.CP2D.r)[15*2+1] +#define gteSZx ((u16*)psxRegs.CP2D.r)[16*2] +#define gteSZ0 ((u16*)psxRegs.CP2D.r)[17*2] +#define gteSZ1 ((u16*)psxRegs.CP2D.r)[18*2] +#define gteSZ2 ((u16*)psxRegs.CP2D.r)[19*2] +#define gteRGB0 psxRegs.CP2D.r[20] +#define gteRGB1 psxRegs.CP2D.r[21] +#define gteRGB2 psxRegs.CP2D.r[22] +#define gteMAC0 psxRegs.CP2D.r[24] +#define gteMAC1 ((s32*)psxRegs.CP2D.r)[25] +#define gteMAC2 ((s32*)psxRegs.CP2D.r)[26] +#define gteMAC3 ((s32*)psxRegs.CP2D.r)[27] +#define gteIRGB psxRegs.CP2D.r[28] +#define gteORGB psxRegs.CP2D.r[29] +#define gteLZCS psxRegs.CP2D.r[30] +#define gteLZCR psxRegs.CP2D.r[31] + +#define gteR ((u8 *)psxRegs.CP2D.r)[6*4] +#define gteG ((u8 *)psxRegs.CP2D.r)[6*4+1] +#define gteB ((u8 *)psxRegs.CP2D.r)[6*4+2] +#define gteCODE ((u8 *)psxRegs.CP2D.r)[6*4+3] +#define gteC gteCODE + +#define gteR0 ((u8 *)psxRegs.CP2D.r)[20*4] +#define gteG0 ((u8 *)psxRegs.CP2D.r)[20*4+1] +#define gteB0 ((u8 *)psxRegs.CP2D.r)[20*4+2] +#define gteCODE0 ((u8 *)psxRegs.CP2D.r)[20*4+3] +#define gteC0 gteCODE0 + +#define gteR1 ((u8 *)psxRegs.CP2D.r)[21*4] +#define gteG1 ((u8 *)psxRegs.CP2D.r)[21*4+1] +#define gteB1 ((u8 *)psxRegs.CP2D.r)[21*4+2] +#define gteCODE1 ((u8 *)psxRegs.CP2D.r)[21*4+3] +#define gteC1 gteCODE1 + +#define gteR2 ((u8 *)psxRegs.CP2D.r)[22*4] +#define gteG2 ((u8 *)psxRegs.CP2D.r)[22*4+1] +#define gteB2 ((u8 *)psxRegs.CP2D.r)[22*4+2] +#define gteCODE2 ((u8 *)psxRegs.CP2D.r)[22*4+3] +#define gteC2 gteCODE2 + + + +#define gteR11 ((s16*)psxRegs.CP2C.r)[0] +#define gteR12 ((s16*)psxRegs.CP2C.r)[1] +#define gteR13 ((s16*)psxRegs.CP2C.r)[2] +#define gteR21 ((s16*)psxRegs.CP2C.r)[3] +#define gteR22 ((s16*)psxRegs.CP2C.r)[4] +#define gteR23 ((s16*)psxRegs.CP2C.r)[5] +#define gteR31 ((s16*)psxRegs.CP2C.r)[6] +#define gteR32 ((s16*)psxRegs.CP2C.r)[7] +#define gteR33 ((s16*)psxRegs.CP2C.r)[8] +#define gteTRX ((s32*)psxRegs.CP2C.r)[5] +#define gteTRY ((s32*)psxRegs.CP2C.r)[6] +#define gteTRZ ((s32*)psxRegs.CP2C.r)[7] +#define gteL11 ((s16*)psxRegs.CP2C.r)[16] +#define gteL12 ((s16*)psxRegs.CP2C.r)[17] +#define gteL13 ((s16*)psxRegs.CP2C.r)[18] +#define gteL21 ((s16*)psxRegs.CP2C.r)[19] +#define gteL22 ((s16*)psxRegs.CP2C.r)[20] +#define gteL23 ((s16*)psxRegs.CP2C.r)[21] +#define gteL31 ((s16*)psxRegs.CP2C.r)[22] +#define gteL32 ((s16*)psxRegs.CP2C.r)[23] +#define gteL33 ((s16*)psxRegs.CP2C.r)[24] +#define gteRBK ((s32*)psxRegs.CP2C.r)[13] +#define gteGBK ((s32*)psxRegs.CP2C.r)[14] +#define gteBBK ((s32*)psxRegs.CP2C.r)[15] +#define gteLR1 ((s16*)psxRegs.CP2C.r)[32] +#define gteLR2 ((s16*)psxRegs.CP2C.r)[33] +#define gteLR3 ((s16*)psxRegs.CP2C.r)[34] +#define gteLG1 ((s16*)psxRegs.CP2C.r)[35] +#define gteLG2 ((s16*)psxRegs.CP2C.r)[36] +#define gteLG3 ((s16*)psxRegs.CP2C.r)[37] +#define gteLB1 ((s16*)psxRegs.CP2C.r)[38] +#define gteLB2 ((s16*)psxRegs.CP2C.r)[39] +#define gteLB3 ((s16*)psxRegs.CP2C.r)[40] +#define gteRFC ((s32*)psxRegs.CP2C.r)[21] +#define gteGFC ((s32*)psxRegs.CP2C.r)[22] +#define gteBFC ((s32*)psxRegs.CP2C.r)[23] +#define gteOFX ((s32*)psxRegs.CP2C.r)[24] +#define gteOFY ((s32*)psxRegs.CP2C.r)[25] +#define gteH ((u16*)psxRegs.CP2C.r)[52] +#define gteDQA ((s16*)psxRegs.CP2C.r)[54] +#define gteDQB ((s32*)psxRegs.CP2C.r)[28] +#define gteZSF3 ((s16*)psxRegs.CP2C.r)[58] +#define gteZSF4 ((s16*)psxRegs.CP2C.r)[60] +#define gteFLAG psxRegs.CP2C.r[31] + +__inline unsigned long MFC2(int reg) { + switch(reg) { + case 29: + gteORGB = (gteIR1 ) | + (gteIR2 << 5) | + (gteIR3 << 10); +// gteORGB = ((gteIR1 & 0xf80)>>7) | +// ((gteIR2 & 0xf80)>>2) | +// ((gteIR3 & 0xf80)<<3); + return gteORGB; + + default: + return psxRegs.CP2D.r[reg]; + } +} + +__inline void MTC2(unsigned long value, int reg) { + int a; + + switch(reg) { + case 8: case 9: case 10: case 11: + psxRegs.CP2D.r[reg] = (short)value; + break; + + case 15: + psxRegs.CP2D.r[12] = psxRegs.CP2D.r[13]; + psxRegs.CP2D.r[13] = psxRegs.CP2D.r[14]; + psxRegs.CP2D.r[14] = value; + psxRegs.CP2D.r[15] = value; + break; + + case 16: case 17: case 18: case 19: + psxRegs.CP2D.r[reg] = (value & 0xffff); + break; + + case 28: + psxRegs.CP2D.r[28] = value; + gteIR1 = (value ) & 0x1f; + gteIR2 = (value >> 5) & 0x1f; + gteIR3 = (value >> 10) & 0x1f; +// gteIR1 = ((value ) & 0x1f) << 4; +// gteIR2 = ((value >> 5) & 0x1f) << 4; +// gteIR3 = ((value >> 10) & 0x1f) << 4; + break; + + case 30: + psxRegs.CP2D.r[30] = value; + + a = psxRegs.CP2D.r[30]; +#if defined(__WIN32__) + if (a > 0) { + __asm { + mov eax, a; + bsr eax, eax; + mov a, eax; + } + psxRegs.CP2D.r[31] = 31 - a; + } else if (a < 0) { + __asm { + mov eax, a; + xor eax, 0xffffffff; + bsr eax, eax; + mov a, eax; + } + psxRegs.CP2D.r[31] = 31 - a; + } else { + psxRegs.CP2D.r[31] = 32; + } +#elif defined(__LINUX__) + if (a > 0) { + __asm__ ("bsrl %1, %0\n" : "=r"(a) : "r"(a) ); + psxRegs.CP2D.r[31] = 31 - a; + } else if (a < 0) { + a^= 0xffffffff; + __asm__ ("bsrl %1, %0\n" : "=r"(a) : "r"(a) ); + psxRegs.CP2D.r[31] = 31 - a; + } else { + psxRegs.CP2D.r[31] = 32; + } +#else + if (a > 0) { + int i; + for (i=31; (a & (1 << i)) == 0 && i >= 0; i--); + psxRegs.CP2D.r[31] = 31 - i; + } else if (a < 0) { + int i; + a^= 0xffffffff; + for (i=31; (a & (1 << i)) == 0 && i >= 0; i--); + psxRegs.CP2D.r[31] = 31 - i; + } else { + psxRegs.CP2D.r[31] = 32; + } +#endif + break; + + default: + psxRegs.CP2D.r[reg] = value; + } +} + +void gteMFC2() { + if (!_Rt_) return; + psxRegs.GPR.r[_Rt_] = MFC2(_Rd_); +} + +void gteCFC2() { + if (!_Rt_) return; + psxRegs.GPR.r[_Rt_] = psxRegs.CP2C.r[_Rd_]; +} + +void gteMTC2() { + MTC2(psxRegs.GPR.r[_Rt_], _Rd_); +} + +void gteCTC2() { + psxRegs.CP2C.r[_Rd_] = psxRegs.GPR.r[_Rt_]; +} + +#define _oB_ (psxRegs.GPR.r[_Rs_] + _Imm_) + +void gteLWC2() { + MTC2(psxMemRead32(_oB_), _Rt_); +} + +void gteSWC2() { + psxMemWrite32(_oB_, MFC2(_Rt_)); +} + +/////LIMITATIONS AND OTHER STUFF************************************ +#define MAC2IR() \ +{ \ + if (gteMAC1 < (long)(-32768)) { gteIR1=(long)(-32768); gteFLAG|=1<<24;} \ + else \ + if (gteMAC1 > (long)( 32767)) { gteIR1=(long)( 32767); gteFLAG|=1<<24;} \ + else gteIR1=(long)gteMAC1; \ + if (gteMAC2 < (long)(-32768)) { gteIR2=(long)(-32768); gteFLAG|=1<<23;} \ + else \ + if (gteMAC2 > (long)( 32767)) { gteIR2=(long)( 32767); gteFLAG|=1<<23;} \ + else gteIR2=(long)gteMAC2; \ + if (gteMAC3 < (long)(-32768)) { gteIR3=(long)(-32768); gteFLAG|=1<<22;} \ + else \ + if (gteMAC3 > (long)( 32767)) { gteIR3=(long)( 32767); gteFLAG|=1<<22;} \ + else gteIR3=(long)gteMAC3; \ +} + + +#define MAC2IR1() \ +{ \ + if (gteMAC1 < (long)0) { gteIR1=(long)0; gteFLAG|=1<<24;} \ + else if (gteMAC1 > (long)(32767)) { gteIR1=(long)(32767); gteFLAG|=1<<24;} \ + else gteIR1=(long)gteMAC1; \ + if (gteMAC2 < (long)0) { gteIR2=(long)0; gteFLAG|=1<<23;} \ + else if (gteMAC2 > (long)(32767)) { gteIR2=(long)(32767); gteFLAG|=1<<23;} \ + else gteIR2=(long)gteMAC2; \ + if (gteMAC3 < (long)0) { gteIR3=(long)0; gteFLAG|=1<<22;} \ + else if (gteMAC3 > (long)(32767)) { gteIR3=(long)(32767); gteFLAG|=1<<22;} \ + else gteIR3=(long)gteMAC3; \ +} + + + +/* +#define MAGIC (((65536. * 65536. * 16) + (65536.*.5)) * 65536.) + +static __inline long float2int(double d) +{ + double dtemp = MAGIC + d; + return (*(long *)&dtemp)-0x80000000; +}*/ +__inline double NC_OVERFLOW1(double x) +{ + if (x<-2147483648.0) {gteFLAG |= 1<<29;} + else + if (x> 2147483647.0) {gteFLAG |= 1<<26;} + + return x; +} + +__inline double NC_OVERFLOW2(double x) +{ + if (x<-2147483648.0) {gteFLAG |= 1<<28;} + else + if (x> 2147483647.0) {gteFLAG |= 1<<25;} + + return x; +} + +__inline double NC_OVERFLOW3(double x) +{ + if (x<-2147483648.0) {gteFLAG |= 1<<27;} + else + if (x> 2147483647.0) {gteFLAG |= 1<<24;} + + return x; +} + +__inline double NC_OVERFLOW4(double x) +{ + if (x<-2147483648.0) {gteFLAG |= 1<<16;} + else + if (x> 2147483647.0) {gteFLAG |= 1<<15;} + + return x; +} +/* +__inline double EDETEC1(double data) +{ + if (data<(double)-2147483647) {gteFLAG|=1<<30; return (double)-2147483647;} + else + if (data>(double) 2147483647) {gteFLAG|=1<<27; return (double) 2147483647;} + + else return data; +} + +__inline double EDETEC2(double data) +{ + if (data<(double)-2147483647) {gteFLAG|=1<<29; return (double)-2147483647;} + else + if (data>(double) 2147483647) {gteFLAG|=1<<26; return (double) 2147483647;} + + else return data; +} + +__inline double EDETEC3(double data) +{ + if (data<(double)-2147483647) {gteFLAG|=1<<28; return (double)-2147483647;} + else + if (data>(double) 2147483647) {gteFLAG|=1<<25; return (double) 2147483647;} + + else return data; +} + +__inline double EDETEC4(double data) +{ + if (data<(double)-2147483647) {gteFLAG|=1<<16; return (double)-2147483647;} + else + if (data>(double) 2147483647) {gteFLAG|=1<<15; return (double) 2147483647;} + + else return data; +}*/ +/* +double LimitAU(double fraction,unsigned long bitIndex) { + if (fraction < 0.0) { fraction = 0.0; gteFLAG |= (1< 32767.0) { fraction = 32767.0; gteFLAG |= (1< 32767.0) { fraction = 32767.0; gteFLAG |= (1< 255.0) { fraction = 255.0; gteFLAG |= (1< 65535.0) { fraction = 65535.0; gteFLAG |= (1< 1023.0) { fraction = 1023.0; gteFLAG |= (1< 1023.0) { fraction = 1023.0; gteFLAG |= (1<MAX) {gteFLAG|=1<MAX) return MAX; + + else return data; +} + +double OLIMIT(double data) +{ + data=(data); + + if (data<(double)-2147483647) {return (double)-2147483647;} + else + if (data>(double) 2147483647) {return (double) 2147483647;} + + else return data; +}*/ + +double limA1S(double x) { + + if (x <-32768.0) { x =-32768.0; gteFLAG |= (1<<24); } else + if (x > 32767.0) { x = 32767.0; gteFLAG |= (1<<24); } return (x); +} + +double limA2S(double x) { + + if (x <-32768.0) { x =-32768.0; gteFLAG |= (1<<23); } else + if (x > 32767.0) { x = 32767.0; gteFLAG |= (1<<23); } return (x); +} + +double limA3S(double x) { + + if (x <-32768.0) { x =-32768.0; gteFLAG |= (1<<22); } else + if (x > 32767.0) { x = 32767.0; gteFLAG |= (1<<22); } return (x); +} + +double limA1U(double x) { + + if (x < 0.0) { x = 0.0; gteFLAG |= (1<<24); } else + if (x > 32767.0) { x = 32767.0; gteFLAG |= (1<<24); } return (x); +} + +double limA2U(double x) { + + if (x < 0.0) { x = 0.0; gteFLAG |= (1<<23); } else + if (x > 32767.0) { x = 32767.0; gteFLAG |= (1<<23); } return (x); +} + +double limA3U(double x) { + + if (x < 0.0) { x = 0.0; gteFLAG |= (1<<22); } else + if (x > 32767.0) { x = 32767.0; gteFLAG |= (1<<22); } return (x); +} + +double limB1 (double x) { + + if (x < 0.0) { x = 0.0; gteFLAG |= (1<<21); } else + if (x > 255.0) { x = 255.0; gteFLAG |= (1<<21); } return (x); +} + +double limB2 (double x) { + + if (x < 0.0) { x = 0.0; gteFLAG |= (1<<20); } else + if (x > 255.0) { x = 255.0; gteFLAG |= (1<<20); } return (x); +} + +double limB3 (double x) { + + if (x < 0.0) { x = 0.0; gteFLAG |= (1<<19); } else + if (x > 255.0) { x = 255.0; gteFLAG |= (1<<19); } return (x); +} + +double limC (double x) { + + if (x < 0.0) { x = 0.0; gteFLAG |= (1<<18); } else + if (x > 65535.0) { x = 65535.0; gteFLAG |= (1<<18); } return (x); +} + +double limD1 (double x) { + + if (x < 1024.0) { x = 1024.0; gteFLAG |= (1<<14); } else + if (x > 1023.0) { x = 1023.0; gteFLAG |= (1<<14); } return (x); +} + +double limD2 (double x) { + + if (x < 1024.0) { x = 1024.0; gteFLAG |= (1<<13); } else + if (x > 1023.0) { x = 1023.0; gteFLAG |= (1<<13); } return (x); +} + +double limE (double x) { + + if (x < 0.0) { x = 0.0; gteFLAG |= (1<<12); } else + if (x > 4095.0) { x = 4095.0; gteFLAG |= (1<<12); } return (x); +} + +double limG1(double x) { + + if (x > 2147483647.0f) { gteFLAG |= (1<<16); } else + if (x <-2147483648.0f) { gteFLAG |= (1<<15); } + + if (x > 1023.0f) { x = 1023.0f; gteFLAG |= (1<<14); } else + if (x < -1024.0f) { x = -1024.0f; gteFLAG |= (1<<14); } return (x); +} + +double limG2(double x) { + + if (x > 2147483647.0f) { gteFLAG |= (1<<16); } else + if (x <-2147483648.0f) { gteFLAG |= (1<<15); } + + if (x > 1023.0f) { x = 1023.0f; gteFLAG |= (1<<13); } else + if (x < -1024.0f) { x = -1024.0f; gteFLAG |= (1<<13); } return (x); +} + +//********END OF LIMITATIONS**********************************/ + +void gteRTPS() { +// double SSX0,SSY0,SSZ0; +// double SZ; + double DSZ; +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif + +#ifdef GTE_LOG + GTE_LOG("GTE_RTPS\n"); +#endif + +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("RTPS", 14); + G_SD(0); + G_SD(1); + + G_SD(16); // Store original fifo + G_SD(17); + G_SD(18); + G_SD(19); + + G_SC(0); + G_SC(1); + G_SC(2); + G_SC(3); + G_SC(4); + G_SC(5); + G_SC(6); + G_SC(7); + + G_SC(24); + G_SC(25); + G_SC(26); + G_SC(27); + G_SC(28); + } +#endif +/* gteFLAG = 0; + + SSX0 = NC_OVERFLOW1((double)gteTRX + ((double)(gteVX0*gteR11) + (double)(gteVY0*gteR12) + (double)(gteVZ0*gteR13))/4096.0); + SSY0 = NC_OVERFLOW2((double)gteTRY + ((double)(gteVX0*gteR21) + (double)(gteVY0*gteR22) + (double)(gteVZ0*gteR23))/4096.0); + SSZ0 = NC_OVERFLOW3((double)gteTRZ + ((double)(gteVX0*gteR31) + (double)(gteVY0*gteR32) + (double)(gteVZ0*gteR33))/4096.0); + + SZ = LIMIT(SSZ0,(double)0,(double)65535,18); + DSZ = ((double)gteH/SZ); + + if ((DSZ>(double)2147483647)) {DSZ=(double)2; gteFLAG|=1<<17;} + + gteSZ0 = gteSZ1; + gteSZ1 = gteSZ2; + gteSZ2 = gteSZx; + gteSZx = (unsigned short)float2int(SZ); + + psxRegs.CP2D.r[12]= psxRegs.CP2D.r[13]; + psxRegs.CP2D.r[13]= psxRegs.CP2D.r[14]; + + gteSX2 = (signed short)float2int(LIMIT((double)(gteOFX)/65536.0f + (LimitAS(SSX0,24)*DSZ),(double)-1024,(double)1024,14)); + gteSY2 = (signed short)float2int(LIMIT((double)(gteOFY)/65536.0f + (LimitAS(SSY0,23)*DSZ),(double)-1024,(double)1024,13)); + + gteMAC1 = (signed long)(SSX0); + gteMAC2 = (signed long)(SSY0); + gteMAC3 = (signed long)(SSZ0); + + MAC2IR(); + + gteMAC0 = (signed long)float2int(OLIMIT((((double)gteDQB/(double)16777216) + (((double)gteDQA/(double)256)*DSZ))*16777216)); + gteIR0 = (signed long)float2int(LIMIT(((((double)gteDQB/(double)16777216) + (((double)gteDQA/(double)256)*DSZ))*4096),(double)0,(double)4095,12)); + + if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/ + + gteFLAG = 0; + + gteMAC1 = NC_OVERFLOW1(((signed long)(gteR11*gteVX0 + gteR12*gteVY0 + gteR13*gteVZ0)>>12) + gteTRX); + gteMAC2 = NC_OVERFLOW2(((signed long)(gteR21*gteVX0 + gteR22*gteVY0 + gteR23*gteVZ0)>>12) + gteTRY); + gteMAC3 = NC_OVERFLOW3(((signed long)(gteR31*gteVX0 + gteR32*gteVY0 + gteR33*gteVZ0)>>12) + gteTRZ); + + gteSZx = gteSZ0; + gteSZ0 = gteSZ1; + gteSZ1 = gteSZ2; + gteSZ2 = limC(gteMAC3); + + psxRegs.CP2D.r[12]= psxRegs.CP2D.r[13]; + psxRegs.CP2D.r[13]= psxRegs.CP2D.r[14]; + + DSZ = (double)gteH / gteSZ2; + if (DSZ > 2.0) { DSZ = 2.0f; gteFLAG |= 1<<17; } +// if (DSZ > 2147483647.0) { DSZ = 2.0f; gteFLAG |= 1<<17; } + + gteSX2 = limG1(gteOFX/65536.0 + (limA1S(gteMAC1) * DSZ)); + gteSY2 = limG2(gteOFY/65536.0 + (limA2S(gteMAC2) * DSZ)); + + MAC2IR(); + + gteMAC0 = (gteDQB/16777216.0 + (gteDQA/256.0) * DSZ) * 16777216.0; + gteIR0 = limE((gteDQB/16777216.0 + (gteDQA/256.0) * DSZ) * 4096.0); + + SUM_FLAG; + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(8); + G_GD(9); + G_GD(10); + G_GD(11); + + //G_GD(12); + //G_GD(13); + G_GD(14); + + G_GD(16); + G_GD(17); + G_GD(18); + G_GD(19); + + G_GD(24); + G_GD(25); + G_GD(26); + G_GD(27); + + G_GC(31); + } +#endif +} + +void gteRTPT() { +// double SSX0,SSY0,SSZ0; +// double SZ; + double DSZ; +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif + +#ifdef GTE_LOG + GTE_LOG("GTE_RTPT\n"); +#endif + +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("RTPT", 22); + G_SD(0); + G_SD(1); + G_SD(2); + G_SD(3); + G_SD(4); + G_SD(5); + + G_SD(16); // Store original fifo + G_SD(17); + G_SD(18); + G_SD(19); + + G_SC(0); + G_SC(1); + G_SC(2); + G_SC(3); + G_SC(4); + G_SC(5); + G_SC(6); + G_SC(7); + + G_SC(24); + G_SC(25); + G_SC(26); + G_SC(27); + G_SC(28); + } +#endif +/* gteFLAG = 0; + + gteSZ0 = gteSZx; + + SSX0 = NC_OVERFLOW1((double)gteTRX + ((double)(gteVX0 * gteR11) + (double)(gteVY0 * gteR12) + (double)(gteVZ0 * gteR13)) / 4096.0); + SSY0 = NC_OVERFLOW2((double)gteTRY + ((double)(gteVX0 * gteR21) + (double)(gteVY0 * gteR22) + (double)(gteVZ0 * gteR23)) / 4096.0); + SSZ0 = NC_OVERFLOW3((double)gteTRZ + ((double)(gteVX0 * gteR31) + (double)(gteVY0 * gteR32) + (double)(gteVZ0 * gteR33)) / 4096.0); + + SZ = LIMIT(SSZ0, (double)0, (double)65535, 18); + DSZ = ((double)gteH / SZ); + + if ((DSZ>(double)2147483647)) {DSZ=(double)2; gteFLAG|=1<<17;} + + gteSZ1 = (unsigned short)float2int(SZ); + gteSX0 = (signed short)float2int(LIMIT((double)(gteOFX)/65536.0f + (LimitAS(SSX0,24)*DSZ),(double)-1024,(double)1023,14)); + gteSY0 = (signed short)float2int(LIMIT((double)(gteOFY)/65536.0f + (LimitAS(SSY0,23)*DSZ),(double)-1024,(double)1023,13)); + + SSX0 = NC_OVERFLOW1((double)gteTRX + ((double)(gteVX1*gteR11) + (double)(gteVY1*gteR12) + (double)(gteVZ1*gteR13))/4096.0); + SSY0 = NC_OVERFLOW2((double)gteTRY + ((double)(gteVX1*gteR21) + (double)(gteVY1*gteR22) + (double)(gteVZ1*gteR23))/4096.0); + SSZ0 = NC_OVERFLOW3((double)gteTRZ + ((double)(gteVX1*gteR31) + (double)(gteVY1*gteR32) + (double)(gteVZ1*gteR33))/4096.0); + + SZ = LIMIT(SSZ0,(double)0,(double)65535,18); + DSZ = ((double)gteH/SZ); + + if ((DSZ>(double)2147483647)) {DSZ=(double)2; gteFLAG|=1<<17;} + + gteSZ2 = (unsigned short)float2int(SZ); + gteSX1 = (signed short)float2int(LIMIT((double)(gteOFX)/65536.0f + (LimitAS(SSX0,24)*DSZ),(double)-1024,(double)1023,14)); + gteSY1 = (signed short)float2int(LIMIT((double)(gteOFY)/65536.0f + (LimitAS(SSY0,23)*DSZ),(double)-1024,(double)1023,13)); + + SSX0 = NC_OVERFLOW1((double)gteTRX + ((double)(gteVX2*gteR11) + (double)(gteVY2*gteR12) + (double)(gteVZ2*gteR13))/4096.0); + SSY0 = NC_OVERFLOW2((double)gteTRY + ((double)(gteVX2*gteR21) + (double)(gteVY2*gteR22) + (double)(gteVZ2*gteR23))/4096.0); + SSZ0 = NC_OVERFLOW3((double)gteTRZ + ((double)(gteVX2*gteR31) + (double)(gteVY2*gteR32) + (double)(gteVZ2*gteR33))/4096.0); + + SZ = LIMIT(SSZ0,(double)0,(double)65535,18); + DSZ = ((double)gteH/SZ); + + if ((DSZ>(double)2147483647)) {DSZ=(double)2; gteFLAG|=1<<17;} + + gteSZx = (unsigned short)float2int(SZ); + gteSX2 = (signed short)float2int(LIMIT((double)(gteOFX)/65536.0f + (LimitAS(SSX0,24)*DSZ),(double)-1024,(double)1023,14)); + gteSY2 = (signed short)float2int(LIMIT((double)(gteOFY)/65536.0f + (LimitAS(SSY0,23)*DSZ),(double)-1024,(double)1023,13)); + + gteMAC1 = (signed long)float2int(SSX0); + gteMAC2 = (signed long)float2int(SSY0); + gteMAC3 = (signed long)float2int(SSZ0); + + MAC2IR(); + + gteMAC0 = (signed long)float2int(OLIMIT((((double)gteDQB/(double)16777216) + (((double)gteDQA/(double)256)*DSZ))*16777216)); + gteIR0 = (signed long)float2int(LIMIT(((((double)gteDQB/(double)16777216) + (((double)gteDQA/(double)256)*DSZ))*4096),(double)0,(double)4095,12)); + + if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/ + + /* NC: old + gteFLAG = 0; + + gteSZ0 = gteSZx; + + gteMAC1 = NC_OVERFLOW1(((signed long)(gteR11*gteVX0 + gteR12*gteVY0 + gteR13*gteVZ0)>>12) + gteTRX); + gteMAC2 = NC_OVERFLOW2(((signed long)(gteR21*gteVX0 + gteR22*gteVY0 + gteR23*gteVZ0)>>12) + gteTRY); + gteMAC3 = NC_OVERFLOW3(((signed long)(gteR31*gteVX0 + gteR32*gteVY0 + gteR33*gteVZ0)>>12) + gteTRZ); + + DSZ = gteH / limC(gteMAC3); + if (DSZ > 2147483647.0) { DSZ = 2.0f; gteFLAG |= 1<<17; } + + gteSZ1 = limC(gteMAC3); + + gteSX0 = limG1(gteOFX/65536.0 + (limA1S(gteMAC1) * DSZ)); + gteSY0 = limG2(gteOFY/65536.0 + (limA2S(gteMAC2) * DSZ)); + + gteMAC1 = NC_OVERFLOW1(((signed long)(gteR11*gteVX1 + gteR12*gteVY1 + gteR13*gteVZ1)>>12) + gteTRX); + gteMAC2 = NC_OVERFLOW2(((signed long)(gteR21*gteVX1 + gteR22*gteVY1 + gteR23*gteVZ1)>>12) + gteTRY); + gteMAC3 = NC_OVERFLOW3(((signed long)(gteR31*gteVX1 + gteR32*gteVY1 + gteR33*gteVZ1)>>12) + gteTRZ); + + DSZ = gteH / limC(gteMAC3); + if (DSZ > 2147483647.0) { DSZ = 2.0f; gteFLAG |= 1<<17; } + + gteSZ2 = limC(gteMAC3); + + gteSX1 = limG1(gteOFX/65536.0 + (limA1S(gteMAC1) * DSZ )); + gteSY1 = limG2(gteOFY/65536.0 + (limA2S(gteMAC2) * DSZ )); + + gteMAC1 = NC_OVERFLOW1(((signed long)(gteR11*gteVX2 + gteR12*gteVY2 + gteR13*gteVZ2)>>12) + gteTRX); + gteMAC2 = NC_OVERFLOW2(((signed long)(gteR21*gteVX2 + gteR22*gteVY2 + gteR23*gteVZ2)>>12) + gteTRY); + gteMAC3 = NC_OVERFLOW3(((signed long)(gteR31*gteVX2 + gteR32*gteVY2 + gteR33*gteVZ2)>>12) + gteTRZ); + + DSZ = gteH / limC(gteMAC3); if (DSZ > 2147483647.0f) { DSZ = 2.0f; gteFLAG |= 1<<17; } + + gteSZx = gteSZ2; + + gteSX2 = limG1(gteOFX/65536.0 + (limA1S(gteMAC1) * DSZ )); + gteSY2 = limG2(gteOFY/65536.0 + (limA2S(gteMAC2) * DSZ )); + + MAC2IR(); + + gteMAC0 = (gteDQB/16777216.0 + (gteDQA/256.0) * DSZ ) * 16777216.0; + gteIR0 = limE((gteDQB/16777216.0 + (gteDQA/256.0) * DSZ ) * 4096.0f); + */ + + gteFLAG = 0; + + gteSZx = gteSZ2; + + gteMAC1 = NC_OVERFLOW1(((signed long)(gteR11*gteVX0 + gteR12*gteVY0 + gteR13*gteVZ0)>>12) + gteTRX); + gteMAC2 = NC_OVERFLOW2(((signed long)(gteR21*gteVX0 + gteR22*gteVY0 + gteR23*gteVZ0)>>12) + gteTRY); + gteMAC3 = NC_OVERFLOW3(((signed long)(gteR31*gteVX0 + gteR32*gteVY0 + gteR33*gteVZ0)>>12) + gteTRZ); + + DSZ = gteH / limC(gteMAC3); + if (DSZ > 2.0) { DSZ = 2.0f; gteFLAG |= 1<<17; } +// if (DSZ > 2147483647.0) { DSZ = 2.0f; gteFLAG |= 1<<17; } + + gteSZ0 = limC(gteMAC3); + + gteSX0 = limG1(gteOFX/65536.0 + (limA1S(gteMAC1) * DSZ)); + gteSY0 = limG2(gteOFY/65536.0 + (limA2S(gteMAC2) * DSZ)); + + gteMAC1 = NC_OVERFLOW1(((signed long)(gteR11*gteVX1 + gteR12*gteVY1 + gteR13*gteVZ1)>>12) + gteTRX); + gteMAC2 = NC_OVERFLOW2(((signed long)(gteR21*gteVX1 + gteR22*gteVY1 + gteR23*gteVZ1)>>12) + gteTRY); + gteMAC3 = NC_OVERFLOW3(((signed long)(gteR31*gteVX1 + gteR32*gteVY1 + gteR33*gteVZ1)>>12) + gteTRZ); + + DSZ = gteH / limC(gteMAC3); + if (DSZ > 2.0) { DSZ = 2.0f; gteFLAG |= 1<<17; } +// if (DSZ > 2147483647.0) { DSZ = 2.0f; gteFLAG |= 1<<17; } + + gteSZ1 = limC(gteMAC3); + + gteSX1 = limG1(gteOFX/65536.0 + (limA1S(gteMAC1) * DSZ )); + gteSY1 = limG2(gteOFY/65536.0 + (limA2S(gteMAC2) * DSZ )); + + gteMAC1 = NC_OVERFLOW1(((signed long)(gteR11*gteVX2 + gteR12*gteVY2 + gteR13*gteVZ2)>>12) + gteTRX); + gteMAC2 = NC_OVERFLOW2(((signed long)(gteR21*gteVX2 + gteR22*gteVY2 + gteR23*gteVZ2)>>12) + gteTRY); + gteMAC3 = NC_OVERFLOW3(((signed long)(gteR31*gteVX2 + gteR32*gteVY2 + gteR33*gteVZ2)>>12) + gteTRZ); + + DSZ = gteH / limC(gteMAC3); + if (DSZ > 2.0) { DSZ = 2.0f; gteFLAG |= 1<<17; } +// if (DSZ > 2147483647.0f) { DSZ = 2.0f; gteFLAG |= 1<<17; } + + gteSZ2 = limC(gteMAC3); + + gteSX2 = limG1(gteOFX/65536.0 + (limA1S(gteMAC1) * DSZ )); + gteSY2 = limG2(gteOFY/65536.0 + (limA2S(gteMAC2) * DSZ )); + + MAC2IR(); + + gteMAC0 = (gteDQB/16777216.0 + (gteDQA/256.0) * DSZ ) * 16777216.0; + gteIR0 = limE((gteDQB/16777216.0 + (gteDQA/256.0) * DSZ ) * 4096.0f); + + SUM_FLAG; + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(8); + G_GD(9); + G_GD(10); + G_GD(11); + + G_GD(12); + G_GD(13); + G_GD(14); + + G_GD(16); + G_GD(17); + G_GD(18); + G_GD(19); + + G_GD(24); + G_GD(25); + G_GD(26); + G_GD(27); + + G_GC(31); + } +#endif +} + +#define gte_C11 gteLR1 +#define gte_C12 gteLR2 +#define gte_C13 gteLR3 +#define gte_C21 gteLG1 +#define gte_C22 gteLG2 +#define gte_C23 gteLG3 +#define gte_C31 gteLB1 +#define gte_C32 gteLB2 +#define gte_C33 gteLB3 + +#define _MVMVA_FUNC(_v0, _v1, _v2, mx) { \ + SSX = (_v0) * mx##11 + (_v1) * mx##12 + (_v2) * mx##13; \ + SSY = (_v0) * mx##21 + (_v1) * mx##22 + (_v2) * mx##23; \ + SSZ = (_v0) * mx##31 + (_v1) * mx##32 + (_v2) * mx##33; \ +} + +void gteMVMVA() { + double SSX, SSY, SSZ; + +#ifdef GTE_LOG + GTE_LOG("GTE_MVMVA %lx\n", psxRegs.code & 0x1ffffff); +#endif + + switch (psxRegs.code & 0x78000) { + case 0x00000: // V0 * R + _MVMVA_FUNC(gteVX0, gteVY0, gteVZ0, gteR); break; + case 0x08000: // V1 * R + _MVMVA_FUNC(gteVX1, gteVY1, gteVZ1, gteR); break; + case 0x10000: // V2 * R + _MVMVA_FUNC(gteVX2, gteVY2, gteVZ2, gteR); break; + case 0x18000: // IR * R + _MVMVA_FUNC((short)gteIR1, (short)gteIR2, (short)gteIR3, gteR); + break; + case 0x20000: // V0 * L + _MVMVA_FUNC(gteVX0, gteVY0, gteVZ0, gteL); break; + case 0x28000: // V1 * L + _MVMVA_FUNC(gteVX1, gteVY1, gteVZ1, gteL); break; + case 0x30000: // V2 * L + _MVMVA_FUNC(gteVX2, gteVY2, gteVZ2, gteL); break; + case 0x38000: // IR * L + _MVMVA_FUNC((short)gteIR1, (short)gteIR2, (short)gteIR3, gteL); break; + case 0x40000: // V0 * C + _MVMVA_FUNC(gteVX0, gteVY0, gteVZ0, gte_C); break; + case 0x48000: // V1 * C + _MVMVA_FUNC(gteVX1, gteVY1, gteVZ1, gte_C); break; + case 0x50000: // V2 * C + _MVMVA_FUNC(gteVX2, gteVY2, gteVZ2, gte_C); break; + case 0x58000: // IR * C + _MVMVA_FUNC((short)gteIR1, (short)gteIR2, (short)gteIR3, gte_C); break; + default: + SSX = SSY = SSZ = 0; + } + + if (psxRegs.code & 0x80000) { + SSX /= 4096.0; SSY /= 4096.0; SSZ /= 4096.0; + } + + switch (psxRegs.code & 0x6000) { + case 0x0000: // Add TR + SSX+= gteTRX; + SSY+= gteTRY; + SSZ+= gteTRZ; + break; + case 0x2000: // Add BK + SSX+= gteRBK; + SSY+= gteGBK; + SSZ+= gteBBK; + break; + case 0x4000: // Add FC + SSX+= gteRFC; + SSY+= gteGFC; + SSZ+= gteBFC; + break; + } + + gteFLAG = 0; + //gteMAC1 = (long)SSX; + //gteMAC2 = (long)SSY; + //gteMAC3 = (long)SSZ;//okay the follow lines are correct?? + gteMAC1=NC_OVERFLOW1(SSX); + gteMAC2=NC_OVERFLOW2(SSY); + gteMAC3=NC_OVERFLOW3(SSZ); + if (psxRegs.code & 0x400) + MAC2IR1() + else MAC2IR() + + SUM_FLAG; +} + +void gteNCLIP() { +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif + +#ifdef GTE_LOG + GTE_LOG("GTE_NCLIP\n"); +#endif + + //gteLog + +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("NCLIP", 8); + G_SD(12); + G_SD(13); + G_SD(14); + } +#endif + +/* gteFLAG = 0; + + gteMAC0 = (signed long)float2int(EDETEC4( + ((double)gteSX0*((double)gteSY1-(double)gteSY2))+ + ((double)gteSX1*((double)gteSY2-(double)gteSY0))+ + ((double)gteSX2*((double)gteSY0-(double)gteSY1)))); + + if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/ + gteFLAG = 0; + + + gteMAC0 = gteSX0 * (gteSY1 - gteSY2) + + gteSX1 * (gteSY2 - gteSY0) + + gteSX2 * (gteSY0 - gteSY1); + + //gteMAC0 = (gteSX0 - gteSX1) * (gteSY0 - gteSY2) - (gteSX0 - gteSX2) * (gteSY0 - gteSY1); + + SUM_FLAG; + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(24); + G_GC(31); + } +#endif +} + +void gteAVSZ3() { +// unsigned long SS; +// double SZ1,SZ2,SZ3; +// double ZSF3; +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif + +#ifdef GTE_LOG + GTE_LOG("GTE_AVSZ3\n"); +#endif + +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("AVSZ3", 5); + G_SD(16); + G_SD(17); + G_SD(18); + G_SD(19); + G_SC(29); + G_SC(30); + } +#endif + +/* gteFLAG = 0; + + SS = psxRegs.CP2D.r[17] & 0xffff; SZ1 = (double)SS; + SS = psxRegs.CP2D.r[18] & 0xffff; SZ2 = (double)SS; + SS = psxRegs.CP2D.r[19] & 0xffff; SZ3 = (double)SS; + SS = psxRegs.CP2C.r[29] & 0xffff; ZSF3 = (double)SS/(double)4096; + + psxRegs.CP2D.r[24] = (signed long)float2int(EDETEC4(((SZ1+SZ2+SZ3)*ZSF3))); + psxRegs.CP2D.r[7] = (unsigned short)float2int(LimitC(((SZ1+SZ2+SZ3)*ZSF3),18)); + + if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/ + + + gteFLAG = 0; + + /* NC: OLD + gteMAC0 = ((gteSZ1 + gteSZ2 + gteSZx) * (gteZSF3/4096.0f)); + + gteOTZ = limC((double)gteMAC0); + */ +/* gteMAC0 = ((gteSZ1 + gteSZ2 + gteSZx) * (gteZSF3)); + + gteOTZ = limC((double)(gteMAC0 >> 12));*/ + gteMAC0 = ((gteSZ0 + gteSZ1 + gteSZ2) * (gteZSF3)) >> 12; + + gteOTZ = limC((double)gteMAC0); + + SUM_FLAG + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(7); + G_GD(24); + G_GC(31); + } +#endif +} + +void gteAVSZ4() { +// unsigned long SS; +// double SZ0,SZ1,SZ2,SZ3; +// double ZSF4; +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif + +#ifdef GTE_LOG + GTE_LOG("GTE_AVSZ4\n"); +#endif + +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("AVSZ4", 6); + G_SD(16); + G_SD(17); + G_SD(18); + G_SD(19); + G_SC(29); + G_SC(30); + } +#endif + +/* gteFLAG = 0; + + SS = psxRegs.CP2D.r[16] & 0xffff; SZ0 = (double)SS; + SS = psxRegs.CP2D.r[17] & 0xffff; SZ1 = (double)SS; + SS = psxRegs.CP2D.r[18] & 0xffff; SZ2 = (double)SS; + SS = psxRegs.CP2D.r[19] & 0xffff; SZ3 = (double)SS; + SS = psxRegs.CP2C.r[30] & 0xffff; ZSF4 = (double)SS/(double)4096; + + psxRegs.CP2D.r[24] = (signed long)float2int(EDETEC4(((SZ0+SZ1+SZ2+SZ3)*ZSF4))); + psxRegs.CP2D.r[7] = (unsigned short)float2int(LimitC(((SZ0+SZ1+SZ2+SZ3)*ZSF4),18)); + + if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/ + gteFLAG = 0; + + /* NC: OLD + gteMAC0 = ((gteSZ0 + gteSZ1 + gteSZ2 + gteSZx) * (gteZSF4/4096.0f)); + + gteOTZ = limC((double)gteMAC0); + */ +/* gteMAC0 = ((gteSZ0 + gteSZ1 + gteSZ2 + gteSZx) * (gteZSF4)); + + gteOTZ = limC((double)(gteMAC0 >> 12)); +*/ + gteMAC0 = ((gteSZx + gteSZ0 + gteSZ1 + gteSZ2) * (gteZSF4))>> 12; + + gteOTZ = limC((double)gteMAC0); + + SUM_FLAG + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(7); + G_GD(24); + G_GC(31); + } +#endif +} + +void gteSQR() { + //double SSX0,SSY0,SSZ0; +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif + +#ifdef GTE_LOG + GTE_LOG("GTE_SQR %lx\n", psxRegs.code & 0x1ffffff); +#endif + +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("SQR", 5); + G_SD(9); + G_SD(10); + G_SD(11); + } +#endif + +/* gteFLAG = 0; + + SSX0 = (double)gteIR1 * gteIR1; + SSY0 = (double)gteIR2 * gteIR2; + SSZ0 = (double)gteIR3 * gteIR3; + + if (psxRegs.code & 0x80000) { + SSX0 /= 4096.0; SSY0 /= 4096.0; SSZ0 /= 4096.0; + } + + gteMAC1 = (long)SSX0; + gteMAC2 = (long)SSY0; + gteMAC3 = (long)SSZ0; + + MAC2IR1(); + + if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/ + gteFLAG = 0; + + if (psxRegs.code & 0x80000) { + + gteMAC1 = NC_OVERFLOW1((gteIR1 * gteIR1) / 4096.0f); + gteMAC2 = NC_OVERFLOW2((gteIR2 * gteIR2) / 4096.0f); + gteMAC3 = NC_OVERFLOW3((gteIR3 * gteIR3) / 4096.0f); + } else { + + gteMAC1 = NC_OVERFLOW1(gteIR1 * gteIR1); + gteMAC2 = NC_OVERFLOW2(gteIR2 * gteIR2); + gteMAC3 = NC_OVERFLOW3(gteIR3 * gteIR3); + } + MAC2IR1(); + + SUM_FLAG + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(9); + G_GD(10); + G_GD(11); + G_GD(25); + G_GD(26); + G_GD(27); + G_GC(31); + } +#endif +} +/* +#define GTE_NCCS(vn) { \ + RR0 = ((double)gteL11 * gteVX##vn + (double)gteL12 * gteVY##vn + (double)gteL13 * gteVZ##vn)/4096.0; \ + GG0 = ((double)gteL21 * gteVX##vn + (double)gteL22 * gteVY##vn + (double)gteL23 * gteVZ##vn)/4096.0; \ + BB0 = ((double)gteL31 * gteVX##vn + (double)gteL32 * gteVY##vn + (double)gteL33 * gteVZ##vn)/4096.0; \ + t1 = LimitAU(RR0,24); \ + t2 = LimitAU(GG0,23); \ + t3 = LimitAU(BB0,22); \ + \ + RR0 = (double)gteRBK + ((double)gteLR1 * t1 + (double)gteLR2 * t2 + (double)gteLR3 * t3)/4096.0; \ + GG0 = (double)gteGBK + ((double)gteLG1 * t1 + (double)gteLG2 * t2 + (double)gteLG3 * t3)/4096.0; \ + BB0 = (double)gteBBK + ((double)gteLB1 * t1 + (double)gteLB2 * t2 + (double)gteLB3 * t3)/4096.0; \ + t1 = LimitAU(RR0,24); \ + t2 = LimitAU(GG0,23); \ + t3 = LimitAU(BB0,22); \ + \ + RR0 = ((double)gteR * t1)/256.0; \ + GG0 = ((double)gteG * t2)/256.0; \ + BB0 = ((double)gteB * t3)/256.0; \ + \ + gteIR1 = (long)LimitAU(RR0,24); \ + gteIR2 = (long)LimitAU(GG0,23); \ + gteIR3 = (long)LimitAU(BB0,22); \ + \ + gteCODE0 = gteCODE1; gteCODE1 = gteCODE2; gteCODE2 = gteCODE; \ + gteR0 = gteR1; gteR1 = gteR2; gteR2 = (unsigned char)LimitB(RR0/16.0,21); \ + gteG0 = gteG1; gteG1 = gteG2; gteG2 = (unsigned char)LimitB(GG0/16.0,20); \ + gteB0 = gteB1; gteB1 = gteB2; gteB2 = (unsigned char)LimitB(BB0/16.0,19); \ + \ + gteMAC1 = (long)RR0; \ + gteMAC2 = (long)GG0; \ + gteMAC3 = (long)BB0; \ +} +*/ +/* +__forceinline double ncLIM1(double x) +{ + if(x > 8796093022207.0) + { + return 8796093022207.0; + } +} +*/ + + + +/* NC: OLD +#define GTE_NCCS(vn)\ +gte_LL1 = limA1U((gteL11*gteVX##vn + gteL12*gteVY##vn + gteL13*gteVZ##vn)/16777216.0f);\ +gte_LL2 = limA2U((gteL21*gteVX##vn + gteL22*gteVY##vn + gteL23*gteVZ##vn)/16777216.0f);\ +gte_LL3 = limA3U((gteL31*gteVX##vn + gteL32*gteVY##vn + gteL33*gteVZ##vn)/16777216.0f);\ +gte_RRLT= limA1U(gteRBK/4096.0f + (gteLR1/4096.0f*gte_LL1 + gteLR2/4096.0f*gte_LL2 + gteLR3/4096.0f*gte_LL3));\ +gte_GGLT= limA2U(gteGBK/4096.0f + (gteLG1/4096.0f*gte_LL1 + gteLG2/4096.0f*gte_LL2 + gteLG3/4096.0f*gte_LL3));\ +gte_BBLT= limA3U(gteBBK/4096.0f + (gteLB1/4096.0f*gte_LL1 + gteLB2/4096.0f*gte_LL2 + gteLB3/4096.0f*gte_LL3));\ +gte_RR0 = gteR*gte_RRLT;\ +gte_GG0 = gteG*gte_GGLT;\ +gte_BB0 = gteB*gte_BBLT;\ +gteIR1 = (long)limA1U(gte_RR0);\ +gteIR2 = (long)limA2U(gte_GG0);\ +gteIR3 = (long)limA3U(gte_BB0);\ +gteCODE0 = gteCODE1; gteCODE1 = gteCODE2; gteCODE2 = gteCODE;\ +gteR0 = gteR1; gteR1 = gteR2; gteR2 = (unsigned char)limB1(gte_RR0);\ +gteG0 = gteG1; gteG1 = gteG2; gteG2 = (unsigned char)limB2(gte_GG0);\ +gteB0 = gteB1; gteB1 = gteB2; gteB2 = (unsigned char)limB3(gte_BB0);\ +gteMAC1 = (long)gte_RR0;\ +gteMAC2 = (long)gte_GG0;\ +gteMAC3 = (long)gte_BB0;\ +*/ + +#define GTE_NCCS(vn)\ +gte_LL1 = limA1U((gteL11*gteVX##vn + gteL12*gteVY##vn + gteL13*gteVZ##vn)/16777216.0f);\ +gte_LL2 = limA2U((gteL21*gteVX##vn + gteL22*gteVY##vn + gteL23*gteVZ##vn)/16777216.0f);\ +gte_LL3 = limA3U((gteL31*gteVX##vn + gteL32*gteVY##vn + gteL33*gteVZ##vn)/16777216.0f);\ +gte_RRLT= limA1U(gteRBK/4096.0f + (gteLR1/4096.0f*gte_LL1 + gteLR2/4096.0f*gte_LL2 + gteLR3/4096.0f*gte_LL3));\ +gte_GGLT= limA2U(gteGBK/4096.0f + (gteLG1/4096.0f*gte_LL1 + gteLG2/4096.0f*gte_LL2 + gteLG3/4096.0f*gte_LL3));\ +gte_BBLT= limA3U(gteBBK/4096.0f + (gteLB1/4096.0f*gte_LL1 + gteLB2/4096.0f*gte_LL2 + gteLB3/4096.0f*gte_LL3));\ +gteMAC1 = (long)(gteR*gte_RRLT*16);\ +gteMAC2 = (long)(gteG*gte_GGLT*16);\ +gteMAC3 = (long)(gteB*gte_BBLT*16);\ +gteIR1 = (long)limA1U(gteMAC1);\ +gteIR2 = (long)limA2U(gteMAC2);\ +gteIR3 = (long)limA3U(gteMAC3);\ +gte_RR0 = gteMAC1>>4;\ +gte_GG0 = gteMAC2>>4;\ +gte_BB0 = gteMAC3>>4;\ +gteCODE0 = gteCODE1; gteCODE1 = gteCODE2; gteCODE2 = gteCODE;\ +gteR0 = gteR1; gteR1 = gteR2; gteR2 = (unsigned char)limB1(gte_RR0);\ +gteG0 = gteG1; gteG1 = gteG2; gteG2 = (unsigned char)limB2(gte_GG0);\ +gteB0 = gteB1; gteB1 = gteB2; gteB2 = (unsigned char)limB3(gte_BB0);\ + +void gteNCCS() { +// double RR0,GG0,BB0; +// double t1, t2, t3; + + double gte_LL1, gte_RR0, gte_RRLT; + double gte_LL2, gte_GG0, gte_GGLT; + double gte_LL3, gte_BB0, gte_BBLT; + +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif + +#ifdef GTE_LOG + GTE_LOG("GTE_NCCS\n"); +#endif + +/* + gteFLAG = 0; + + GTE_NCCS(0); + + if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/ + +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("NCCS", 17); + G_SD(0); + G_SD(1); + G_SD(6); + G_SC(8); + G_SC(9); + G_SC(10); + G_SC(11); + G_SC(12); + G_SC(13); + G_SC(14); + G_SC(15); + G_SC(16); + G_SC(17); + G_SC(18); + G_SC(19); + G_SC(20); + } +#endif + + gteFLAG = 0; + + GTE_NCCS(0); + + SUM_FLAG + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(9); + G_GD(10); + G_GD(11); + + //G_GD(20); + //G_GD(21); + G_GD(22); + + //G_GD(24); Doc must be wrong. PSX does not touch it. + G_GD(25); + G_GD(26); + G_GD(27); + + G_GC(31); + } +#endif +} + +void gteNCCT() { +// double RR0,GG0,BB0; +// double t1, t2, t3; + double gte_LL1, gte_RR0, gte_RRLT; + double gte_LL2, gte_GG0, gte_GGLT; + double gte_LL3, gte_BB0, gte_BBLT; + +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif + +#ifdef GTE_LOG + GTE_LOG("GTE_NCCT\n"); +#endif + + + /*gteFLAG = 0; + + GTE_NCCS(0); + GTE_NCCS(1); + GTE_NCCS(2); + + if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/ + +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("NCCT", 39); + G_SD(0); + G_SD(1); + G_SD(2); + G_SD(3); + G_SD(4); + G_SD(5); + G_SD(6); + + G_SC(8); + G_SC(9); + G_SC(10); + G_SC(11); + G_SC(12); + G_SC(13); + G_SC(14); + G_SC(15); + G_SC(16); + G_SC(17); + G_SC(18); + G_SC(19); + G_SC(20); + } +#endif + + gteFLAG = 0; + + GTE_NCCS(0); + GTE_NCCS(1); + GTE_NCCS(2); + + SUM_FLAG + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(9); + G_GD(10); + G_GD(11); + + G_GD(20); + G_GD(21); + G_GD(22); + + //G_GD(24); Doc must be wrong. PSX does not touch it. + G_GD(25); + G_GD(26); + G_GD(27); + + G_GC(31); + } +#endif +} + +#define GTE_NCDS(vn) \ +gte_LL1 = limA1U((gteL11*gteVX##vn + gteL12*gteVY##vn + gteL13*gteVZ##vn)/16777216.0f);\ +gte_LL2 = limA2U((gteL21*gteVX##vn + gteL22*gteVY##vn + gteL23*gteVZ##vn)/16777216.0f);\ +gte_LL3 = limA3U((gteL31*gteVX##vn + gteL32*gteVY##vn + gteL33*gteVZ##vn)/16777216.0f);\ +gte_RRLT= limA1U(gteRBK/4096.0f + (gteLR1/4096.0f*gte_LL1 + gteLR2/4096.0f*gte_LL2 + gteLR3/4096.0f*gte_LL3));\ +gte_GGLT= limA2U(gteGBK/4096.0f + (gteLG1/4096.0f*gte_LL1 + gteLG2/4096.0f*gte_LL2 + gteLG3/4096.0f*gte_LL3));\ +gte_BBLT= limA3U(gteBBK/4096.0f + (gteLB1/4096.0f*gte_LL1 + gteLB2/4096.0f*gte_LL2 + gteLB3/4096.0f*gte_LL3));\ +gte_RR0 = (gteR*gte_RRLT) + (gteIR0/4096.0f * limA1S(gteRFC/16.0f - (gteR*gte_RRLT)));\ +gte_GG0 = (gteG*gte_GGLT) + (gteIR0/4096.0f * limA2S(gteGFC/16.0f - (gteG*gte_GGLT)));\ +gte_BB0 = (gteB*gte_BBLT) + (gteIR0/4096.0f * limA3S(gteBFC/16.0f - (gteB*gte_BBLT)));\ +gteMAC1= (long)(gte_RR0 * 16.0f); gteIR1 = (long)limA1U(gte_RR0*16.0f);\ +gteMAC2= (long)(gte_GG0 * 16.0f); gteIR2 = (long)limA2U(gte_GG0*16.0f);\ +gteMAC3= (long)(gte_BB0 * 16.0f); gteIR3 = (long)limA3U(gte_BB0*16.0f);\ +gteRGB0 = gteRGB1; \ +gteRGB1 = gteRGB2; \ +gteR2 = limB1(gte_RR0); \ +gteG2 = limB2(gte_GG0); \ +gteB2 = limB3(gte_BB0); gteCODE2 = gteCODE; + +void gteNCDS() { +/* double tRLT,tRRLT; + double tGLT,tGGLT; + double tBLT,tBBLT; + double tRR0,tL1,tLL1; + double tGG0,tL2,tLL2; + double tBB0,tL3,tLL3; + unsigned long C,R,G,B; */ + double gte_LL1, gte_RR0, gte_RRLT; + double gte_LL2, gte_GG0, gte_GGLT; + double gte_LL3, gte_BB0, gte_BBLT; + +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif + +#ifdef GTE_LOG + GTE_LOG("GTE_NCDS\n"); +#endif + +/* gteFLAG = 0; + + R = ((gteRGB)&0xff); + G = ((gteRGB>> 8)&0xff); + B = ((gteRGB>>16)&0xff); + C = ((gteRGB>>24)&0xff); + + tLL1 = (gteL11/4096.0 * gteVX0/4096.0) + (gteL12/4096.0 * gteVY0/4096.0) + (gteL13/4096.0 * gteVZ0/4096.0); + tLL2 = (gteL21/4096.0 * gteVX0/4096.0) + (gteL22/4096.0 * gteVY0/4096.0) + (gteL23/4096.0 * gteVZ0/4096.0); + tLL3 = (gteL31/4096.0 * gteVX0/4096.0) + (gteL32/4096.0 * gteVY0/4096.0) + (gteL33/4096.0 * gteVZ0/4096.0); + + tL1 = LimitAU(tLL1,24); + tL2 = LimitAU(tLL2,23); + tL3 = LimitAU(tLL3,22); + + tRRLT = gteRBK/4096.0 + (gteLR1/4096.0 * tL1) + (gteLR2/4096.0 * tL2) + (gteLR3/4096.0 * tL3); + tGGLT = gteGBK/4096.0 + (gteLG1/4096.0 * tL1) + (gteLG2/4096.0 * tL2) + (gteLG3/4096.0 * tL3); + tBBLT = gteBBK/4096.0 + (gteLB1/4096.0 * tL1) + (gteLB2/4096.0 * tL2) + (gteLB3/4096.0 * tL3); + + tRLT = LimitAU(tRRLT,24); + tGLT = LimitAU(tGGLT,23); + tBLT = LimitAU(tBBLT,22); + + tRR0 = (R * tRLT) + (gteIR0/4096.0 * LimitAS(gteRFC/16.0 - (R * tRLT),24)); + tGG0 = (G * tGLT) + (gteIR0/4096.0 * LimitAS(gteGFC/16.0 - (G * tGLT),23)); + tBB0 = (B * tBLT) + (gteIR0/4096.0 * LimitAS(gteBFC/16.0 - (B * tBLT),22)); + + gteMAC1 = (long)(tRR0 * 16.0); gteIR1 = (long)LimitAU((tRR0*16.0),24); + gteMAC2 = (long)(tGG0 * 16.0); gteIR2 = (long)LimitAU((tGG0*16.0),23); + gteMAC3 = (long)(tBB0 * 16.0); gteIR3 = (long)LimitAU((tBB0*16.0),22); + + R = (unsigned long)LimitB(tRR0,21); if (R>255) R=255; else if (R<0) R=0; + G = (unsigned long)LimitB(tGG0,20); if (G>255) G=255; else if (G<0) G=0; + B = (unsigned long)LimitB(tBB0,19); if (B>255) B=255; else if (B<0) B=0; + + gteRGB0 = gteRGB1; + gteRGB1 = gteRGB2; + gteRGB2 = R|(G<<8)|(B<<16)|(C<<24); + + if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/ + +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("NCDS", 19); + G_SD(0); + G_SD(1); + G_SD(6); + G_SD(8); + + G_SC(8); + G_SC(9); + G_SC(10); + G_SC(11); + G_SC(12); + G_SC(13); + G_SC(14); + G_SC(15); + G_SC(16); + G_SC(17); + G_SC(18); + G_SC(19); + G_SC(20); + G_SC(21); + G_SC(22); + G_SC(23); + } +#endif + + gteFLAG = 0; + GTE_NCDS(0); + + SUM_FLAG; + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(9); + G_GD(10); + G_GD(11); + + //G_GD(20); + //G_GD(21); + G_GD(22); + + G_GD(25); + G_GD(26); + G_GD(27); + + G_GC(31); + } +#endif +} + +void gteNCDT() { + /*double tRLT,tRRLT; + double tGLT,tGGLT; + double tBLT,tBBLT; + double tRR0,tL1,tLL1; + double tGG0,tL2,tLL2; + double tBB0,tL3,tLL3; + unsigned long C,R,G,B;*/ + double gte_LL1, gte_RR0, gte_RRLT; + double gte_LL2, gte_GG0, gte_GGLT; + double gte_LL3, gte_BB0, gte_BBLT; + +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif + +#ifdef GTE_LOG + GTE_LOG("GTE_NCDT\n"); +#endif + +/* gteFLAG = 0; + + R = ((gteRGB)&0xff); + G = ((gteRGB>> 8)&0xff); + B = ((gteRGB>>16)&0xff); + C = ((gteRGB>>24)&0xff); + + tLL1 = (gteL11/4096.0 * gteVX0/4096.0) + (gteL12/4096.0 * gteVY0/4096.0) + (gteL13/4096.0 * gteVZ0/4096.0); + tLL2 = (gteL21/4096.0 * gteVX0/4096.0) + (gteL22/4096.0 * gteVY0/4096.0) + (gteL23/4096.0 * gteVZ0/4096.0); + tLL3 = (gteL31/4096.0 * gteVX0/4096.0) + (gteL32/4096.0 * gteVY0/4096.0) + (gteL33/4096.0 * gteVZ0/4096.0); + + tL1 = LimitAU(tLL1,24); + tL2 = LimitAU(tLL2,23); + tL3 = LimitAU(tLL3,22); + + tRRLT = gteRBK/4096.0 + (gteLR1/4096.0 * tL1) + (gteLR2/4096.0 * tL2) + (gteLR3/4096.0 * tL3); + tGGLT = gteGBK/4096.0 + (gteLG1/4096.0 * tL1) + (gteLG2/4096.0 * tL2) + (gteLG3/4096.0 * tL3); + tBBLT = gteBBK/4096.0 + (gteLB1/4096.0 * tL1) + (gteLB2/4096.0 * tL2) + (gteLB3/4096.0 * tL3); + + tRLT = LimitAU(tRRLT,24); + tGLT = LimitAU(tGGLT,23); + tBLT = LimitAU(tBBLT,22); + + tRR0 = (R * tRLT) + (gteIR0/4096.0 * LimitAS(gteRFC/16.0 - (R * tRLT),24)); + tGG0 = (G * tGLT) + (gteIR0/4096.0 * LimitAS(gteGFC/16.0 - (G * tGLT),23)); + tBB0 = (B * tBLT) + (gteIR0/4096.0 * LimitAS(gteBFC/16.0 - (B * tBLT),22)); + + gteMAC1 = (long)(tRR0 * 16.0); gteIR1 = (long)LimitAU((tRR0*16.0),24); + gteMAC2 = (long)(tGG0 * 16.0); gteIR2 = (long)LimitAU((tGG0*16.0),23); + gteMAC3 = (long)(tBB0 * 16.0); gteIR3 = (long)LimitAU((tBB0*16.0),22); + + R = (unsigned long)LimitB(tRR0,21); if (R>255) R=255; else if (R<0) R=0; + G = (unsigned long)LimitB(tGG0,20); if (G>255) G=255; else if (G<0) G=0; + B = (unsigned long)LimitB(tBB0,19); if (B>255) B=255; else if (B<0) B=0; + + gteRGB0 = gteRGB1; + gteRGB1 = gteRGB2; + gteRGB2 = R|(G<<8)|(B<<16)|(C<<24); + + R = ((gteRGB)&0xff); + G = ((gteRGB>> 8)&0xff); + B = ((gteRGB>>16)&0xff); + C = ((gteRGB>>24)&0xff); + + tLL1 = (gteL11/4096.0 * gteVX1/4096.0) + (gteL12/4096.0 * gteVY1/4096.0) + (gteL13/4096.0 * gteVZ1/4096.0); + tLL2 = (gteL21/4096.0 * gteVX1/4096.0) + (gteL22/4096.0 * gteVY1/4096.0) + (gteL23/4096.0 * gteVZ1/4096.0); + tLL3 = (gteL31/4096.0 * gteVX1/4096.0) + (gteL32/4096.0 * gteVY1/4096.0) + (gteL33/4096.0 * gteVZ1/4096.0); + + tL1 = LimitAU(tLL1,24); + tL2 = LimitAU(tLL2,23); + tL3 = LimitAU(tLL3,22); + + tRRLT = gteRBK/4096.0 + (gteLR1/4096.0 * tL1) + (gteLR2/4096.0 * tL2) + (gteLR3/4096.0 * tL3); + tGGLT = gteGBK/4096.0 + (gteLG1/4096.0 * tL1) + (gteLG2/4096.0 * tL2) + (gteLG3/4096.0 * tL3); + tBBLT = gteBBK/4096.0 + (gteLB1/4096.0 * tL1) + (gteLB2/4096.0 * tL2) + (gteLB3/4096.0 * tL3); + + tRLT = LimitAU(tRRLT,24); + tGLT = LimitAU(tGGLT,23); + tBLT = LimitAU(tBBLT,22); + + tRR0 = (R * tRLT) + (gteIR0/4096.0 * LimitAS(gteRFC/16.0 - (R * tRLT),24)); + tGG0 = (G * tGLT) + (gteIR0/4096.0 * LimitAS(gteGFC/16.0 - (G * tGLT),23)); + tBB0 = (B * tBLT) + (gteIR0/4096.0 * LimitAS(gteBFC/16.0 - (B * tBLT),22)); + + gteMAC1 = (long)(tRR0 * 16.0); gteIR1 = (long)LimitAU((tRR0*16.0),24); + gteMAC2 = (long)(tGG0 * 16.0); gteIR2 = (long)LimitAU((tGG0*16.0),23); + gteMAC3 = (long)(tBB0 * 16.0); gteIR3 = (long)LimitAU((tBB0*16.0),22); + + R = (unsigned long)LimitB(tRR0,21); if (R>255) R=255; else if (R<0) R=0; + G = (unsigned long)LimitB(tGG0,20); if (G>255) G=255; else if (G<0) G=0; + B = (unsigned long)LimitB(tBB0,19); if (B>255) B=255; else if (B<0) B=0; + + gteRGB0 = gteRGB1; + gteRGB1 = gteRGB2; + gteRGB2 = R|(G<<8)|(B<<16)|(C<<24); + + R = ((gteRGB)&0xff); + G = ((gteRGB>> 8)&0xff); + B = ((gteRGB>>16)&0xff); + C = ((gteRGB>>24)&0xff); + + tLL1 = (gteL11/4096.0 * gteVX2/4096.0) + (gteL12/4096.0 * gteVY2/4096.0) + (gteL13/4096.0 * gteVZ2/4096.0); + tLL2 = (gteL21/4096.0 * gteVX2/4096.0) + (gteL22/4096.0 * gteVY2/4096.0) + (gteL23/4096.0 * gteVZ2/4096.0); + tLL3 = (gteL31/4096.0 * gteVX2/4096.0) + (gteL32/4096.0 * gteVY2/4096.0) + (gteL33/4096.0 * gteVZ2/4096.0); + + tL1 = LimitAU(tLL1,24); + tL2 = LimitAU(tLL2,23); + tL3 = LimitAU(tLL3,22); + + tRRLT = gteRBK/4096.0 + (gteLR1/4096.0 * tL1) + (gteLR2/4096.0 * tL2) + (gteLR3/4096.0 * tL3); + tGGLT = gteGBK/4096.0 + (gteLG1/4096.0 * tL1) + (gteLG2/4096.0 * tL2) + (gteLG3/4096.0 * tL3); + tBBLT = gteBBK/4096.0 + (gteLB1/4096.0 * tL1) + (gteLB2/4096.0 * tL2) + (gteLB3/4096.0 * tL3); + + tRLT = LimitAU(tRRLT,24); + tGLT = LimitAU(tGGLT,23); + tBLT = LimitAU(tBBLT,22); + + tRR0 = (R * tRLT) + (gteIR0/4096.0 * LimitAS(gteRFC/16.0 - (R * tRLT),24)); + tGG0 = (G * tGLT) + (gteIR0/4096.0 * LimitAS(gteGFC/16.0 - (G * tGLT),23)); + tBB0 = (B * tBLT) + (gteIR0/4096.0 * LimitAS(gteBFC/16.0 - (B * tBLT),22)); + + gteMAC1 = (long)(tRR0 * 16.0); gteIR1 = (long)LimitAU((tRR0*16.0),24); + gteMAC2 = (long)(tGG0 * 16.0); gteIR2 = (long)LimitAU((tGG0*16.0),23); + gteMAC3 = (long)(tBB0 * 16.0); gteIR3 = (long)LimitAU((tBB0*16.0),22); + + R = (unsigned long)LimitB(tRR0,21); if (R>255) R=255; else if (R<0) R=0; + G = (unsigned long)LimitB(tGG0,20); if (G>255) G=255; else if (G<0) G=0; + B = (unsigned long)LimitB(tBB0,19); if (B>255) B=255; else if (B<0) B=0; + + gteRGB0 = gteRGB1; + gteRGB1 = gteRGB2; + gteRGB2 = R|(G<<8)|(B<<16)|(C<<24); + + if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/ + +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("NCDT", 44); + G_SD(0); + G_SD(1); + G_SD(2); + G_SD(3); + G_SD(4); + G_SD(5); + G_SD(6); + G_SD(8); + + G_SC(8); + G_SC(9); + G_SC(10); + G_SC(11); + G_SC(12); + G_SC(13); + G_SC(14); + G_SC(15); + G_SC(16); + G_SC(17); + G_SC(18); + G_SC(19); + G_SC(20); + G_SC(21); + G_SC(22); + G_SC(23); + } +#endif + + gteFLAG = 0; + GTE_NCDS(0); + GTE_NCDS(1); + GTE_NCDS(2); + + SUM_FLAG; + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(9); + G_GD(10); + G_GD(11); + + G_GD(20); + G_GD(21); + G_GD(22); + + G_GD(25); + G_GD(26); + G_GD(27); + + G_GC(31); + } +#endif +} + +#define gteD1 (*(short *)>eR11) +#define gteD2 (*(short *)>eR22) +#define gteD3 (*(short *)>eR33) + +void gteOP() { +// double SSX0=0,SSY0=0,SSZ0=0; +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif + +#ifdef GTE_LOG + GTE_LOG("GTE_OP %lx\n", psxRegs.code & 0x1ffffff); +#endif + +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("OP", 6); + G_SD(9); + G_SD(10); + G_SD(11); + + G_SC(0); + G_SC(2); + G_SC(4); + } +#endif +/* gteFLAG=0; + + switch (psxRegs.code & 0x1ffffff) { + case 0x178000C://op12 + SSX0 = EDETEC1((gteR22*(short)gteIR3 - gteR33*(short)gteIR2)/(double)4096); + SSY0 = EDETEC2((gteR33*(short)gteIR1 - gteR11*(short)gteIR3)/(double)4096); + SSZ0 = EDETEC3((gteR11*(short)gteIR2 - gteR22*(short)gteIR1)/(double)4096); + break; + case 0x170000C: + SSX0 = EDETEC1((gteR22*(short)gteIR3 - gteR33*(short)gteIR2)); + SSY0 = EDETEC2((gteR33*(short)gteIR1 - gteR11*(short)gteIR3)); + SSZ0 = EDETEC3((gteR11*(short)gteIR2 - gteR22*(short)gteIR1)); + break; + } + + gteMAC1 = (long)float2int(SSX0); + gteMAC2 = (long)float2int(SSY0); + gteMAC3 = (long)float2int(SSZ0); + + MAC2IR(); + + if (gteIR1<0) gteIR1=0; + if (gteIR2<0) gteIR2=0; + if (gteIR3<0) gteIR3=0; + + if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/ + gteFLAG = 0; + + if (psxRegs.code & 0x80000) { + + gteMAC1 = NC_OVERFLOW1((gteD2 * gteIR3 - gteD3 * gteIR2) / 4096.0f); + gteMAC2 = NC_OVERFLOW2((gteD3 * gteIR1 - gteD1 * gteIR3) / 4096.0f); + gteMAC3 = NC_OVERFLOW3((gteD1 * gteIR2 - gteD2 * gteIR1) / 4096.0f); + } else { + + gteMAC1 = NC_OVERFLOW1(gteD2 * gteIR3 - gteD3 * gteIR2); + gteMAC2 = NC_OVERFLOW2(gteD3 * gteIR1 - gteD1 * gteIR3); + gteMAC3 = NC_OVERFLOW3(gteD1 * gteIR2 - gteD2 * gteIR1); + } + + /* NC: old + MAC2IR1(); + */ + MAC2IR(); + + SUM_FLAG + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(9); + G_GD(10); + G_GD(11); + + G_GD(25); + G_GD(26); + G_GD(27); + + G_GC(31); + } +#endif +} + +void gteDCPL() { +// unsigned long C,R,G,B; +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif +#ifdef GTE_LOG + GTE_LOG("GTE_DCPL\n"); +#endif + +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("DCPL", 8); + G_SD(6); + G_SD(8); + G_SD(9); + G_SD(10); + G_SD(11); + + G_SC(21); + G_SC(22); + G_SC(23); + } +#endif +/* R = ((gteRGB)&0xff); + G = ((gteRGB>> 8)&0xff); + B = ((gteRGB>>16)&0xff); + C = ((gteRGB>>24)&0xff); + + gteMAC1 = (signed long)((double)(R*gteIR1) + (double)(gteIR0*LimitAS(gteRFC-(double)(R*gteIR1),24))/4096.0); + gteMAC2 = (signed long)((double)(G*gteIR2) + (double)(gteIR0*LimitAS(gteGFC-(double)(G*gteIR2),23))/4096.0); + gteMAC3 = (signed long)((double)(B*gteIR3) + (double)(gteIR0*LimitAS(gteBFC-(double)(B*gteIR3),22))/4096.0); + + MAC2IR() + + R = (unsigned long)LimitB(gteMAC1,21); if (R>255) R=255; else if (R<0) R=0; + G = (unsigned long)LimitB(gteMAC2,20); if (G>255) G=255; else if (G<0) G=0; + B = (unsigned long)LimitB(gteMAC3,19); if (B>255) B=255; else if (B<0) B=0; + + gteRGB0 = gteRGB1; + gteRGB1 = gteRGB2; + gteRGB2 = R|(G<<8)|(B<<16)|(C<<24); + + if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/ + +/* gteFLAG = 0; + + gteMAC1 = NC_OVERFLOW1((gteR * gteIR1) / 256.0f + (gteIR0 * limA1S(gteRFC - ((gteR * gteIR1) / 256.0f))) / 4096.0f); + gteMAC2 = NC_OVERFLOW2((gteG * gteIR1) / 256.0f + (gteIR0 * limA2S(gteGFC - ((gteG * gteIR1) / 256.0f))) / 4096.0f); + gteMAC3 = NC_OVERFLOW3((gteB * gteIR1) / 256.0f + (gteIR0 * limA3S(gteBFC - ((gteB * gteIR1) / 256.0f))) / 4096.0f); + */ +/* gteMAC1 = ( (signed long)(gteR)*gteIR1 + (gteIR0*(signed short)limA1S(gteRFC - ((gteR*gteIR1)>>12) )) ) >>6; + gteMAC2 = ( (signed long)(gteG)*gteIR2 + (gteIR0*(signed short)limA2S(gteGFC - ((gteG*gteIR2)>>12) )) ) >>6; + gteMAC3 = ( (signed long)(gteB)*gteIR3 + (gteIR0*(signed short)limA3S(gteBFC - ((gteB*gteIR3)>>12) )) ) >>6;*/ + + gteMAC1 = ( (signed long)(gteR)*gteIR1 + (gteIR0*(signed short)limA1S(gteRFC - ((gteR*gteIR1)>>12) )) ) >>8; + gteMAC2 = ( (signed long)(gteG)*gteIR2 + (gteIR0*(signed short)limA2S(gteGFC - ((gteG*gteIR2)>>12) )) ) >>8; + gteMAC3 = ( (signed long)(gteB)*gteIR3 + (gteIR0*(signed short)limA3S(gteBFC - ((gteB*gteIR3)>>12) )) ) >>8; + + gteFLAG=0; + MAC2IR(); + + gteRGB0 = gteRGB1; + gteRGB1 = gteRGB2; + + gteR2 = limB1(gteMAC1 / 16.0f); + gteG2 = limB2(gteMAC2 / 16.0f); + gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE; + + SUM_FLAG + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(9); + G_GD(10); + G_GD(11); + + //G_GD(20); + //G_GD(21); + G_GD(22); + + G_GD(25); + G_GD(26); + G_GD(27); + + G_GC(31); + } +#endif +} + +void gteGPF() { +// double ipx, ipy, ipz; +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif +#ifdef GTE_LOG + GTE_LOG("GTE_GPF %lx\n", psxRegs.code & 0x1ffffff); +#endif +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("GPF", 5); + G_SD(6); + G_SD(8); + G_SD(9); + G_SD(10); + G_SD(11); + } +#endif +/* gteFLAG = 0; + + ipx = (double)((short)gteIR0) * ((short)gteIR1); + ipy = (double)((short)gteIR0) * ((short)gteIR2); + ipz = (double)((short)gteIR0) * ((short)gteIR3); + + // same as mvmva + if (psxRegs.code & 0x80000) { + ipx /= 4096.0; ipy /= 4096.0; ipz /= 4096.0; + } + + gteMAC1 = (long)ipx; + gteMAC2 = (long)ipy; + gteMAC3 = (long)ipz; + + gteIR1 = (long)LimitAS(ipx,24); + gteIR2 = (long)LimitAS(ipy,23); + gteIR3 = (long)LimitAS(ipz,22); + + gteRGB0 = gteRGB1; + gteRGB1 = gteRGB2; + gteC2 = gteCODE; + gteR2 = (unsigned char)LimitB(ipx,21); + gteG2 = (unsigned char)LimitB(ipy,20); + gteB2 = (unsigned char)LimitB(ipz,19);*/ + + gteFLAG = 0; + + if (psxRegs.code & 0x80000) { + gteMAC1 = NC_OVERFLOW1((gteIR0 * gteIR1) / 4096.0f); + gteMAC2 = NC_OVERFLOW2((gteIR0 * gteIR2) / 4096.0f); + gteMAC3 = NC_OVERFLOW3((gteIR0 * gteIR3) / 4096.0f); + } else { + gteMAC1 = NC_OVERFLOW1(gteIR0 * gteIR1); + gteMAC2 = NC_OVERFLOW2(gteIR0 * gteIR2); + gteMAC3 = NC_OVERFLOW3(gteIR0 * gteIR3); + } + MAC2IR(); + + gteRGB0 = gteRGB1; + gteRGB1 = gteRGB2; + + gteR2 = limB1(gteMAC1 / 16.0f); + gteG2 = limB2(gteMAC2 / 16.0f); + gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE; + + SUM_FLAG + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(9); + G_GD(10); + G_GD(11); + + //G_GD(20); + //G_GD(21); + G_GD(22); + + G_GD(25); + G_GD(26); + G_GD(27); + + G_GC(31); + } +#endif +} + +void gteGPL() { + // double IPX=0,IPY=0,IPZ=0; +// unsigned long C,R,G,B; +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif +#ifdef GTE_LOG + GTE_LOG("GTE_GPL %lx\n", psxRegs.code & 0x1ffffff); +#endif + +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("GPL", 5); + G_SD(6); + G_SD(8); + G_SD(9); + G_SD(10); + G_SD(11); + + G_SD(25); + G_SD(26); + G_SD(27); + } +#endif + +/* gteFLAG=0; + switch(psxRegs.code & 0x1ffffff) { + case 0x1A8003E: + IPX = EDETEC1((double)gteMAC1 + ((double)gteIR0*(double)gteIR1)/4096.0f); + IPY = EDETEC2((double)gteMAC2 + ((double)gteIR0*(double)gteIR2)/4096.0f); + IPZ = EDETEC3((double)gteMAC3 + ((double)gteIR0*(double)gteIR3)/4096.0f); + break; + + case 0x1A0003E: + IPX = EDETEC1((double)gteMAC1 + ((double)gteIR0*(double)gteIR1)); + IPY = EDETEC2((double)gteMAC2 + ((double)gteIR0*(double)gteIR2)); + IPZ = EDETEC3((double)gteMAC3 + ((double)gteIR0*(double)gteIR3)); + break; + } + gteIR1 = (short)float2int(LimitAS(IPX,24)); + gteIR2 = (short)float2int(LimitAS(IPY,23)); + gteIR3 = (short)float2int(LimitAS(IPZ,22)); + + gteMAC1 = (int)float2int(IPX); + gteMAC2 = (int)float2int(IPY); + gteMAC3 = (int)float2int(IPZ); + + C = gteRGB & 0xff000000; + R = float2int(ALIMIT(IPX,0,255)); + G = float2int(ALIMIT(IPY,0,255)); + B = float2int(ALIMIT(IPZ,0,255)); + + gteRGB0 = gteRGB1; + gteRGB1 = gteRGB2; + gteRGB2 = C|R|(G<<8)|(B<<16);*/ + gteFLAG = 0; + + if (psxRegs.code & 0x80000) { + + gteMAC1 = NC_OVERFLOW1(gteMAC1 + (gteIR0 * gteIR1) / 4096.0f); + gteMAC2 = NC_OVERFLOW2(gteMAC2 + (gteIR0 * gteIR2) / 4096.0f); + gteMAC3 = NC_OVERFLOW3(gteMAC3 + (gteIR0 * gteIR3) / 4096.0f); + } else { + + gteMAC1 = NC_OVERFLOW1(gteMAC1 + (gteIR0 * gteIR1)); + gteMAC2 = NC_OVERFLOW2(gteMAC2 + (gteIR0 * gteIR2)); + gteMAC3 = NC_OVERFLOW3(gteMAC3 + (gteIR0 * gteIR3)); + } + MAC2IR(); + + gteRGB0 = gteRGB1; + gteRGB1 = gteRGB2; + + gteR2 = limB1(gteMAC1 / 16.0f); + gteG2 = limB2(gteMAC2 / 16.0f); + gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE; + + SUM_FLAG + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(9); + G_GD(10); + G_GD(11); + + //G_GD(20); + //G_GD(21); + G_GD(22); + + G_GD(25); + G_GD(26); + G_GD(27); + + G_GC(31); + } +#endif +} + +/* +#define GTE_DPCS() { \ + RR0 = (double)R + (gteIR0*LimitAS((double)(gteRFC - R),24))/4096.0; \ + GG0 = (double)G + (gteIR0*LimitAS((double)(gteGFC - G),23))/4096.0; \ + BB0 = (double)B + (gteIR0*LimitAS((double)(gteBFC - B),22))/4096.0; \ + \ + gteIR1 = (long)LimitAS(RR0,24); \ + gteIR2 = (long)LimitAS(GG0,23); \ + gteIR3 = (long)LimitAS(BB0,22); \ + \ + gteRGB0 = gteRGB1; \ + gteRGB1 = gteRGB2; \ + gteC2 = C; \ + gteR2 = (unsigned char)LimitB(RR0/16.0,21); \ + gteG2 = (unsigned char)LimitB(GG0/16.0,20); \ + gteB2 = (unsigned char)LimitB(BB0/16.0,19); \ + \ + gteMAC1 = (long)RR0; \ + gteMAC2 = (long)GG0; \ + gteMAC3 = (long)BB0; \ +} +*/ +void gteDPCS() { +// unsigned long C,R,G,B; +// double RR0,GG0,BB0; +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif +#ifdef GTE_LOG + GTE_LOG("GTE_DPCS\n"); +#endif + +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("DPCS", 8); + G_SD(6); + G_SD(8); + + G_SC(21); + G_SC(22); + G_SC(23); + } +#endif + +/* gteFLAG = 0; + + C = gteCODE; + R = gteR * 16.0; + G = gteG * 16.0; + B = gteB * 16.0; + + GTE_DPCS(); + + if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/ +/* gteFLAG = 0; + + gteMAC1 = NC_OVERFLOW1((gteR * 16.0f) + (gteIR0 * limA1S(gteRFC - (gteR * 16.0f))) / 4096.0f); + gteMAC2 = NC_OVERFLOW2((gteG * 16.0f) + (gteIR0 * limA2S(gteGFC - (gteG * 16.0f))) / 4096.0f); + gteMAC3 = NC_OVERFLOW3((gteB * 16.0f) + (gteIR0 * limA3S(gteBFC - (gteB * 16.0f))) / 4096.0f); + */ + gteMAC1 = (gteR<<4) + ( (gteIR0*(signed short)limA1S(gteRFC-(gteR<<4)) ) >>12); + gteMAC2 = (gteG<<4) + ( (gteIR0*(signed short)limA2S(gteGFC-(gteG<<4)) ) >>12); + gteMAC3 = (gteB<<4) + ( (gteIR0*(signed short)limA3S(gteBFC-(gteB<<4)) ) >>12); + + gteFLAG = 0; + MAC2IR(); + + gteRGB0 = gteRGB1; + gteRGB1 = gteRGB2; + + gteR2 = limB1(gteMAC1 / 16.0f); + gteG2 = limB2(gteMAC2 / 16.0f); + gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE; + + SUM_FLAG + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(9); + G_GD(10); + G_GD(11); + + //G_GD(20); + //G_GD(21); + G_GD(22); + + G_GD(25); + G_GD(26); + G_GD(27); + + G_GC(31); + } +#endif +} + +void gteDPCT() { +// unsigned long C,R,G,B; +// double RR0,GG0,BB0; +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif +#ifdef GTE_LOG + GTE_LOG("GTE_DPCT\n"); +#endif + +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("DPCT", 17); + G_SD(8); + + G_SD(20); + G_SD(21); + G_SD(22); + + G_SC(21); + G_SC(22); + G_SC(23); + } +#endif +/* gteFLAG = 0; + + C = gteCODE0; + R = gteR0 * 16.0; + G = gteG0 * 16.0; + B = gteB0 * 16.0; + + GTE_DPCS(); + + C = gteCODE0; + R = gteR0 * 16.0; + G = gteG0 * 16.0; + B = gteB0 * 16.0; + + GTE_DPCS(); + + C = gteCODE0; + R = gteR0 * 16.0; + G = gteG0 * 16.0; + B = gteB0 * 16.0; + + GTE_DPCS(); + + if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/ +/* gteFLAG = 0; + + gteMAC1 = NC_OVERFLOW1((gteR0 * 16.0f) + gteIR0 * limA1S(gteRFC - (gteR0 * 16.0f))); + gteMAC2 = NC_OVERFLOW2((gteG0 * 16.0f) + gteIR0 * limA2S(gteGFC - (gteG0 * 16.0f))); + gteMAC3 = NC_OVERFLOW3((gteB0 * 16.0f) + gteIR0 * limA3S(gteBFC - (gteB0 * 16.0f))); + */ + gteMAC1 = (gteR0<<4) + ( (gteIR0*(signed short)limA1S(gteRFC-(gteR0<<4)) ) >>12); + gteMAC2 = (gteG0<<4) + ( (gteIR0*(signed short)limA2S(gteGFC-(gteG0<<4)) ) >>12); + gteMAC3 = (gteB0<<4) + ( (gteIR0*(signed short)limA3S(gteBFC-(gteB0<<4)) ) >>12); +// MAC2IR(); + + gteRGB0 = gteRGB1; + gteRGB1 = gteRGB2; + + gteR2 = limB1(gteMAC1 / 16.0f); + gteG2 = limB2(gteMAC2 / 16.0f); + gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE; + + gteMAC1 = (gteR0<<4) + ( (gteIR0*(signed short)limA1S(gteRFC-(gteR0<<4)) ) >>12); + gteMAC2 = (gteG0<<4) + ( (gteIR0*(signed short)limA2S(gteGFC-(gteG0<<4)) ) >>12); + gteMAC3 = (gteB0<<4) + ( (gteIR0*(signed short)limA3S(gteBFC-(gteB0<<4)) ) >>12); +// MAC2IR(); + gteRGB0 = gteRGB1; + gteRGB1 = gteRGB2; + + gteR2 = limB1(gteMAC1 / 16.0f); + gteG2 = limB2(gteMAC2 / 16.0f); + gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE; + + gteMAC1 = (gteR0<<4) + ( (gteIR0*(signed short)limA1S(gteRFC-(gteR0<<4)) ) >>12); + gteMAC2 = (gteG0<<4) + ( (gteIR0*(signed short)limA2S(gteGFC-(gteG0<<4)) ) >>12); + gteMAC3 = (gteB0<<4) + ( (gteIR0*(signed short)limA3S(gteBFC-(gteB0<<4)) ) >>12); + gteFLAG = 0; + MAC2IR(); + gteRGB0 = gteRGB1; + gteRGB1 = gteRGB2; + + gteR2 = limB1(gteMAC1 / 16.0f); + gteG2 = limB2(gteMAC2 / 16.0f); + gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE; + + SUM_FLAG + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(9); + G_GD(10); + G_GD(11); + + G_GD(20); + G_GD(21); + G_GD(22); + + G_GD(25); + G_GD(26); + G_GD(27); + + G_GC(31); + } +#endif +} + +/* +#define GTE_NCS(vn) { \ + RR0 = ((double)gteVX##vn * gteL11 + (double)gteVY##vn * (double)gteL12 + (double)gteVZ##vn * gteL13) / 4096.0; \ + GG0 = ((double)gteVX##vn * gteL21 + (double)gteVY##vn * (double)gteL22 + (double)gteVZ##vn * gteL23) / 4096.0; \ + BB0 = ((double)gteVX##vn * gteL31 + (double)gteVY##vn * (double)gteL32 + (double)gteVZ##vn * gteL33) / 4096.0; \ + t1 = LimitAU(RR0, 24); \ + t2 = LimitAU(GG0, 23); \ + t3 = LimitAU(BB0, 22); \ + \ + RR0 = (double)gteRBK + ((double)gteLR1 * t1 + (double)gteLR2 * t2 + (double)gteLR3 * t3) / 4096.0; \ + GG0 = (double)gteGBK + ((double)gteLG1 * t1 + (double)gteLG2 * t2 + (double)gteLG3 * t3) / 4096.0; \ + BB0 = (double)gteBBK + ((double)gteLB1 * t1 + (double)gteLB2 * t2 + (double)gteLB3 * t3) / 4096.0; \ + t1 = LimitAU(RR0, 24); \ + t2 = LimitAU(GG0, 23); \ + t3 = LimitAU(BB0, 22); \ + \ + gteRGB0 = gteRGB1; gteRGB1 = gteRGB2; \ + gteR2 = (unsigned char)LimitB(RR0/16.0, 21); \ + gteG2 = (unsigned char)LimitB(GG0/16.0, 20); \ + gteB2 = (unsigned char)LimitB(BB0/16.0, 19); \ + gteCODE2=gteCODE0; \ +}*/ + +#define LOW(a) (((a) < 0) ? 0 : (a)) + +#define GTE_NCS(vn) \ +RR0 = LOW((gteL11*gteVX##vn + gteL12*gteVY##vn + gteL13*gteVZ##vn)/4096.0f); \ +GG0 = LOW((gteL21*gteVX##vn + gteL22*gteVY##vn + gteL23*gteVZ##vn)/4096.0f); \ +BB0 = LOW((gteL31*gteVX##vn + gteL32*gteVY##vn + gteL33*gteVZ##vn)/4096.0f); \ +gteMAC1 = gteRBK + (gteLR1*RR0 + gteLR2*GG0 + gteLR3*BB0)/4096.0f; \ +gteMAC2 = gteGBK + (gteLG1*RR0 + gteLG2*GG0 + gteLG3*BB0)/4096.0f; \ +gteMAC3 = gteBBK + (gteLB1*RR0 + gteLB2*GG0 + gteLB3*BB0)/4096.0f; \ +gteRGB0 = gteRGB1; \ +gteRGB1 = gteRGB2; \ +gteR2 = limB1(gteMAC1 / 16.0f); \ +gteG2 = limB2(gteMAC2 / 16.0f); \ +gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE; + +void gteNCS() { + double RR0,GG0,BB0; +// double t1, t2, t3; +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif +#ifdef GTE_LOG + GTE_LOG("GTE_NCS\n"); +#endif + +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("NCS", 14); + G_SD(0); + G_SD(1); + G_SD(6); + + G_SC(8); + G_SC(9); + G_SC(10); + G_SC(11); + G_SC(12); + G_SC(13); + G_SC(14); + G_SC(15); + G_SC(16); + G_SC(17); + G_SC(18); + G_SC(19); + G_SC(20); + } +#endif +/* gteFLAG = 0; + + GTE_NCS(0); + + gteMAC1=(long)RR0; + gteMAC2=(long)GG0; + gteMAC3=(long)BB0; + + gteIR1=(long)t1; + gteIR2=(long)t2; + gteIR3=(long)t3; + + if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/ + gteFLAG = 0; + + GTE_NCS(0); + + MAC2IR1(); + + SUM_FLAG + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(9); + G_GD(10); + G_GD(11); + + //G_GD(20); + //G_GD(21); + G_GD(22); + + G_GD(25); + G_GD(26); + G_GD(27); + + G_GC(31); + } +#endif +} + +void gteNCT() { + double RR0,GG0,BB0; +// double t1, t2, t3; +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif +#ifdef GTE_LOG + GTE_LOG("GTE_NCT\n"); +#endif + +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("NCT", 30); + G_SD(0); + G_SD(1); + G_SD(2); + G_SD(3); + G_SD(4); + G_SD(5); + G_SD(6); + + G_SC(8); + G_SC(9); + G_SC(10); + G_SC(11); + G_SC(12); + G_SC(13); + G_SC(14); + G_SC(15); + G_SC(16); + G_SC(17); + G_SC(18); + G_SC(19); + G_SC(20); + } +#endif +/* + gteFLAG = 0; + +//V0 + GTE_NCS(0); +//V1 + GTE_NCS(1); +//V2 + GTE_NCS(2); + + gteMAC1=(long)RR0; + gteMAC2=(long)GG0; + gteMAC3=(long)BB0; + + gteIR1=(long)t1; + gteIR2=(long)t2; + gteIR3=(long)t3; + + if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/ + gteFLAG = 0; + + GTE_NCS(0); + GTE_NCS(1); + GTE_NCS(2); + + MAC2IR1(); + + SUM_FLAG + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(9); + G_GD(10); + G_GD(11); + + G_GD(20); + G_GD(21); + G_GD(22); + + G_GD(25); + G_GD(26); + G_GD(27); + + G_GC(31); + } +#endif +} + +void gteCC() { + double RR0,GG0,BB0; +// double t1,t2,t3; +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif +#ifdef GTE_LOG + GTE_LOG("GTE_CC\n"); +#endif + +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("CC", 11); + G_SD(6); + G_SD(9); + G_SD(10); + G_SD(11); + + G_SC(13); + G_SC(14); + G_SC(15); + G_SC(16); + G_SC(17); + G_SC(18); + G_SC(19); + } +#endif +/* gteFLAG = 0; + + RR0 = (double)gteRBK + ((double)gteLR1 * gteIR1 + (double)gteLR2 * gteIR2 + (double)gteLR3 * gteIR3) / 4096.0; + GG0 = (double)gteGBK + ((double)gteLG1 * gteIR1 + (double)gteLG2 * gteIR2 + (double)gteLG3 * gteIR3) / 4096.0; + BB0 = (double)gteBBK + ((double)gteLB1 * gteIR1 + (double)gteLB2 * gteIR2 + (double)gteLB3 * gteIR3) / 4096.0; + t1 = LimitAU(RR0, 24); + t2 = LimitAU(GG0, 23); + t3 = LimitAU(BB0, 22); + + RR0=((double)gteR * t1)/256.0; + GG0=((double)gteG * t2)/256.0; + BB0=((double)gteB * t3)/256.0; + gteIR1 = (long)LimitAU(RR0,24); + gteIR2 = (long)LimitAU(GG0,23); + gteIR3 = (long)LimitAU(BB0,22); + + gteCODE0=gteCODE1; gteCODE1=gteCODE2; + gteC2 = gteCODE0; + gteR2 = (unsigned char)LimitB(RR0/16.0, 21); + gteG2 = (unsigned char)LimitB(GG0/16.0, 20); + gteB2 = (unsigned char)LimitB(BB0/16.0, 19); + + if (gteFLAG & 0x7f87e000) gteFLAG|=0x80000000;*/ + gteFLAG = 0; + + RR0 = NC_OVERFLOW1(gteRBK + (gteLR1*gteIR1 + gteLR2*gteIR2 + gteLR3*gteIR3) / 4096.0f); + GG0 = NC_OVERFLOW2(gteGBK + (gteLG1*gteIR1 + gteLG2*gteIR2 + gteLG3*gteIR3) / 4096.0f); + BB0 = NC_OVERFLOW3(gteBBK + (gteLB1*gteIR1 + gteLB2*gteIR2 + gteLB3*gteIR3) / 4096.0f); + + gteMAC1 = gteR * RR0 / 256.0f; + gteMAC2 = gteG * GG0 / 256.0f; + gteMAC3 = gteB * BB0 / 256.0f; + + MAC2IR1(); + + gteRGB0 = gteRGB1; + gteRGB1 = gteRGB2; + + gteR2 = limB1(gteMAC1 / 16.0f); + gteG2 = limB2(gteMAC2 / 16.0f); + gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE; + + SUM_FLAG + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(9); + G_GD(10); + G_GD(11); + + //G_GD(20); + //G_GD(21); + G_GD(22); + + G_GD(25); + G_GD(26); + G_GD(27); + + G_GC(31); + } +#endif +} + +void gteINTPL() { //test opcode +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif +#ifdef GTE_LOG + GTE_LOG("GTE_INTP\n"); +#endif + +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("INTPL", 8); + G_SD(6); + G_SD(8); + G_SD(9); + G_SD(10); + G_SD(11); + + G_SC(21); + G_SC(22); + G_SC(23); + } +#endif + /* NC: old + gteFLAG=0; + gteMAC1 = gteIR1 + gteIR0*limA1S(gteRFC-gteIR1); + gteMAC2 = gteIR2 + gteIR0*limA2S(gteGFC-gteIR2); + gteMAC3 = gteIR3 + gteIR0*limA3S(gteBFC-gteIR3); + //gteFLAG = 0; + MAC2IR(); + gteRGB0 = gteRGB1; + gteRGB1 = gteRGB2; + + gteR2 = limB1(gteMAC1 / 16.0f); + gteG2 = limB2(gteMAC2 / 16.0f); + gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE; + */ + +/* gteFLAG=0; + gteMAC1 = gteIR1 + gteIR0*(gteRFC-gteIR1)/4096.0; + gteMAC2 = gteIR2 + gteIR0*(gteGFC-gteIR2)/4096.0; + gteMAC3 = gteIR3 + gteIR0*(gteBFC-gteIR3)/4096.0; + + //gteMAC3 = (int)((((psxRegs).CP2D).n).ir3+(((psxRegs).CP2D).n).ir0 * ((((psxRegs).CP2C).n).bfc-(((psxRegs).CP2D).n).ir3)/4096.0); + + if(gteMAC3 > gteIR1 && gteMAC3 > gteBFC) + { + gteMAC3 = gteMAC3; + } + //gteFLAG = 0;*/ + //NEW CODE + gteMAC1 = gteIR1 + ((gteIR0*(signed short)limA1S(gteRFC-gteIR1))>>12); + gteMAC2 = gteIR2 + ((gteIR0*(signed short)limA2S(gteGFC-gteIR2))>>12); + gteMAC3 = gteIR3 + ((gteIR0*(signed short)limA3S(gteBFC-gteIR3))>>12); + gteFLAG = 0; + + MAC2IR(); + gteRGB0 = gteRGB1; + gteRGB1 = gteRGB2; + + gteR2 = limB1(gteMAC1 / 16.0f); + gteG2 = limB2(gteMAC2 / 16.0f); + gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE; + + SUM_FLAG + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(9); + G_GD(10); + G_GD(11); + + //G_GD(20); + //G_GD(21); + G_GD(22); + + G_GD(25); + G_GD(26); + G_GD(27); + + G_GC(31); + } +#endif +} + +void gteCDP() { //test opcode + double RR0,GG0,BB0; +#ifdef GTE_DUMP + static int sample = 0; sample++; +#endif +#ifdef GTE_LOG + GTE_LOG("GTE_CDP\n"); +#endif + +#ifdef GTE_DUMP + if(sample < 100) + { + G_OP("CDP", 13); + G_SD(6); + G_SD(8); + G_SD(9); + G_SD(10); + G_SD(11); + + G_SC(13); + G_SC(14); + G_SC(15); + G_SC(16); + G_SC(17); + G_SC(18); + G_SC(19); + G_SC(20); + G_SC(21); + G_SC(22); + G_SC(23); + } +#endif + + gteFLAG = 0; + + RR0 = NC_OVERFLOW1(gteRBK + (gteLR1*gteIR1 +gteLR2*gteIR2 + gteLR3*gteIR3)); + GG0 = NC_OVERFLOW2(gteGBK + (gteLG1*gteIR1 +gteLG2*gteIR2 + gteLG3*gteIR3)); + BB0 = NC_OVERFLOW3(gteBBK + (gteLB1*gteIR1 +gteLB2*gteIR2 + gteLB3*gteIR3)); + gteMAC1 = gteR*RR0 + gteIR0*limA1S(gteRFC-gteR*RR0); + gteMAC2 = gteG*GG0 + gteIR0*limA2S(gteGFC-gteG*GG0); + gteMAC3 = gteB*BB0 + gteIR0*limA3S(gteBFC-gteB*BB0); + MAC2IR1(); + gteRGB0 = gteRGB1; + gteRGB1 = gteRGB2; + + gteR2 = limB1(gteMAC1 / 16.0f); + gteG2 = limB2(gteMAC2 / 16.0f); + gteB2 = limB3(gteMAC3 / 16.0f); gteCODE2 = gteCODE; + + SUM_FLAG + +#ifdef GTE_DUMP + if(sample < 100) + { + G_GD(9); + G_GD(10); + G_GD(11); + + //G_GD(20); + //G_GD(21); + G_GD(22); + + G_GD(25); + G_GD(26); + G_GD(27); + + G_GC(31); + } +#endif +} diff --git a/PcsxSrc/Gte.h b/PcsxSrc/Gte.h new file mode 100644 index 0000000..146dbd0 --- /dev/null +++ b/PcsxSrc/Gte.h @@ -0,0 +1,52 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __GTE_H__ +#define __GTE_H__ + +void gteMFC2(); +void gteCFC2(); +void gteMTC2(); +void gteCTC2(); +void gteLWC2(); +void gteSWC2(); + +void gteRTPS(); +void gteOP(); +void gteNCLIP(); +void gteDPCS(); +void gteINTPL(); +void gteMVMVA(); +void gteNCDS(); +void gteNCDT(); +void gteCDP(); +void gteNCCS(); +void gteCC(); +void gteNCS(); +void gteNCT(); +void gteSQR(); +void gteDCPL(); +void gteDPCT(); +void gteAVSZ3(); +void gteAVSZ4(); +void gteRTPT(); +void gteGPF(); +void gteGPL(); +void gteNCCT(); + +#endif /* __GTE_H__ */ diff --git a/PcsxSrc/Linux/Config.c b/PcsxSrc/Linux/Config.c new file mode 100644 index 0000000..be8cfb3 --- /dev/null +++ b/PcsxSrc/Linux/Config.c @@ -0,0 +1,125 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +#include "Linux.h" + +#define GetValue(name, var) \ + tmp = strstr(data, name); \ + if (tmp != NULL) { \ + tmp+=strlen(name); \ + while ((*tmp == ' ') || (*tmp == '=')) tmp++; \ + if (*tmp != '\n') sscanf(tmp, "%s", var); \ + } + +#define GetValuel(name, var) \ + tmp = strstr(data, name); \ + if (tmp != NULL) { \ + tmp+=strlen(name); \ + while ((*tmp == ' ') || (*tmp == '=')) tmp++; \ + if (*tmp != '\n') sscanf(tmp, "%lx", &var); \ + } + +#define SetValue(name, var) \ + fprintf (f,"%s = %s\n", name, var); + +#define SetValuel(name, var) \ + fprintf (f,"%s = %lx\n", name, var); + +int LoadConfig(PcsxConfig *Conf) { + struct stat buf; + FILE *f; + int size; + char *data,*tmp; + + if (stat(cfgfile, &buf) == -1) return -1; + size = buf.st_size; + + f = fopen(cfgfile,"r"); + if (f == NULL) return -1; + + data = (char*)malloc(size); + if (data == NULL) return -1; + + fread(data, 1, size, f); + fclose(f); + + GetValue("Bios", Config.Bios); + GetValue("Gpu", Config.Gpu); + GetValue("Spu", Config.Spu); + GetValue("Cdr", Config.Cdr); + GetValue("Pad1", Config.Pad1); + GetValue("Pad2", Config.Pad2); + GetValue("Mcd1", Config.Mcd1); + GetValue("Mcd2", Config.Mcd2); + GetValue("PluginsDir", Config.PluginsDir); + GetValue("BiosDir", Config.BiosDir); + GetValuel("Xa", Config.Xa); + GetValuel("Sio", Config.Sio); + GetValuel("Mdec", Config.Mdec); + GetValuel("PsxAuto", Config.PsxAuto); + GetValuel("PsxType", Config.PsxType); + GetValuel("Cdda", Config.Cdda); + GetValuel("Cpu", Config.Cpu); + GetValuel("PsxOut", Config.PsxOut); + GetValuel("SpuIrq", Config.SpuIrq); + GetValuel("CdTiming",Config.CdTiming); + + free(data); + + return 0; +} + +///////////////////////////////////////////////////////// + +void SaveConfig() { + FILE *f; + + f = fopen(cfgfile,"w"); + if (f == NULL) return; + + SetValue("Bios", Config.Bios); + SetValue("Gpu", Config.Gpu); + SetValue("Spu", Config.Spu); + SetValue("Cdr", Config.Cdr); + SetValue("Pad1", Config.Pad1); + SetValue("Pad2", Config.Pad2); + SetValue("Mcd1", Config.Mcd1); + SetValue("Mcd2", Config.Mcd2); + SetValue("PluginsDir", Config.PluginsDir); + SetValue("BiosDir", Config.BiosDir); + SetValuel("Xa", Config.Xa); + SetValuel("Sio", Config.Sio); + SetValuel("Mdec", Config.Mdec); + SetValuel("PsxAuto", Config.PsxAuto); + SetValuel("PsxType", Config.PsxType); + SetValuel("Cdda", Config.Cdda); + SetValuel("Cpu", Config.Cpu); + SetValuel("PsxOut", Config.PsxOut); + SetValuel("SpuIrq", Config.SpuIrq); + SetValuel("CdTiming",Config.CdTiming); + + fclose(f); + + return; +} diff --git a/PcsxSrc/Linux/GladeCalls.c b/PcsxSrc/Linux/GladeCalls.c new file mode 100644 index 0000000..5b52857 --- /dev/null +++ b/PcsxSrc/Linux/GladeCalls.c @@ -0,0 +1,477 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "GladeCalls.h" +#include "GladeGui.h" +#include "GladeFuncs.h" + + +void +OnDestroy (GtkObject *object, + gpointer user_data) +{ + +} + + +void +OnFile_RunCd (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +OnFile_RunCdBios (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +OnFile_RunExe (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +OnFile_Exit (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +OnEmu_Run (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +OnEmu_Reset (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +OnConf_Conf (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +OnConf_Gpu (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +OnConf_Spu (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +OnConf_Cdr (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +OnConf_Pads (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +OnConf_Cpu (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +OnConf_Mcds (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +OnHelp_About (GtkMenuItem *menuitem, + gpointer user_data) +{ + +} + + +void +OnHelpAbout_Ok (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConfConf_CdrConf (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConfConf_CdrTest (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConfConf_CdrAbout (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConfConf_Pad2Conf (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConfConf_Pad2Test (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConfConf_Pad2About (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConfConf_Pad1Conf (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConfConf_Pad1Test (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConfConf_Pad1About (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConfConf_GpuConf (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConfConf_GpuTest (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConfConf_GpuAbout (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConfConf_SpuConf (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConfConf_SpuTest (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConfConf_SpuAbout (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConfConf_PluginsPath (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConfConf_BiosPath (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConfConf_Ok (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnConfConf_Cancel (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnCpu_Ok (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnCpu_Cancel (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnMcd_FS1 (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnMcd_Format1 (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnMcd_Reload1 (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnMcd_FS2 (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnMcd_Format2 (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnMcd_Reload2 (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnMcd_Ok (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnMcd_Cancel (GtkButton *button, + gpointer user_data) +{ + +} + + +gboolean +OnList1_KeyPress (GtkWidget *widget, + GdkEventKey *event, + gpointer user_data) +{ + + return FALSE; +} + + +gboolean +OnList2_KeyPress (GtkWidget *widget, + GdkEventKey *event, + gpointer user_data) +{ + + return FALSE; +} + + +void +OnMcd_Copy (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnMcd_Paste (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnMcd_Delete (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnMcd_CopyTo2 (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnMcd_CopyTo1 (GtkButton *button, + gpointer user_data) +{ + +} + + +GtkDirectionType +OnList1_Focus (GtkContainer *container, + GtkDirectionType direction, + gpointer user_data) +{ + +} + + +void +OnList1_SelectRow (GtkCList *clist, + gint row, + gint column, + GdkEvent *event, + gpointer user_data) +{ + +} + + +void +OnList2_SelectRow (GtkCList *clist, + gint row, + gint column, + GdkEvent *event, + gpointer user_data) +{ + +} + + +void +OnMcd_Delete2 (GtkButton *button, + gpointer user_data) +{ + +} + + +void +OnMcd_Delete1 (GtkButton *button, + gpointer user_data) +{ + +} + diff --git a/PcsxSrc/Linux/GladeCalls.h b/PcsxSrc/Linux/GladeCalls.h new file mode 100644 index 0000000..9e81a10 --- /dev/null +++ b/PcsxSrc/Linux/GladeCalls.h @@ -0,0 +1,239 @@ +#include + + +void +OnDestroy (GtkObject *object, + gpointer user_data); + +void +OnFile_RunCd (GtkMenuItem *menuitem, + gpointer user_data); + +void +OnFile_RunCdBios (GtkMenuItem *menuitem, + gpointer user_data); + +void +OnFile_RunExe (GtkMenuItem *menuitem, + gpointer user_data); + +void +OnFile_Exit (GtkMenuItem *menuitem, + gpointer user_data); + +void +OnEmu_Run (GtkMenuItem *menuitem, + gpointer user_data); + +void +OnEmu_Reset (GtkMenuItem *menuitem, + gpointer user_data); + +void +OnConf_Conf (GtkMenuItem *menuitem, + gpointer user_data); + +void +OnConf_Gpu (GtkMenuItem *menuitem, + gpointer user_data); + +void +OnConf_Spu (GtkMenuItem *menuitem, + gpointer user_data); + +void +OnConf_Cdr (GtkMenuItem *menuitem, + gpointer user_data); + +void +OnConf_Pads (GtkMenuItem *menuitem, + gpointer user_data); + +void +OnConf_Cpu (GtkMenuItem *menuitem, + gpointer user_data); + +void +OnConf_Mcds (GtkMenuItem *menuitem, + gpointer user_data); + +void +OnHelp_About (GtkMenuItem *menuitem, + gpointer user_data); + +void +OnHelpAbout_Ok (GtkButton *button, + gpointer user_data); + +void +OnConfConf_CdrConf (GtkButton *button, + gpointer user_data); + +void +OnConfConf_CdrTest (GtkButton *button, + gpointer user_data); + +void +OnConfConf_CdrAbout (GtkButton *button, + gpointer user_data); + +void +OnConfConf_Pad2Conf (GtkButton *button, + gpointer user_data); + +void +OnConfConf_Pad2Test (GtkButton *button, + gpointer user_data); + +void +OnConfConf_Pad2About (GtkButton *button, + gpointer user_data); + +void +OnConfConf_Pad1Conf (GtkButton *button, + gpointer user_data); + +void +OnConfConf_Pad1Test (GtkButton *button, + gpointer user_data); + +void +OnConfConf_Pad1About (GtkButton *button, + gpointer user_data); + +void +OnConfConf_GpuConf (GtkButton *button, + gpointer user_data); + +void +OnConfConf_GpuTest (GtkButton *button, + gpointer user_data); + +void +OnConfConf_GpuAbout (GtkButton *button, + gpointer user_data); + +void +OnConfConf_SpuConf (GtkButton *button, + gpointer user_data); + +void +OnConfConf_SpuTest (GtkButton *button, + gpointer user_data); + +void +OnConfConf_SpuAbout (GtkButton *button, + gpointer user_data); + +void +OnConfConf_PluginsPath (GtkButton *button, + gpointer user_data); + +void +OnConfConf_BiosPath (GtkButton *button, + gpointer user_data); + +void +OnConfConf_Ok (GtkButton *button, + gpointer user_data); + +void +OnConfConf_Cancel (GtkButton *button, + gpointer user_data); + +void +OnCpu_Ok (GtkButton *button, + gpointer user_data); + +void +OnCpu_Cancel (GtkButton *button, + gpointer user_data); + +void +OnMcd_FS1 (GtkButton *button, + gpointer user_data); + +void +OnMcd_Format1 (GtkButton *button, + gpointer user_data); + +void +OnMcd_Reload1 (GtkButton *button, + gpointer user_data); + +void +OnMcd_FS2 (GtkButton *button, + gpointer user_data); + +void +OnMcd_Format2 (GtkButton *button, + gpointer user_data); + +void +OnMcd_Reload2 (GtkButton *button, + gpointer user_data); + +void +OnMcd_Ok (GtkButton *button, + gpointer user_data); + +void +OnMcd_Cancel (GtkButton *button, + gpointer user_data); + +gboolean +OnList1_KeyPress (GtkWidget *widget, + GdkEventKey *event, + gpointer user_data); + +gboolean +OnList2_KeyPress (GtkWidget *widget, + GdkEventKey *event, + gpointer user_data); + +void +OnMcd_Copy (GtkButton *button, + gpointer user_data); + +void +OnMcd_Paste (GtkButton *button, + gpointer user_data); + +void +OnMcd_Delete (GtkButton *button, + gpointer user_data); + +void +OnMcd_CopyTo2 (GtkButton *button, + gpointer user_data); + +void +OnMcd_CopyTo1 (GtkButton *button, + gpointer user_data); + +GtkDirectionType +OnList1_Focus (GtkContainer *container, + GtkDirectionType direction, + gpointer user_data); + +void +OnList1_SelectRow (GtkCList *clist, + gint row, + gint column, + GdkEvent *event, + gpointer user_data); + +void +OnList2_SelectRow (GtkCList *clist, + gint row, + gint column, + GdkEvent *event, + gpointer user_data); + +void +OnMcd_Delete2 (GtkButton *button, + gpointer user_data); + +void +OnMcd_Delete1 (GtkButton *button, + gpointer user_data); diff --git a/PcsxSrc/Linux/GladeFuncs.c b/PcsxSrc/Linux/GladeFuncs.c new file mode 100644 index 0000000..47dbfc3 --- /dev/null +++ b/PcsxSrc/Linux/GladeFuncs.c @@ -0,0 +1,162 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include + +#include "GladeFuncs.h" + +/* This is an internally used function to check if a pixmap file exists. */ +static gchar* check_file_exists (const gchar *directory, + const gchar *filename); + +/* This is an internally used function to create pixmaps. */ +static GtkWidget* create_dummy_pixmap (GtkWidget *widget); + +GtkWidget* +lookup_widget (GtkWidget *widget, + const gchar *widget_name) +{ + GtkWidget *parent, *found_widget; + + for (;;) + { + if (GTK_IS_MENU (widget)) + parent = gtk_menu_get_attach_widget (GTK_MENU (widget)); + else + parent = widget->parent; + if (parent == NULL) + break; + widget = parent; + } + + found_widget = (GtkWidget*) gtk_object_get_data (GTK_OBJECT (widget), + widget_name); + if (!found_widget) + g_warning ("Widget not found: %s", widget_name); + return found_widget; +} + +/* This is a dummy pixmap we use when a pixmap can't be found. */ +static char *dummy_pixmap_xpm[] = { +/* columns rows colors chars-per-pixel */ +"1 1 1 1", +" c None", +/* pixels */ +" " +}; + +/* This is an internally used function to create pixmaps. */ +static GtkWidget* +create_dummy_pixmap (GtkWidget *widget) +{ + GdkColormap *colormap; + GdkPixmap *gdkpixmap; + GdkBitmap *mask; + GtkWidget *pixmap; + + colormap = gtk_widget_get_colormap (widget); + gdkpixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &mask, + NULL, dummy_pixmap_xpm); + if (gdkpixmap == NULL) + g_error ("Couldn't create replacement pixmap."); + pixmap = gtk_pixmap_new (gdkpixmap, mask); + gdk_pixmap_unref (gdkpixmap); + gdk_bitmap_unref (mask); + return pixmap; +} + +static GList *pixmaps_directories = NULL; + +/* Use this function to set the directory containing installed pixmaps. */ +void +add_pixmap_directory (const gchar *directory) +{ + pixmaps_directories = g_list_prepend (pixmaps_directories, + g_strdup (directory)); +} + +/* This is an internally used function to create pixmaps. */ +GtkWidget* +create_pixmap (GtkWidget *widget, + const gchar *filename) +{ + gchar *found_filename = NULL; + GdkColormap *colormap; + GdkPixmap *gdkpixmap; + GdkBitmap *mask; + GtkWidget *pixmap; + GList *elem; + + if (!filename || !filename[0]) + return create_dummy_pixmap (widget); + + /* We first try any pixmaps directories set by the application. */ + elem = pixmaps_directories; + while (elem) + { + found_filename = check_file_exists ((gchar*)elem->data, filename); + if (found_filename) + break; + elem = elem->next; + } + + /* If we haven't found the pixmap, try the source directory. */ + if (!found_filename) + { + found_filename = check_file_exists (".pixmaps", filename); + } + + if (!found_filename) + { + g_warning ("Couldn't find pixmap file: %s", filename); + return create_dummy_pixmap (widget); + } + + colormap = gtk_widget_get_colormap (widget); + gdkpixmap = gdk_pixmap_colormap_create_from_xpm (NULL, colormap, &mask, + NULL, found_filename); + if (gdkpixmap == NULL) + { + g_warning ("Error loading pixmap file: %s", found_filename); + g_free (found_filename); + return create_dummy_pixmap (widget); + } + g_free (found_filename); + pixmap = gtk_pixmap_new (gdkpixmap, mask); + gdk_pixmap_unref (gdkpixmap); + gdk_bitmap_unref (mask); + return pixmap; +} + +/* This is an internally used function to check if a pixmap file exists. */ +gchar* +check_file_exists (const gchar *directory, + const gchar *filename) +{ + gchar *full_filename; + struct stat s; + gint status; + + full_filename = (gchar*) g_malloc (strlen (directory) + 1 + + strlen (filename) + 1); + strcpy (full_filename, directory); + strcat (full_filename, G_DIR_SEPARATOR_S); + strcat (full_filename, filename); + + status = stat (full_filename, &s); + if (status == 0 && S_ISREG (s.st_mode)) + return full_filename; + g_free (full_filename); + return NULL; +} + diff --git a/PcsxSrc/Linux/GladeFuncs.h b/PcsxSrc/Linux/GladeFuncs.h new file mode 100644 index 0000000..8866159 --- /dev/null +++ b/PcsxSrc/Linux/GladeFuncs.h @@ -0,0 +1,38 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +/* + * Public Functions. + */ + +/* + * This function returns a widget in a component created by Glade. + * Call it with the toplevel widget in the component (i.e. a window/dialog), + * or alternatively any widget in the component, and the name of the widget + * you want returned. + */ +GtkWidget* lookup_widget (GtkWidget *widget, + const gchar *widget_name); + +/* get_widget() is deprecated. Use lookup_widget instead. */ +#define get_widget lookup_widget + +/* Use this function to set the directory containing installed pixmaps. */ +void add_pixmap_directory (const gchar *directory); + + +/* + * Private Functions. + */ + +/* This is used to create the pixmaps in the interface. */ +GtkWidget* create_pixmap (GtkWidget *widget, + const gchar *filename); + diff --git a/PcsxSrc/Linux/GladeGui.c b/PcsxSrc/Linux/GladeGui.c new file mode 100644 index 0000000..af4b26e --- /dev/null +++ b/PcsxSrc/Linux/GladeGui.c @@ -0,0 +1,1562 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#include +#include + +#include "GladeCalls.h" +#include "GladeGui.h" +#include "GladeFuncs.h" + +GtkWidget* +create_MainWindow (void) +{ + GtkWidget *MainWindow; + GtkWidget *vbox1; + GtkWidget *menubar1; + GtkWidget *item1; + GtkWidget *item1_menu; + GtkAccelGroup *item1_menu_accels; + GtkWidget *RunCd; + GtkWidget *RunCdBiois; + GtkWidget *Run_Exe; + GtkWidget *separator2; + GtkWidget *exit2; + GtkWidget *emulator1; + GtkWidget *emulator1_menu; + GtkAccelGroup *emulator1_menu_accels; + GtkWidget *run1; + GtkWidget *reset1; + GtkWidget *configuration1; + GtkWidget *configuration1_menu; + GtkAccelGroup *configuration1_menu_accels; + GtkWidget *plugins___bios1; + GtkWidget *separator3; + GtkWidget *graphics1; + GtkWidget *sound1; + GtkWidget *cd_rom1; + GtkWidget *controllers1; + GtkWidget *separator4; + GtkWidget *cpu1; + GtkWidget *memory_cards1; + GtkWidget *help1; + GtkWidget *help1_menu; + GtkAccelGroup *help1_menu_accels; + GtkWidget *about_pcsx1; + + MainWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_object_set_data (GTK_OBJECT (MainWindow), "MainWindow", MainWindow); + gtk_widget_set_usize (MainWindow, 350, 200); + gtk_window_set_title (GTK_WINDOW (MainWindow), "PCSX"); + gtk_window_set_position (GTK_WINDOW (MainWindow), GTK_WIN_POS_CENTER); + gtk_window_set_policy (GTK_WINDOW (MainWindow), FALSE, FALSE, FALSE); + + vbox1 = gtk_vbox_new (FALSE, 0); + gtk_widget_ref (vbox1); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "vbox1", vbox1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (vbox1); + gtk_container_add (GTK_CONTAINER (MainWindow), vbox1); + + menubar1 = gtk_menu_bar_new (); + gtk_widget_ref (menubar1); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "menubar1", menubar1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (menubar1); + gtk_box_pack_start (GTK_BOX (vbox1), menubar1, FALSE, FALSE, 0); + + item1 = gtk_menu_item_new_with_label ("File"); + gtk_widget_ref (item1); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "item1", item1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (item1); + gtk_container_add (GTK_CONTAINER (menubar1), item1); + + item1_menu = gtk_menu_new (); + gtk_widget_ref (item1_menu); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "item1_menu", item1_menu, + (GtkDestroyNotify) gtk_widget_unref); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item1), item1_menu); + item1_menu_accels = gtk_menu_ensure_uline_accel_group (GTK_MENU (item1_menu)); + + RunCd = gtk_menu_item_new_with_label ("Run Cd"); + gtk_widget_ref (RunCd); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "RunCd", RunCd, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (RunCd); + gtk_container_add (GTK_CONTAINER (item1_menu), RunCd); + + RunCdBiois = gtk_menu_item_new_with_label ("Run Cd Through Bios"); + gtk_widget_ref (RunCdBiois); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "RunCdBiois", RunCdBiois, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (RunCdBiois); + gtk_container_add (GTK_CONTAINER (item1_menu), RunCdBiois); + + Run_Exe = gtk_menu_item_new_with_label ("Run Exe"); + gtk_widget_ref (Run_Exe); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "Run_Exe", Run_Exe, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (Run_Exe); + gtk_container_add (GTK_CONTAINER (item1_menu), Run_Exe); + + separator2 = gtk_menu_item_new (); + gtk_widget_ref (separator2); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "separator2", separator2, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (separator2); + gtk_container_add (GTK_CONTAINER (item1_menu), separator2); + gtk_widget_set_sensitive (separator2, FALSE); + + exit2 = gtk_menu_item_new_with_label ("Exit"); + gtk_widget_ref (exit2); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "exit2", exit2, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (exit2); + gtk_container_add (GTK_CONTAINER (item1_menu), exit2); + + emulator1 = gtk_menu_item_new_with_label ("Emulator"); + gtk_widget_ref (emulator1); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "emulator1", emulator1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (emulator1); + gtk_container_add (GTK_CONTAINER (menubar1), emulator1); + + emulator1_menu = gtk_menu_new (); + gtk_widget_ref (emulator1_menu); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "emulator1_menu", emulator1_menu, + (GtkDestroyNotify) gtk_widget_unref); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (emulator1), emulator1_menu); + emulator1_menu_accels = gtk_menu_ensure_uline_accel_group (GTK_MENU (emulator1_menu)); + + run1 = gtk_menu_item_new_with_label ("Run"); + gtk_widget_ref (run1); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "run1", run1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (run1); + gtk_container_add (GTK_CONTAINER (emulator1_menu), run1); + + reset1 = gtk_menu_item_new_with_label ("Reset"); + gtk_widget_ref (reset1); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "reset1", reset1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (reset1); + gtk_container_add (GTK_CONTAINER (emulator1_menu), reset1); + + configuration1 = gtk_menu_item_new_with_label ("Configuration"); + gtk_widget_ref (configuration1); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "configuration1", configuration1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (configuration1); + gtk_container_add (GTK_CONTAINER (menubar1), configuration1); + + configuration1_menu = gtk_menu_new (); + gtk_widget_ref (configuration1_menu); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "configuration1_menu", configuration1_menu, + (GtkDestroyNotify) gtk_widget_unref); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (configuration1), configuration1_menu); + configuration1_menu_accels = gtk_menu_ensure_uline_accel_group (GTK_MENU (configuration1_menu)); + + plugins___bios1 = gtk_menu_item_new_with_label ("Plugins & Bios"); + gtk_widget_ref (plugins___bios1); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "plugins___bios1", plugins___bios1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (plugins___bios1); + gtk_container_add (GTK_CONTAINER (configuration1_menu), plugins___bios1); + + separator3 = gtk_menu_item_new (); + gtk_widget_ref (separator3); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "separator3", separator3, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (separator3); + gtk_container_add (GTK_CONTAINER (configuration1_menu), separator3); + gtk_widget_set_sensitive (separator3, FALSE); + + graphics1 = gtk_menu_item_new_with_label ("Graphics"); + gtk_widget_ref (graphics1); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "graphics1", graphics1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (graphics1); + gtk_container_add (GTK_CONTAINER (configuration1_menu), graphics1); + + sound1 = gtk_menu_item_new_with_label ("Sound"); + gtk_widget_ref (sound1); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "sound1", sound1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (sound1); + gtk_container_add (GTK_CONTAINER (configuration1_menu), sound1); + + cd_rom1 = gtk_menu_item_new_with_label ("CD-ROM"); + gtk_widget_ref (cd_rom1); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "cd_rom1", cd_rom1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (cd_rom1); + gtk_container_add (GTK_CONTAINER (configuration1_menu), cd_rom1); + + controllers1 = gtk_menu_item_new_with_label ("Controllers"); + gtk_widget_ref (controllers1); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "controllers1", controllers1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (controllers1); + gtk_container_add (GTK_CONTAINER (configuration1_menu), controllers1); + + separator4 = gtk_menu_item_new (); + gtk_widget_ref (separator4); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "separator4", separator4, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (separator4); + gtk_container_add (GTK_CONTAINER (configuration1_menu), separator4); + gtk_widget_set_sensitive (separator4, FALSE); + + cpu1 = gtk_menu_item_new_with_label ("Cpu"); + gtk_widget_ref (cpu1); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "cpu1", cpu1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (cpu1); + gtk_container_add (GTK_CONTAINER (configuration1_menu), cpu1); + + memory_cards1 = gtk_menu_item_new_with_label ("Memory Cards"); + gtk_widget_ref (memory_cards1); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "memory_cards1", memory_cards1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (memory_cards1); + gtk_container_add (GTK_CONTAINER (configuration1_menu), memory_cards1); + + help1 = gtk_menu_item_new_with_label ("Help"); + gtk_widget_ref (help1); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "help1", help1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (help1); + gtk_container_add (GTK_CONTAINER (menubar1), help1); + + help1_menu = gtk_menu_new (); + gtk_widget_ref (help1_menu); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "help1_menu", help1_menu, + (GtkDestroyNotify) gtk_widget_unref); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (help1), help1_menu); + help1_menu_accels = gtk_menu_ensure_uline_accel_group (GTK_MENU (help1_menu)); + + about_pcsx1 = gtk_menu_item_new_with_label ("About P©SX"); + gtk_widget_ref (about_pcsx1); + gtk_object_set_data_full (GTK_OBJECT (MainWindow), "about_pcsx1", about_pcsx1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (about_pcsx1); + gtk_container_add (GTK_CONTAINER (help1_menu), about_pcsx1); + + gtk_signal_connect (GTK_OBJECT (MainWindow), "destroy", + GTK_SIGNAL_FUNC (OnDestroy), + NULL); + gtk_signal_connect (GTK_OBJECT (RunCd), "activate", + GTK_SIGNAL_FUNC (OnFile_RunCd), + NULL); + gtk_signal_connect (GTK_OBJECT (RunCdBiois), "activate", + GTK_SIGNAL_FUNC (OnFile_RunCdBios), + NULL); + gtk_signal_connect (GTK_OBJECT (Run_Exe), "activate", + GTK_SIGNAL_FUNC (OnFile_RunExe), + NULL); + gtk_signal_connect (GTK_OBJECT (exit2), "activate", + GTK_SIGNAL_FUNC (OnFile_Exit), + NULL); + gtk_signal_connect (GTK_OBJECT (run1), "activate", + GTK_SIGNAL_FUNC (OnEmu_Run), + NULL); + gtk_signal_connect (GTK_OBJECT (reset1), "activate", + GTK_SIGNAL_FUNC (OnEmu_Reset), + NULL); + gtk_signal_connect (GTK_OBJECT (plugins___bios1), "activate", + GTK_SIGNAL_FUNC (OnConf_Conf), + NULL); + gtk_signal_connect (GTK_OBJECT (graphics1), "activate", + GTK_SIGNAL_FUNC (OnConf_Gpu), + NULL); + gtk_signal_connect (GTK_OBJECT (sound1), "activate", + GTK_SIGNAL_FUNC (OnConf_Spu), + NULL); + gtk_signal_connect (GTK_OBJECT (cd_rom1), "activate", + GTK_SIGNAL_FUNC (OnConf_Cdr), + NULL); + gtk_signal_connect (GTK_OBJECT (controllers1), "activate", + GTK_SIGNAL_FUNC (OnConf_Pads), + NULL); + gtk_signal_connect (GTK_OBJECT (cpu1), "activate", + GTK_SIGNAL_FUNC (OnConf_Cpu), + NULL); + gtk_signal_connect (GTK_OBJECT (memory_cards1), "activate", + GTK_SIGNAL_FUNC (OnConf_Mcds), + NULL); + gtk_signal_connect (GTK_OBJECT (about_pcsx1), "activate", + GTK_SIGNAL_FUNC (OnHelp_About), + NULL); + + return MainWindow; +} + +GtkWidget* +create_AboutDlg (void) +{ + GtkWidget *AboutDlg; + GtkWidget *vbox2; + GtkWidget *packer1; + GtkWidget *hbox1; + GtkWidget *vbox4; + GtkWidget *GtkAbout_LabelVersion; + GtkWidget *frame1; + GtkWidget *vbox6; + GtkWidget *GtkAbout_LabelAuthors; + GtkWidget *pixmap1; + GtkWidget *frame2; + GtkWidget *vbox5; + GtkWidget *GtkAbout_LabelGreets; + GtkWidget *hbuttonbox1; + GtkWidget *button1; + + AboutDlg = gtk_window_new (GTK_WINDOW_DIALOG); + gtk_object_set_data (GTK_OBJECT (AboutDlg), "AboutDlg", AboutDlg); + gtk_container_set_border_width (GTK_CONTAINER (AboutDlg), 10); + gtk_window_set_title (GTK_WINDOW (AboutDlg), "Pcsx About"); + gtk_window_set_position (GTK_WINDOW (AboutDlg), GTK_WIN_POS_CENTER); + + vbox2 = gtk_vbox_new (FALSE, 0); + gtk_widget_ref (vbox2); + gtk_object_set_data_full (GTK_OBJECT (AboutDlg), "vbox2", vbox2, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (vbox2); + gtk_container_add (GTK_CONTAINER (AboutDlg), vbox2); + + packer1 = gtk_packer_new (); + gtk_widget_ref (packer1); + gtk_object_set_data_full (GTK_OBJECT (AboutDlg), "packer1", packer1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (packer1); + gtk_box_pack_start (GTK_BOX (vbox2), packer1, FALSE, FALSE, 0); + + hbox1 = gtk_hbox_new (FALSE, 0); + gtk_widget_ref (hbox1); + gtk_object_set_data_full (GTK_OBJECT (AboutDlg), "hbox1", hbox1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (hbox1); + gtk_box_pack_start (GTK_BOX (vbox2), hbox1, TRUE, TRUE, 0); + + vbox4 = gtk_vbox_new (FALSE, 0); + gtk_widget_ref (vbox4); + gtk_object_set_data_full (GTK_OBJECT (AboutDlg), "vbox4", vbox4, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (vbox4); + gtk_box_pack_start (GTK_BOX (hbox1), vbox4, TRUE, TRUE, 0); + + GtkAbout_LabelVersion = gtk_label_new ("PCSX\r\nVersion x.x"); + gtk_widget_ref (GtkAbout_LabelVersion); + gtk_object_set_data_full (GTK_OBJECT (AboutDlg), "GtkAbout_LabelVersion", GtkAbout_LabelVersion, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkAbout_LabelVersion); + gtk_box_pack_start (GTK_BOX (vbox4), GtkAbout_LabelVersion, FALSE, FALSE, 0); + + frame1 = gtk_frame_new (NULL); + gtk_widget_ref (frame1); + gtk_object_set_data_full (GTK_OBJECT (AboutDlg), "frame1", frame1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (frame1); + gtk_box_pack_start (GTK_BOX (vbox4), frame1, FALSE, FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame1), 5); + + vbox6 = gtk_vbox_new (FALSE, 0); + gtk_widget_ref (vbox6); + gtk_object_set_data_full (GTK_OBJECT (AboutDlg), "vbox6", vbox6, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (vbox6); + gtk_container_add (GTK_CONTAINER (frame1), vbox6); + gtk_container_set_border_width (GTK_CONTAINER (vbox6), 5); + + GtkAbout_LabelAuthors = gtk_label_new ("written by..."); + gtk_widget_ref (GtkAbout_LabelAuthors); + gtk_object_set_data_full (GTK_OBJECT (AboutDlg), "GtkAbout_LabelAuthors", GtkAbout_LabelAuthors, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkAbout_LabelAuthors); + gtk_box_pack_start (GTK_BOX (vbox6), GtkAbout_LabelAuthors, FALSE, FALSE, 0); + + pixmap1 = create_pixmap (AboutDlg, "pcsxAbout.xpm"); + gtk_widget_ref (pixmap1); + gtk_object_set_data_full (GTK_OBJECT (AboutDlg), "pixmap1", pixmap1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (pixmap1); + gtk_box_pack_start (GTK_BOX (hbox1), pixmap1, TRUE, TRUE, 0); + + frame2 = gtk_frame_new (NULL); + gtk_widget_ref (frame2); + gtk_object_set_data_full (GTK_OBJECT (AboutDlg), "frame2", frame2, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (frame2); + gtk_box_pack_start (GTK_BOX (vbox2), frame2, FALSE, FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame2), 5); + + vbox5 = gtk_vbox_new (FALSE, 0); + gtk_widget_ref (vbox5); + gtk_object_set_data_full (GTK_OBJECT (AboutDlg), "vbox5", vbox5, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (vbox5); + gtk_container_add (GTK_CONTAINER (frame2), vbox5); + gtk_container_set_border_width (GTK_CONTAINER (vbox5), 5); + + GtkAbout_LabelGreets = gtk_label_new ("greets to..."); + gtk_widget_ref (GtkAbout_LabelGreets); + gtk_object_set_data_full (GTK_OBJECT (AboutDlg), "GtkAbout_LabelGreets", GtkAbout_LabelGreets, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkAbout_LabelGreets); + gtk_box_pack_start (GTK_BOX (vbox5), GtkAbout_LabelGreets, FALSE, FALSE, 0); + + hbuttonbox1 = gtk_hbutton_box_new (); + gtk_widget_ref (hbuttonbox1); + gtk_object_set_data_full (GTK_OBJECT (AboutDlg), "hbuttonbox1", hbuttonbox1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (hbuttonbox1); + gtk_box_pack_start (GTK_BOX (vbox2), hbuttonbox1, TRUE, TRUE, 0); + + button1 = gtk_button_new_with_label ("Ok"); + gtk_widget_ref (button1); + gtk_object_set_data_full (GTK_OBJECT (AboutDlg), "button1", button1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button1); + gtk_container_add (GTK_CONTAINER (hbuttonbox1), button1); + GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT); + + gtk_signal_connect (GTK_OBJECT (button1), "clicked", + GTK_SIGNAL_FUNC (OnHelpAbout_Ok), + NULL); + + return AboutDlg; +} + +GtkWidget* +create_ConfDlg (void) +{ + GtkWidget *ConfDlg; + GtkWidget *vbox12; + GtkWidget *table2; + GtkWidget *GtkCombo_Pad1; + GtkWidget *combo_entry4; + GtkWidget *GtkCombo_Pad2; + GtkWidget *combo_entry5; + GtkWidget *GtkCombo_Cdr; + GtkWidget *combo_entry6; + GtkWidget *GtkCombo_Bios; + GtkWidget *combo_entry7; + GtkWidget *hbuttonbox5; + GtkWidget *button6; + GtkWidget *button7; + GtkWidget *button8; + GtkWidget *hbuttonbox6; + GtkWidget *button9; + GtkWidget *button10; + GtkWidget *button11; + GtkWidget *hbuttonbox7; + GtkWidget *button12; + GtkWidget *button13; + GtkWidget *button14; + GtkWidget *hbuttonbox8; + GtkWidget *button15; + GtkWidget *button16; + GtkWidget *button17; + GtkWidget *hbuttonbox9; + GtkWidget *button18; + GtkWidget *button19; + GtkWidget *button20; + GtkWidget *label2; + GtkWidget *label1; + GtkWidget *label3; + GtkWidget *label5; + GtkWidget *label6; + GtkWidget *label4; + GtkWidget *GtkCombo_Gpu; + GtkWidget *combo_entry2; + GtkWidget *GtkCombo_Spu; + GtkWidget *combo_entry3; + GtkWidget *hbox5; + GtkWidget *hbuttonbox11; + GtkWidget *button22; + GtkWidget *button23; + GtkWidget *hbuttonbox10; + GtkWidget *button4; + GtkWidget *button25; + + ConfDlg = gtk_window_new (GTK_WINDOW_DIALOG); + gtk_object_set_data (GTK_OBJECT (ConfDlg), "ConfDlg", ConfDlg); + gtk_container_set_border_width (GTK_CONTAINER (ConfDlg), 10); + gtk_window_set_title (GTK_WINDOW (ConfDlg), "Conf"); + gtk_window_set_position (GTK_WINDOW (ConfDlg), GTK_WIN_POS_CENTER); + + vbox12 = gtk_vbox_new (FALSE, 0); + gtk_widget_ref (vbox12); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "vbox12", vbox12, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (vbox12); + gtk_container_add (GTK_CONTAINER (ConfDlg), vbox12); + + table2 = gtk_table_new (9, 2, FALSE); + gtk_widget_ref (table2); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "table2", table2, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (table2); + gtk_box_pack_start (GTK_BOX (vbox12), table2, TRUE, TRUE, 0); + gtk_table_set_col_spacings (GTK_TABLE (table2), 15); + + GtkCombo_Pad1 = gtk_combo_new (); + gtk_widget_ref (GtkCombo_Pad1); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "GtkCombo_Pad1", GtkCombo_Pad1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkCombo_Pad1); + gtk_table_attach (GTK_TABLE (table2), GtkCombo_Pad1, 0, 1, 4, 5, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + combo_entry4 = GTK_COMBO (GtkCombo_Pad1)->entry; + gtk_widget_ref (combo_entry4); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "combo_entry4", combo_entry4, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (combo_entry4); + + GtkCombo_Pad2 = gtk_combo_new (); + gtk_widget_ref (GtkCombo_Pad2); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "GtkCombo_Pad2", GtkCombo_Pad2, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkCombo_Pad2); + gtk_table_attach (GTK_TABLE (table2), GtkCombo_Pad2, 1, 2, 4, 5, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + combo_entry5 = GTK_COMBO (GtkCombo_Pad2)->entry; + gtk_widget_ref (combo_entry5); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "combo_entry5", combo_entry5, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (combo_entry5); + + GtkCombo_Cdr = gtk_combo_new (); + gtk_widget_ref (GtkCombo_Cdr); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "GtkCombo_Cdr", GtkCombo_Cdr, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkCombo_Cdr); + gtk_table_attach (GTK_TABLE (table2), GtkCombo_Cdr, 0, 1, 7, 8, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + combo_entry6 = GTK_COMBO (GtkCombo_Cdr)->entry; + gtk_widget_ref (combo_entry6); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "combo_entry6", combo_entry6, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (combo_entry6); + + GtkCombo_Bios = gtk_combo_new (); + gtk_widget_ref (GtkCombo_Bios); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "GtkCombo_Bios", GtkCombo_Bios, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkCombo_Bios); + gtk_table_attach (GTK_TABLE (table2), GtkCombo_Bios, 1, 2, 7, 8, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + combo_entry7 = GTK_COMBO (GtkCombo_Bios)->entry; + gtk_widget_ref (combo_entry7); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "combo_entry7", combo_entry7, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (combo_entry7); + + hbuttonbox5 = gtk_hbutton_box_new (); + gtk_widget_ref (hbuttonbox5); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "hbuttonbox5", hbuttonbox5, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (hbuttonbox5); + gtk_table_attach (GTK_TABLE (table2), hbuttonbox5, 0, 1, 8, 9, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbuttonbox5), 0); + + button6 = gtk_button_new_with_label ("Configure"); + gtk_widget_ref (button6); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "button6", button6, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button6); + gtk_container_add (GTK_CONTAINER (hbuttonbox5), button6); + GTK_WIDGET_SET_FLAGS (button6, GTK_CAN_DEFAULT); + + button7 = gtk_button_new_with_label ("Test"); + gtk_widget_ref (button7); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "button7", button7, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button7); + gtk_container_add (GTK_CONTAINER (hbuttonbox5), button7); + GTK_WIDGET_SET_FLAGS (button7, GTK_CAN_DEFAULT); + + button8 = gtk_button_new_with_label ("About"); + gtk_widget_ref (button8); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "button8", button8, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button8); + gtk_container_add (GTK_CONTAINER (hbuttonbox5), button8); + GTK_WIDGET_SET_FLAGS (button8, GTK_CAN_DEFAULT); + + hbuttonbox6 = gtk_hbutton_box_new (); + gtk_widget_ref (hbuttonbox6); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "hbuttonbox6", hbuttonbox6, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (hbuttonbox6); + gtk_table_attach (GTK_TABLE (table2), hbuttonbox6, 1, 2, 5, 6, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbuttonbox6), 0); + + button9 = gtk_button_new_with_label ("Configure"); + gtk_widget_ref (button9); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "button9", button9, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button9); + gtk_container_add (GTK_CONTAINER (hbuttonbox6), button9); + GTK_WIDGET_SET_FLAGS (button9, GTK_CAN_DEFAULT); + + button10 = gtk_button_new_with_label ("Test"); + gtk_widget_ref (button10); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "button10", button10, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button10); + gtk_container_add (GTK_CONTAINER (hbuttonbox6), button10); + GTK_WIDGET_SET_FLAGS (button10, GTK_CAN_DEFAULT); + + button11 = gtk_button_new_with_label ("About"); + gtk_widget_ref (button11); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "button11", button11, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button11); + gtk_container_add (GTK_CONTAINER (hbuttonbox6), button11); + GTK_WIDGET_SET_FLAGS (button11, GTK_CAN_DEFAULT); + + hbuttonbox7 = gtk_hbutton_box_new (); + gtk_widget_ref (hbuttonbox7); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "hbuttonbox7", hbuttonbox7, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (hbuttonbox7); + gtk_table_attach (GTK_TABLE (table2), hbuttonbox7, 0, 1, 5, 6, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbuttonbox7), 0); + + button12 = gtk_button_new_with_label ("Configure"); + gtk_widget_ref (button12); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "button12", button12, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button12); + gtk_container_add (GTK_CONTAINER (hbuttonbox7), button12); + GTK_WIDGET_SET_FLAGS (button12, GTK_CAN_DEFAULT); + + button13 = gtk_button_new_with_label ("Test"); + gtk_widget_ref (button13); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "button13", button13, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button13); + gtk_container_add (GTK_CONTAINER (hbuttonbox7), button13); + GTK_WIDGET_SET_FLAGS (button13, GTK_CAN_DEFAULT); + + button14 = gtk_button_new_with_label ("About"); + gtk_widget_ref (button14); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "button14", button14, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button14); + gtk_container_add (GTK_CONTAINER (hbuttonbox7), button14); + GTK_WIDGET_SET_FLAGS (button14, GTK_CAN_DEFAULT); + + hbuttonbox8 = gtk_hbutton_box_new (); + gtk_widget_ref (hbuttonbox8); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "hbuttonbox8", hbuttonbox8, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (hbuttonbox8); + gtk_table_attach (GTK_TABLE (table2), hbuttonbox8, 0, 1, 2, 3, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0); + gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbuttonbox8), 0); + + button15 = gtk_button_new_with_label ("Configure"); + gtk_widget_ref (button15); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "button15", button15, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button15); + gtk_container_add (GTK_CONTAINER (hbuttonbox8), button15); + GTK_WIDGET_SET_FLAGS (button15, GTK_CAN_DEFAULT); + + button16 = gtk_button_new_with_label ("Test"); + gtk_widget_ref (button16); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "button16", button16, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button16); + gtk_container_add (GTK_CONTAINER (hbuttonbox8), button16); + GTK_WIDGET_SET_FLAGS (button16, GTK_CAN_DEFAULT); + + button17 = gtk_button_new_with_label ("About"); + gtk_widget_ref (button17); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "button17", button17, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button17); + gtk_container_add (GTK_CONTAINER (hbuttonbox8), button17); + GTK_WIDGET_SET_FLAGS (button17, GTK_CAN_DEFAULT); + + hbuttonbox9 = gtk_hbutton_box_new (); + gtk_widget_ref (hbuttonbox9); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "hbuttonbox9", hbuttonbox9, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (hbuttonbox9); + gtk_table_attach (GTK_TABLE (table2), hbuttonbox9, 1, 2, 2, 3, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (GTK_FILL), 0, 0); + gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbuttonbox9), 0); + + button18 = gtk_button_new_with_label ("Configure"); + gtk_widget_ref (button18); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "button18", button18, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button18); + gtk_container_add (GTK_CONTAINER (hbuttonbox9), button18); + GTK_WIDGET_SET_FLAGS (button18, GTK_CAN_DEFAULT); + + button19 = gtk_button_new_with_label ("Test"); + gtk_widget_ref (button19); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "button19", button19, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button19); + gtk_container_add (GTK_CONTAINER (hbuttonbox9), button19); + GTK_WIDGET_SET_FLAGS (button19, GTK_CAN_DEFAULT); + + button20 = gtk_button_new_with_label ("About"); + gtk_widget_ref (button20); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "button20", button20, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button20); + gtk_container_add (GTK_CONTAINER (hbuttonbox9), button20); + GTK_WIDGET_SET_FLAGS (button20, GTK_CAN_DEFAULT); + + label2 = gtk_label_new ("Sound"); + gtk_widget_ref (label2); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "label2", label2, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (label2); + gtk_table_attach (GTK_TABLE (table2), label2, 1, 2, 0, 1, + (GtkAttachOptions) (0), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label2), 0, 0.5); + + label1 = gtk_label_new ("Graphics"); + gtk_widget_ref (label1); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "label1", label1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (label1); + gtk_table_attach (GTK_TABLE (table2), label1, 0, 1, 0, 1, + (GtkAttachOptions) (0), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label1), 0, 0.5); + + label3 = gtk_label_new ("First Controller"); + gtk_widget_ref (label3); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "label3", label3, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (label3); + gtk_table_attach (GTK_TABLE (table2), label3, 0, 1, 3, 4, + (GtkAttachOptions) (0), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label3), 0, 0.5); + + label5 = gtk_label_new ("Cdrom"); + gtk_widget_ref (label5); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "label5", label5, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (label5); + gtk_table_attach (GTK_TABLE (table2), label5, 0, 1, 6, 7, + (GtkAttachOptions) (0), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label5), 0, 0.5); + + label6 = gtk_label_new ("Bios"); + gtk_widget_ref (label6); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "label6", label6, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (label6); + gtk_table_attach (GTK_TABLE (table2), label6, 1, 2, 6, 7, + (GtkAttachOptions) (0), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label6), 0, 0.5); + + label4 = gtk_label_new ("Second Controller"); + gtk_widget_ref (label4); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "label4", label4, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (label4); + gtk_table_attach (GTK_TABLE (table2), label4, 1, 2, 3, 4, + (GtkAttachOptions) (0), + (GtkAttachOptions) (0), 0, 0); + gtk_misc_set_alignment (GTK_MISC (label4), 0, 0.5); + + GtkCombo_Gpu = gtk_combo_new (); + gtk_widget_ref (GtkCombo_Gpu); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "GtkCombo_Gpu", GtkCombo_Gpu, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkCombo_Gpu); + gtk_table_attach (GTK_TABLE (table2), GtkCombo_Gpu, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + combo_entry2 = GTK_COMBO (GtkCombo_Gpu)->entry; + gtk_widget_ref (combo_entry2); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "combo_entry2", combo_entry2, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (combo_entry2); + + GtkCombo_Spu = gtk_combo_new (); + gtk_widget_ref (GtkCombo_Spu); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "GtkCombo_Spu", GtkCombo_Spu, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkCombo_Spu); + gtk_table_attach (GTK_TABLE (table2), GtkCombo_Spu, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + combo_entry3 = GTK_COMBO (GtkCombo_Spu)->entry; + gtk_widget_ref (combo_entry3); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "combo_entry3", combo_entry3, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (combo_entry3); + + hbox5 = gtk_hbox_new (FALSE, 14); + gtk_widget_ref (hbox5); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "hbox5", hbox5, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (hbox5); + gtk_box_pack_start (GTK_BOX (vbox12), hbox5, TRUE, TRUE, 0); + + hbuttonbox11 = gtk_hbutton_box_new (); + gtk_widget_ref (hbuttonbox11); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "hbuttonbox11", hbuttonbox11, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (hbuttonbox11); + gtk_box_pack_start (GTK_BOX (hbox5), hbuttonbox11, TRUE, TRUE, 0); + gtk_widget_set_usize (hbuttonbox11, 169, -2); + gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbuttonbox11), 0); + + button22 = gtk_button_new_with_label ("Select Plugins Dir"); + gtk_widget_ref (button22); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "button22", button22, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button22); + gtk_container_add (GTK_CONTAINER (hbuttonbox11), button22); + gtk_widget_set_usize (button22, 109, -2); + GTK_WIDGET_SET_FLAGS (button22, GTK_CAN_DEFAULT); + + button23 = gtk_button_new_with_label ("Select Bios Dir"); + gtk_widget_ref (button23); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "button23", button23, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button23); + gtk_container_add (GTK_CONTAINER (hbuttonbox11), button23); + GTK_WIDGET_SET_FLAGS (button23, GTK_CAN_DEFAULT); + + hbuttonbox10 = gtk_hbutton_box_new (); + gtk_widget_ref (hbuttonbox10); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "hbuttonbox10", hbuttonbox10, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (hbuttonbox10); + gtk_box_pack_start (GTK_BOX (hbox5), hbuttonbox10, TRUE, TRUE, 0); + gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbuttonbox10), 0); + + button4 = gtk_button_new_with_label ("Ok"); + gtk_widget_ref (button4); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "button4", button4, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button4); + gtk_container_add (GTK_CONTAINER (hbuttonbox10), button4); + GTK_WIDGET_SET_FLAGS (button4, GTK_CAN_DEFAULT); + + button25 = gtk_button_new_with_label ("Cancel"); + gtk_widget_ref (button25); + gtk_object_set_data_full (GTK_OBJECT (ConfDlg), "button25", button25, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button25); + gtk_container_add (GTK_CONTAINER (hbuttonbox10), button25); + GTK_WIDGET_SET_FLAGS (button25, GTK_CAN_DEFAULT); + + gtk_signal_connect (GTK_OBJECT (button6), "clicked", + GTK_SIGNAL_FUNC (OnConfConf_CdrConf), + NULL); + gtk_signal_connect (GTK_OBJECT (button7), "clicked", + GTK_SIGNAL_FUNC (OnConfConf_CdrTest), + NULL); + gtk_signal_connect (GTK_OBJECT (button8), "clicked", + GTK_SIGNAL_FUNC (OnConfConf_CdrAbout), + NULL); + gtk_signal_connect (GTK_OBJECT (button9), "clicked", + GTK_SIGNAL_FUNC (OnConfConf_Pad2Conf), + NULL); + gtk_signal_connect (GTK_OBJECT (button10), "clicked", + GTK_SIGNAL_FUNC (OnConfConf_Pad2Test), + NULL); + gtk_signal_connect (GTK_OBJECT (button11), "clicked", + GTK_SIGNAL_FUNC (OnConfConf_Pad2About), + NULL); + gtk_signal_connect (GTK_OBJECT (button12), "clicked", + GTK_SIGNAL_FUNC (OnConfConf_Pad1Conf), + NULL); + gtk_signal_connect (GTK_OBJECT (button13), "clicked", + GTK_SIGNAL_FUNC (OnConfConf_Pad1Test), + NULL); + gtk_signal_connect (GTK_OBJECT (button14), "clicked", + GTK_SIGNAL_FUNC (OnConfConf_Pad1About), + NULL); + gtk_signal_connect (GTK_OBJECT (button15), "clicked", + GTK_SIGNAL_FUNC (OnConfConf_GpuConf), + NULL); + gtk_signal_connect (GTK_OBJECT (button16), "clicked", + GTK_SIGNAL_FUNC (OnConfConf_GpuTest), + NULL); + gtk_signal_connect (GTK_OBJECT (button17), "clicked", + GTK_SIGNAL_FUNC (OnConfConf_GpuAbout), + NULL); + gtk_signal_connect (GTK_OBJECT (button18), "clicked", + GTK_SIGNAL_FUNC (OnConfConf_SpuConf), + NULL); + gtk_signal_connect (GTK_OBJECT (button19), "clicked", + GTK_SIGNAL_FUNC (OnConfConf_SpuTest), + NULL); + gtk_signal_connect (GTK_OBJECT (button20), "clicked", + GTK_SIGNAL_FUNC (OnConfConf_SpuAbout), + NULL); + gtk_signal_connect (GTK_OBJECT (button22), "clicked", + GTK_SIGNAL_FUNC (OnConfConf_PluginsPath), + NULL); + gtk_signal_connect (GTK_OBJECT (button23), "clicked", + GTK_SIGNAL_FUNC (OnConfConf_BiosPath), + NULL); + gtk_signal_connect (GTK_OBJECT (button4), "clicked", + GTK_SIGNAL_FUNC (OnConfConf_Ok), + NULL); + gtk_signal_connect (GTK_OBJECT (button25), "clicked", + GTK_SIGNAL_FUNC (OnConfConf_Cancel), + NULL); + + return ConfDlg; +} + +GtkWidget* +create_CpuDlg (void) +{ + GtkWidget *CpuDlg; + GtkWidget *vbox8; + GtkWidget *frame3; + GtkWidget *vbox15; + GtkWidget *table1; + GtkWidget *GtkCheckButton_Xa; + GtkWidget *GtkCheckButton_Cdda; + GtkWidget *GtkCheckButton_Sio; + GtkWidget *GtkCheckButton_Cpu; + GtkWidget *GtkCheckButton_PsxOut; + GtkWidget *GtkCheckButton_Mdec; + GtkWidget *GtkCheckButton_SpuIrq; + GtkWidget *GtkCheckButton_CdTiming; + GtkWidget *frame6; + GtkWidget *hbox4; + GtkWidget *GtkCheckButton_PsxAuto; + GtkWidget *GtkCombo_PsxType; + GtkWidget *combo_entry1; + GtkWidget *hbuttonbox3; + GtkWidget *button2; + GtkWidget *button3; + + CpuDlg = gtk_window_new (GTK_WINDOW_DIALOG); + gtk_object_set_data (GTK_OBJECT (CpuDlg), "CpuDlg", CpuDlg); + gtk_container_set_border_width (GTK_CONTAINER (CpuDlg), 5); + gtk_window_set_title (GTK_WINDOW (CpuDlg), "Cpu"); + gtk_window_set_position (GTK_WINDOW (CpuDlg), GTK_WIN_POS_CENTER); + + vbox8 = gtk_vbox_new (FALSE, 0); + gtk_widget_ref (vbox8); + gtk_object_set_data_full (GTK_OBJECT (CpuDlg), "vbox8", vbox8, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (vbox8); + gtk_container_add (GTK_CONTAINER (CpuDlg), vbox8); + + frame3 = gtk_frame_new ("Options"); + gtk_widget_ref (frame3); + gtk_object_set_data_full (GTK_OBJECT (CpuDlg), "frame3", frame3, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (frame3); + gtk_box_pack_start (GTK_BOX (vbox8), frame3, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame3), 5); + + vbox15 = gtk_vbox_new (FALSE, 0); + gtk_widget_ref (vbox15); + gtk_object_set_data_full (GTK_OBJECT (CpuDlg), "vbox15", vbox15, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (vbox15); + gtk_container_add (GTK_CONTAINER (frame3), vbox15); + gtk_container_set_border_width (GTK_CONTAINER (vbox15), 5); + + table1 = gtk_table_new (4, 2, FALSE); + gtk_widget_ref (table1); + gtk_object_set_data_full (GTK_OBJECT (CpuDlg), "table1", table1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (table1); + gtk_box_pack_start (GTK_BOX (vbox15), table1, TRUE, TRUE, 0); + + GtkCheckButton_Xa = gtk_check_button_new_with_label ("Disable Xa Decoding"); + gtk_widget_ref (GtkCheckButton_Xa); + gtk_object_set_data_full (GTK_OBJECT (CpuDlg), "GtkCheckButton_Xa", GtkCheckButton_Xa, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkCheckButton_Xa); + gtk_table_attach (GTK_TABLE (table1), GtkCheckButton_Xa, 0, 1, 0, 1, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + GtkCheckButton_Cdda = gtk_check_button_new_with_label ("Disable Cd Audio"); + gtk_widget_ref (GtkCheckButton_Cdda); + gtk_object_set_data_full (GTK_OBJECT (CpuDlg), "GtkCheckButton_Cdda", GtkCheckButton_Cdda, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkCheckButton_Cdda); + gtk_table_attach (GTK_TABLE (table1), GtkCheckButton_Cdda, 1, 2, 0, 1, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + GtkCheckButton_Sio = gtk_check_button_new_with_label ("Sio Irq Always Enabled"); + gtk_widget_ref (GtkCheckButton_Sio); + gtk_object_set_data_full (GTK_OBJECT (CpuDlg), "GtkCheckButton_Sio", GtkCheckButton_Sio, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkCheckButton_Sio); + gtk_table_attach (GTK_TABLE (table1), GtkCheckButton_Sio, 0, 1, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + GtkCheckButton_Cpu = gtk_check_button_new_with_label ("Enable Interpreter Cpu"); + gtk_widget_ref (GtkCheckButton_Cpu); + gtk_object_set_data_full (GTK_OBJECT (CpuDlg), "GtkCheckButton_Cpu", GtkCheckButton_Cpu, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkCheckButton_Cpu); + gtk_table_attach (GTK_TABLE (table1), GtkCheckButton_Cpu, 1, 2, 1, 2, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + GtkCheckButton_PsxOut = gtk_check_button_new_with_label ("Enable Console Output"); + gtk_widget_ref (GtkCheckButton_PsxOut); + gtk_object_set_data_full (GTK_OBJECT (CpuDlg), "GtkCheckButton_PsxOut", GtkCheckButton_PsxOut, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkCheckButton_PsxOut); + gtk_table_attach (GTK_TABLE (table1), GtkCheckButton_PsxOut, 1, 2, 2, 3, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + GtkCheckButton_Mdec = gtk_check_button_new_with_label ("Black & White Movies"); + gtk_widget_ref (GtkCheckButton_Mdec); + gtk_object_set_data_full (GTK_OBJECT (CpuDlg), "GtkCheckButton_Mdec", GtkCheckButton_Mdec, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkCheckButton_Mdec); + gtk_table_attach (GTK_TABLE (table1), GtkCheckButton_Mdec, 0, 1, 3, 4, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + GtkCheckButton_SpuIrq = gtk_check_button_new_with_label ("Spu Irq Always Enabled"); + gtk_widget_ref (GtkCheckButton_SpuIrq); + gtk_object_set_data_full (GTK_OBJECT (CpuDlg), "GtkCheckButton_SpuIrq", GtkCheckButton_SpuIrq, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkCheckButton_SpuIrq); + gtk_table_attach (GTK_TABLE (table1), GtkCheckButton_SpuIrq, 0, 1, 2, 3, + (GtkAttachOptions) (GTK_FILL), + (GtkAttachOptions) (0), 0, 0); + + GtkCheckButton_CdTiming = gtk_check_button_new_with_label ("Old Cdrom Timing (Gran Turismo...)"); + gtk_widget_ref (GtkCheckButton_CdTiming); + gtk_object_set_data_full (GTK_OBJECT (CpuDlg), "GtkCheckButton_CdTiming", GtkCheckButton_CdTiming, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkCheckButton_CdTiming); + gtk_box_pack_start (GTK_BOX (vbox15), GtkCheckButton_CdTiming, FALSE, FALSE, 0); + + frame6 = gtk_frame_new ("Psx System Type"); + gtk_widget_ref (frame6); + gtk_object_set_data_full (GTK_OBJECT (CpuDlg), "frame6", frame6, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (frame6); + gtk_box_pack_start (GTK_BOX (vbox8), frame6, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame6), 5); + + hbox4 = gtk_hbox_new (FALSE, 0); + gtk_widget_ref (hbox4); + gtk_object_set_data_full (GTK_OBJECT (CpuDlg), "hbox4", hbox4, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (hbox4); + gtk_container_add (GTK_CONTAINER (frame6), hbox4); + gtk_container_set_border_width (GTK_CONTAINER (hbox4), 5); + + GtkCheckButton_PsxAuto = gtk_check_button_new_with_label ("Autodetect"); + gtk_widget_ref (GtkCheckButton_PsxAuto); + gtk_object_set_data_full (GTK_OBJECT (CpuDlg), "GtkCheckButton_PsxAuto", GtkCheckButton_PsxAuto, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkCheckButton_PsxAuto); + gtk_box_pack_start (GTK_BOX (hbox4), GtkCheckButton_PsxAuto, FALSE, FALSE, 0); + gtk_widget_set_usize (GtkCheckButton_PsxAuto, 159, -2); + + GtkCombo_PsxType = gtk_combo_new (); + gtk_widget_ref (GtkCombo_PsxType); + gtk_object_set_data_full (GTK_OBJECT (CpuDlg), "GtkCombo_PsxType", GtkCombo_PsxType, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkCombo_PsxType); + gtk_box_pack_start (GTK_BOX (hbox4), GtkCombo_PsxType, FALSE, FALSE, 0); + gtk_widget_set_usize (GtkCombo_PsxType, 154, -2); + + combo_entry1 = GTK_COMBO (GtkCombo_PsxType)->entry; + gtk_widget_ref (combo_entry1); + gtk_object_set_data_full (GTK_OBJECT (CpuDlg), "combo_entry1", combo_entry1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (combo_entry1); + gtk_entry_set_editable (GTK_ENTRY (combo_entry1), FALSE); + + hbuttonbox3 = gtk_hbutton_box_new (); + gtk_widget_ref (hbuttonbox3); + gtk_object_set_data_full (GTK_OBJECT (CpuDlg), "hbuttonbox3", hbuttonbox3, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (hbuttonbox3); + gtk_box_pack_start (GTK_BOX (vbox8), hbuttonbox3, TRUE, TRUE, 0); + + button2 = gtk_button_new_with_label ("Ok"); + gtk_widget_ref (button2); + gtk_object_set_data_full (GTK_OBJECT (CpuDlg), "button2", button2, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button2); + gtk_container_add (GTK_CONTAINER (hbuttonbox3), button2); + GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT); + + button3 = gtk_button_new_with_label ("Cancel"); + gtk_widget_ref (button3); + gtk_object_set_data_full (GTK_OBJECT (CpuDlg), "button3", button3, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button3); + gtk_container_add (GTK_CONTAINER (hbuttonbox3), button3); + GTK_WIDGET_SET_FLAGS (button3, GTK_CAN_DEFAULT); + + gtk_signal_connect (GTK_OBJECT (button2), "clicked", + GTK_SIGNAL_FUNC (OnCpu_Ok), + NULL); + gtk_signal_connect (GTK_OBJECT (button3), "clicked", + GTK_SIGNAL_FUNC (OnCpu_Cancel), + NULL); + + return CpuDlg; +} + +GtkWidget* +create_McdsDlg (void) +{ + GtkWidget *McdsDlg; + GtkWidget *vbox10; + GtkWidget *hbox6; + GtkWidget *frame7; + GtkWidget *vbox13; + GtkWidget *scrolledwindow1; + GtkWidget *GtkCList_McdList1; + GtkWidget *label9; + GtkWidget *label10; + GtkWidget *label11; + GtkWidget *label15; + GtkWidget *label16; + GtkWidget *hbuttonbox12; + GtkWidget *GtkButton_SelMcd1; + GtkWidget *GtkButton_Format1; + GtkWidget *GtkButton_Reload1; + GtkWidget *GtkEntry_Mcd1; + GtkWidget *vbuttonbox1; + GtkWidget *button26; + GtkWidget *button28; + GtkWidget *GtkButton_McdPaste; + GtkWidget *button29; + GtkWidget *button30; + GtkWidget *frame8; + GtkWidget *vbox14; + GtkWidget *scrolledwindow2; + GtkWidget *GtkCList_McdList2; + GtkWidget *label12; + GtkWidget *label13; + GtkWidget *label14; + GtkWidget *label17; + GtkWidget *label18; + GtkWidget *hbuttonbox13; + GtkWidget *GtkButton_SelMcd2; + GtkWidget *GtkButton_Format2; + GtkWidget *GtkButton_Reload2; + GtkWidget *GtkEntry_Mcd2; + GtkWidget *hbuttonbox2; + GtkWidget *GtkMcds_Ok; + GtkWidget *GtkMcds_Cancel; + + McdsDlg = gtk_window_new (GTK_WINDOW_DIALOG); + gtk_object_set_data (GTK_OBJECT (McdsDlg), "McdsDlg", McdsDlg); + gtk_container_set_border_width (GTK_CONTAINER (McdsDlg), 5); + gtk_window_set_title (GTK_WINDOW (McdsDlg), "Mcds"); + gtk_window_set_position (GTK_WINDOW (McdsDlg), GTK_WIN_POS_CENTER); + + vbox10 = gtk_vbox_new (FALSE, 5); + gtk_widget_ref (vbox10); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "vbox10", vbox10, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (vbox10); + gtk_container_add (GTK_CONTAINER (McdsDlg), vbox10); + + hbox6 = gtk_hbox_new (FALSE, 0); + gtk_widget_ref (hbox6); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "hbox6", hbox6, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (hbox6); + gtk_box_pack_start (GTK_BOX (vbox10), hbox6, TRUE, TRUE, 0); + + frame7 = gtk_frame_new ("Memory Card 1"); + gtk_widget_ref (frame7); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "frame7", frame7, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (frame7); + gtk_box_pack_start (GTK_BOX (hbox6), frame7, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame7), 5); + + vbox13 = gtk_vbox_new (FALSE, 0); + gtk_widget_ref (vbox13); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "vbox13", vbox13, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (vbox13); + gtk_container_add (GTK_CONTAINER (frame7), vbox13); + gtk_container_set_border_width (GTK_CONTAINER (vbox13), 5); + + scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_ref (scrolledwindow1); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "scrolledwindow1", scrolledwindow1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (scrolledwindow1); + gtk_box_pack_start (GTK_BOX (vbox13), scrolledwindow1, TRUE, TRUE, 0); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + + GtkCList_McdList1 = gtk_clist_new (5); + gtk_widget_ref (GtkCList_McdList1); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "GtkCList_McdList1", GtkCList_McdList1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkCList_McdList1); + gtk_container_add (GTK_CONTAINER (scrolledwindow1), GtkCList_McdList1); + gtk_widget_set_usize (GtkCList_McdList1, -2, 180); + gtk_clist_set_column_width (GTK_CLIST (GtkCList_McdList1), 0, 25); + gtk_clist_set_column_width (GTK_CLIST (GtkCList_McdList1), 1, 180); + gtk_clist_set_column_width (GTK_CLIST (GtkCList_McdList1), 2, 50); + gtk_clist_set_column_width (GTK_CLIST (GtkCList_McdList1), 3, 80); + gtk_clist_set_column_width (GTK_CLIST (GtkCList_McdList1), 4, 80); + gtk_clist_column_titles_show (GTK_CLIST (GtkCList_McdList1)); + + label9 = gtk_label_new ("Icon"); + gtk_widget_ref (label9); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "label9", label9, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (label9); + gtk_clist_set_column_widget (GTK_CLIST (GtkCList_McdList1), 0, label9); + + label10 = gtk_label_new ("Title"); + gtk_widget_ref (label10); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "label10", label10, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (label10); + gtk_clist_set_column_widget (GTK_CLIST (GtkCList_McdList1), 1, label10); + + label11 = gtk_label_new ("Status"); + gtk_widget_ref (label11); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "label11", label11, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (label11); + gtk_clist_set_column_widget (GTK_CLIST (GtkCList_McdList1), 2, label11); + + label15 = gtk_label_new ("Game ID"); + gtk_widget_ref (label15); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "label15", label15, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (label15); + gtk_clist_set_column_widget (GTK_CLIST (GtkCList_McdList1), 3, label15); + + label16 = gtk_label_new ("Game"); + gtk_widget_ref (label16); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "label16", label16, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (label16); + gtk_clist_set_column_widget (GTK_CLIST (GtkCList_McdList1), 4, label16); + + hbuttonbox12 = gtk_hbutton_box_new (); + gtk_widget_ref (hbuttonbox12); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "hbuttonbox12", hbuttonbox12, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (hbuttonbox12); + gtk_box_pack_start (GTK_BOX (vbox13), hbuttonbox12, TRUE, TRUE, 0); + gtk_widget_set_usize (hbuttonbox12, 240, -2); + gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbuttonbox12), 0); + gtk_button_box_set_child_size (GTK_BUTTON_BOX (hbuttonbox12), 70, 27); + + GtkButton_SelMcd1 = gtk_button_new_with_label ("Select"); + gtk_widget_ref (GtkButton_SelMcd1); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "GtkButton_SelMcd1", GtkButton_SelMcd1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkButton_SelMcd1); + gtk_container_add (GTK_CONTAINER (hbuttonbox12), GtkButton_SelMcd1); + GTK_WIDGET_SET_FLAGS (GtkButton_SelMcd1, GTK_CAN_DEFAULT); + + GtkButton_Format1 = gtk_button_new_with_label ("Format"); + gtk_widget_ref (GtkButton_Format1); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "GtkButton_Format1", GtkButton_Format1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkButton_Format1); + gtk_container_add (GTK_CONTAINER (hbuttonbox12), GtkButton_Format1); + GTK_WIDGET_SET_FLAGS (GtkButton_Format1, GTK_CAN_DEFAULT); + + GtkButton_Reload1 = gtk_button_new_with_label ("Reload"); + gtk_widget_ref (GtkButton_Reload1); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "GtkButton_Reload1", GtkButton_Reload1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkButton_Reload1); + gtk_container_add (GTK_CONTAINER (hbuttonbox12), GtkButton_Reload1); + GTK_WIDGET_SET_FLAGS (GtkButton_Reload1, GTK_CAN_DEFAULT); + + GtkEntry_Mcd1 = gtk_entry_new (); + gtk_widget_ref (GtkEntry_Mcd1); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "GtkEntry_Mcd1", GtkEntry_Mcd1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkEntry_Mcd1); + gtk_box_pack_start (GTK_BOX (vbox13), GtkEntry_Mcd1, FALSE, FALSE, 0); + + vbuttonbox1 = gtk_vbutton_box_new (); + gtk_widget_ref (vbuttonbox1); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "vbuttonbox1", vbuttonbox1, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (vbuttonbox1); + gtk_box_pack_start (GTK_BOX (hbox6), vbuttonbox1, TRUE, FALSE, 0); + gtk_button_box_set_layout (GTK_BUTTON_BOX (vbuttonbox1), GTK_BUTTONBOX_SPREAD); + gtk_button_box_set_spacing (GTK_BUTTON_BOX (vbuttonbox1), 0); + gtk_button_box_set_child_size (GTK_BUTTON_BOX (vbuttonbox1), 64, 27); + gtk_button_box_set_child_ipadding (GTK_BUTTON_BOX (vbuttonbox1), 0, 0); + + button26 = gtk_button_new_with_label ("-> Copy ->"); + gtk_widget_ref (button26); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "button26", button26, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button26); + gtk_container_add (GTK_CONTAINER (vbuttonbox1), button26); + GTK_WIDGET_SET_FLAGS (button26, GTK_CAN_DEFAULT); + + button28 = gtk_button_new_with_label ("<- Copy <-"); + gtk_widget_ref (button28); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "button28", button28, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button28); + gtk_container_add (GTK_CONTAINER (vbuttonbox1), button28); + GTK_WIDGET_SET_FLAGS (button28, GTK_CAN_DEFAULT); + + GtkButton_McdPaste = gtk_button_new_with_label ("Paste"); + gtk_widget_ref (GtkButton_McdPaste); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "GtkButton_McdPaste", GtkButton_McdPaste, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkButton_McdPaste); + gtk_container_add (GTK_CONTAINER (vbuttonbox1), GtkButton_McdPaste); + GTK_WIDGET_SET_FLAGS (GtkButton_McdPaste, GTK_CAN_DEFAULT); + + button29 = gtk_button_new_with_label ("Un/Delete ->"); + gtk_widget_ref (button29); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "button29", button29, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button29); + gtk_container_add (GTK_CONTAINER (vbuttonbox1), button29); + GTK_WIDGET_SET_FLAGS (button29, GTK_CAN_DEFAULT); + + button30 = gtk_button_new_with_label ("<- Un/Delete"); + gtk_widget_ref (button30); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "button30", button30, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (button30); + gtk_container_add (GTK_CONTAINER (vbuttonbox1), button30); + GTK_WIDGET_SET_FLAGS (button30, GTK_CAN_DEFAULT); + + frame8 = gtk_frame_new ("Memory Card 2"); + gtk_widget_ref (frame8); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "frame8", frame8, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (frame8); + gtk_box_pack_start (GTK_BOX (hbox6), frame8, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (frame8), 5); + + vbox14 = gtk_vbox_new (FALSE, 0); + gtk_widget_ref (vbox14); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "vbox14", vbox14, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (vbox14); + gtk_container_add (GTK_CONTAINER (frame8), vbox14); + gtk_container_set_border_width (GTK_CONTAINER (vbox14), 5); + + scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_ref (scrolledwindow2); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "scrolledwindow2", scrolledwindow2, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (scrolledwindow2); + gtk_box_pack_start (GTK_BOX (vbox14), scrolledwindow2, TRUE, TRUE, 0); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + + GtkCList_McdList2 = gtk_clist_new (5); + gtk_widget_ref (GtkCList_McdList2); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "GtkCList_McdList2", GtkCList_McdList2, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkCList_McdList2); + gtk_container_add (GTK_CONTAINER (scrolledwindow2), GtkCList_McdList2); + gtk_widget_set_usize (GtkCList_McdList2, -2, 180); + gtk_clist_set_column_width (GTK_CLIST (GtkCList_McdList2), 0, 25); + gtk_clist_set_column_width (GTK_CLIST (GtkCList_McdList2), 1, 180); + gtk_clist_set_column_width (GTK_CLIST (GtkCList_McdList2), 2, 50); + gtk_clist_set_column_width (GTK_CLIST (GtkCList_McdList2), 3, 80); + gtk_clist_set_column_width (GTK_CLIST (GtkCList_McdList2), 4, 80); + gtk_clist_column_titles_show (GTK_CLIST (GtkCList_McdList2)); + + label12 = gtk_label_new ("Icon"); + gtk_widget_ref (label12); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "label12", label12, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (label12); + gtk_clist_set_column_widget (GTK_CLIST (GtkCList_McdList2), 0, label12); + + label13 = gtk_label_new ("Title"); + gtk_widget_ref (label13); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "label13", label13, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (label13); + gtk_clist_set_column_widget (GTK_CLIST (GtkCList_McdList2), 1, label13); + + label14 = gtk_label_new ("Status"); + gtk_widget_ref (label14); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "label14", label14, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (label14); + gtk_clist_set_column_widget (GTK_CLIST (GtkCList_McdList2), 2, label14); + + label17 = gtk_label_new ("Game ID"); + gtk_widget_ref (label17); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "label17", label17, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (label17); + gtk_clist_set_column_widget (GTK_CLIST (GtkCList_McdList2), 3, label17); + + label18 = gtk_label_new ("Game"); + gtk_widget_ref (label18); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "label18", label18, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (label18); + gtk_clist_set_column_widget (GTK_CLIST (GtkCList_McdList2), 4, label18); + + hbuttonbox13 = gtk_hbutton_box_new (); + gtk_widget_ref (hbuttonbox13); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "hbuttonbox13", hbuttonbox13, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (hbuttonbox13); + gtk_box_pack_start (GTK_BOX (vbox14), hbuttonbox13, TRUE, TRUE, 0); + gtk_widget_set_usize (hbuttonbox13, 240, -2); + gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbuttonbox13), 0); + gtk_button_box_set_child_size (GTK_BUTTON_BOX (hbuttonbox13), 70, 27); + + GtkButton_SelMcd2 = gtk_button_new_with_label ("Select"); + gtk_widget_ref (GtkButton_SelMcd2); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "GtkButton_SelMcd2", GtkButton_SelMcd2, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkButton_SelMcd2); + gtk_container_add (GTK_CONTAINER (hbuttonbox13), GtkButton_SelMcd2); + GTK_WIDGET_SET_FLAGS (GtkButton_SelMcd2, GTK_CAN_DEFAULT); + + GtkButton_Format2 = gtk_button_new_with_label ("Format"); + gtk_widget_ref (GtkButton_Format2); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "GtkButton_Format2", GtkButton_Format2, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkButton_Format2); + gtk_container_add (GTK_CONTAINER (hbuttonbox13), GtkButton_Format2); + GTK_WIDGET_SET_FLAGS (GtkButton_Format2, GTK_CAN_DEFAULT); + + GtkButton_Reload2 = gtk_button_new_with_label ("Reload"); + gtk_widget_ref (GtkButton_Reload2); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "GtkButton_Reload2", GtkButton_Reload2, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkButton_Reload2); + gtk_container_add (GTK_CONTAINER (hbuttonbox13), GtkButton_Reload2); + GTK_WIDGET_SET_FLAGS (GtkButton_Reload2, GTK_CAN_DEFAULT); + + GtkEntry_Mcd2 = gtk_entry_new (); + gtk_widget_ref (GtkEntry_Mcd2); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "GtkEntry_Mcd2", GtkEntry_Mcd2, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkEntry_Mcd2); + gtk_box_pack_start (GTK_BOX (vbox14), GtkEntry_Mcd2, FALSE, FALSE, 0); + + hbuttonbox2 = gtk_hbutton_box_new (); + gtk_widget_ref (hbuttonbox2); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "hbuttonbox2", hbuttonbox2, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (hbuttonbox2); + gtk_box_pack_start (GTK_BOX (vbox10), hbuttonbox2, TRUE, TRUE, 0); + + GtkMcds_Ok = gtk_button_new_with_label ("Ok"); + gtk_widget_ref (GtkMcds_Ok); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "GtkMcds_Ok", GtkMcds_Ok, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkMcds_Ok); + gtk_container_add (GTK_CONTAINER (hbuttonbox2), GtkMcds_Ok); + GTK_WIDGET_SET_FLAGS (GtkMcds_Ok, GTK_CAN_DEFAULT); + + GtkMcds_Cancel = gtk_button_new_with_label ("Cancel"); + gtk_widget_ref (GtkMcds_Cancel); + gtk_object_set_data_full (GTK_OBJECT (McdsDlg), "GtkMcds_Cancel", GtkMcds_Cancel, + (GtkDestroyNotify) gtk_widget_unref); + gtk_widget_show (GtkMcds_Cancel); + gtk_container_add (GTK_CONTAINER (hbuttonbox2), GtkMcds_Cancel); + GTK_WIDGET_SET_FLAGS (GtkMcds_Cancel, GTK_CAN_DEFAULT); + + gtk_signal_connect (GTK_OBJECT (GtkButton_SelMcd1), "clicked", + GTK_SIGNAL_FUNC (OnMcd_FS1), + NULL); + gtk_signal_connect (GTK_OBJECT (GtkButton_Format1), "clicked", + GTK_SIGNAL_FUNC (OnMcd_Format1), + NULL); + gtk_signal_connect (GTK_OBJECT (GtkButton_Reload1), "clicked", + GTK_SIGNAL_FUNC (OnMcd_Reload1), + NULL); + gtk_signal_connect (GTK_OBJECT (button26), "clicked", + GTK_SIGNAL_FUNC (OnMcd_CopyTo2), + NULL); + gtk_signal_connect (GTK_OBJECT (button28), "clicked", + GTK_SIGNAL_FUNC (OnMcd_CopyTo1), + NULL); + gtk_signal_connect (GTK_OBJECT (GtkButton_McdPaste), "clicked", + GTK_SIGNAL_FUNC (OnMcd_Paste), + NULL); + gtk_signal_connect (GTK_OBJECT (button29), "clicked", + GTK_SIGNAL_FUNC (OnMcd_Delete2), + NULL); + gtk_signal_connect (GTK_OBJECT (button30), "clicked", + GTK_SIGNAL_FUNC (OnMcd_Delete1), + NULL); + gtk_signal_connect (GTK_OBJECT (GtkButton_SelMcd2), "clicked", + GTK_SIGNAL_FUNC (OnMcd_FS2), + NULL); + gtk_signal_connect (GTK_OBJECT (GtkButton_Format2), "clicked", + GTK_SIGNAL_FUNC (OnMcd_Format2), + NULL); + gtk_signal_connect (GTK_OBJECT (GtkButton_Reload2), "clicked", + GTK_SIGNAL_FUNC (OnMcd_Reload2), + NULL); + gtk_signal_connect (GTK_OBJECT (GtkMcds_Ok), "clicked", + GTK_SIGNAL_FUNC (OnMcd_Ok), + NULL); + gtk_signal_connect (GTK_OBJECT (GtkMcds_Cancel), "clicked", + GTK_SIGNAL_FUNC (OnMcd_Cancel), + NULL); + + return McdsDlg; +} + diff --git a/PcsxSrc/Linux/GladeGui.h b/PcsxSrc/Linux/GladeGui.h new file mode 100644 index 0000000..780f270 --- /dev/null +++ b/PcsxSrc/Linux/GladeGui.h @@ -0,0 +1,9 @@ +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +GtkWidget* create_MainWindow (void); +GtkWidget* create_AboutDlg (void); +GtkWidget* create_ConfDlg (void); +GtkWidget* create_CpuDlg (void); +GtkWidget* create_McdsDlg (void); diff --git a/PcsxSrc/Linux/GtkGui.c b/PcsxSrc/Linux/GtkGui.c new file mode 100644 index 0000000..c3d8f4f --- /dev/null +++ b/PcsxSrc/Linux/GtkGui.c @@ -0,0 +1,1305 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Linux.h" +#include "plugins.h" +#include "Sio.h" +#include "GladeGui.h" +#include "GladeFuncs.h" + +extern int UseGui; +long LoadCdBios; +static int needreset = 1; + +PSEgetLibType PSE_getLibType = NULL; +PSEgetLibVersion PSE_getLibVersion = NULL; +PSEgetLibName PSE_getLibName = NULL; + +// Helper Functions +void FindPlugins(); + +// Functions Callbacks +void OnFile_RunExe(); +void OnFile_RunCd(); +void OnFile_RunCdBios(); +void OnFile_Exit(); +void OnEmu_Run(); +void OnEmu_Reset(); +void OnConf_Gpu(); +void OnConf_Spu(); +void OnConf_Cdr(); +void OnConf_Pads(); +void OnConf_Mcds(); +void OnConf_Cpu(); +void OnConf_Conf(); +void OnHelp_Help(); +void OnHelp_About(); + +GtkWidget *Window = NULL; +GtkWidget *ConfDlg; +GtkWidget *AboutDlg; +GtkWidget *FileSel; + +GtkAccelGroup *AccelGroup; + +typedef struct { + GtkWidget *Combo; + GList *glist; + char plist[255][255]; + int plugins; +} PluginConf; + +PluginConf GpuConfS; +PluginConf SpuConfS; +PluginConf CdrConfS; +PluginConf Pad1ConfS; +PluginConf Pad2ConfS; +PluginConf BiosConfS; + +void StartGui() { + Window = create_MainWindow(); + gtk_window_set_title(GTK_WINDOW(Window), "P©SX"); + + gtk_widget_show_all(Window); + gtk_main(); +} + +void RunGui() { + StartGui(); +} + +int destroy=0; + +void OnDestroy() { + if (!destroy) OnFile_Exit(); +} + +void ConfigurePlugins() { + if (!UseGui) return; + OnConf_Conf(); +} + +void ConfigureMemcards() { + OnConf_Mcds(); +} + +void OnRunExe_Ok() { + gchar *File; + char exe[256]; + + File = gtk_file_selection_get_filename(GTK_FILE_SELECTION(FileSel)); + strcpy(exe, File); + gtk_widget_destroy(FileSel); + destroy=1; + gtk_widget_destroy(Window); + destroy=0; + gtk_main_quit(); + while (gtk_events_pending()) gtk_main_iteration(); + OpenPlugins(); + SysReset(); + needreset = 0; + Load(exe); + psxCpu->Execute(); +} + +void OnRunExe_Cancel() { + gtk_widget_destroy(FileSel); +} + +void OnFile_RunExe() { + GtkWidget *Ok,*Cancel; + + FileSel = gtk_file_selection_new("Select Psx Exe File"); + + Ok = GTK_FILE_SELECTION(FileSel)->ok_button; + gtk_signal_connect (GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnRunExe_Ok), NULL); + gtk_widget_show(Ok); + + Cancel = GTK_FILE_SELECTION(FileSel)->cancel_button; + gtk_signal_connect (GTK_OBJECT(Cancel), "clicked", GTK_SIGNAL_FUNC(OnRunExe_Cancel), NULL); + gtk_widget_show(Cancel); + + gtk_widget_show(FileSel); + gdk_window_raise(FileSel->window); +} + +void OnFile_RunCd() { + LoadCdBios = 0; + destroy=1; + gtk_widget_destroy(Window); + destroy=0; + gtk_main_quit(); + while (gtk_events_pending()) gtk_main_iteration(); + OpenPlugins(); + SysReset(); + needreset = 0; + CheckCdrom(); + if (LoadCdrom() == -1) { + ClosePlugins(); + SysMessage("Could not load Cdrom\n"); + return; + } + psxCpu->Execute(); +} + +void OnFile_RunCdBios() { + LoadCdBios = 1; + destroy=1; + gtk_widget_destroy(Window); + destroy=0; + gtk_main_quit(); + while (gtk_events_pending()) gtk_main_iteration(); + OpenPlugins(); + SysReset(); + needreset = 0; + CheckCdrom(); + psxCpu->Execute(); +} + +void OnFile_Exit() { + DIR *dir; + struct dirent *ent; + void *Handle; + char plugin[256]; + + // with this the problem with plugins that are linked with the pthread + // library is solved + + dir = opendir(Config.PluginsDir); + if (dir != NULL) { + while ((ent = readdir(dir)) != NULL) { + sprintf (plugin, "%s%s", Config.PluginsDir, ent->d_name); + + if (strstr(plugin, ".so") == NULL) continue; + Handle = dlopen(plugin, RTLD_NOW); + if (Handle == NULL) continue; + } + } + + printf ("P©SX Quitting\n"); + if (UseGui) gtk_main_quit(); + SysClose(); + if (UseGui) gtk_exit(0); + else exit(0); +} + +void OnEmu_Run() { + destroy=1; + gtk_widget_destroy(Window); + destroy=0; + gtk_main_quit(); + while (gtk_events_pending()) gtk_main_iteration(); + OpenPlugins(); + if (needreset) { SysReset(); needreset = 0; } + psxCpu->Execute(); +} + +void OnEmu_Reset() { + needreset = 1; +} + +void OnConf_Gpu() { + gtk_widget_set_sensitive(Window, FALSE); + GPU_configure(); + gtk_widget_set_sensitive(Window, TRUE); +} + +void OnConf_Spu() { + gtk_widget_set_sensitive(Window, FALSE); + SPU_configure(); + gtk_widget_set_sensitive(Window, TRUE); +} + +void OnConf_Cdr() { + gtk_widget_set_sensitive(Window, FALSE); + CDR_configure(); + gtk_widget_set_sensitive(Window, TRUE); +} + +void OnConf_Pads() { + gtk_widget_set_sensitive(Window, FALSE); + PAD1_configure(); + if (strcmp(Config.Pad1, Config.Pad2)) PAD2_configure(); + gtk_widget_set_sensitive(Window, TRUE); +} + +GtkWidget *McdDlg; +GtkWidget *Entry1,*Entry2; +GtkWidget *List1,*List2; +GtkWidget *BtnPaste; +GTimer *Gtimer; +int timer; +McdBlock Blocks[2][15]; +int IconC[2][15]; + +void SetIcon(short *icon, GtkWidget *List, int i) { + GdkPixmap *pixmap; + GdkImage *image; + GdkVisual *visual; + GdkGC *gc; + int x, y, c; + + visual = gdk_window_get_visual(McdDlg->window); + + if (visual->depth == 8) return; + + image = gdk_image_new(GDK_IMAGE_NORMAL, visual, 16, 16); + + for (y=0; y<16; y++) { + for (x=0; x<16; x++) { + c = icon[y*16+x]; + c = ((c&0x001f) << 10) | ((c&0x7c00) >> 10) | (c&0x03e0); + if (visual->depth == 16) + c = (c&0x001f) | ((c&0x7c00) << 1) | ((c&0x03e0) << 1); + else if (visual->depth == 24 || visual->depth == 32) + c = ((c&0x001f) << 3) | ((c&0x03e0) << 6) | ((c&0x7c00) << 9); + + gdk_image_put_pixel(image, x, y, c); + } + } + + pixmap = gdk_pixmap_new(McdDlg->window, 16, 16, visual->depth); + + gc = gdk_gc_new(pixmap); + gdk_draw_image(pixmap, gc, image, 0, 0, 0, 0, 16, 16); + gdk_gc_destroy(gc); + gdk_image_destroy(image); + + gtk_clist_set_pixmap(GTK_CLIST(List), i-1, 0, pixmap, NULL); +} + +void LoadListItems(int mcd, GtkWidget *List) { + int i; + + gtk_clist_clear(GTK_CLIST(List)); + + for (i=1; i<16; i++) { + McdBlock *Info; + gchar *text[5]; + + Info = &Blocks[mcd-1][i-1]; + IconC[mcd-1][i-1] = 0; + + if ((Info->Flags & 0xF0) == 0xA0) { + if ((Info->Flags & 0xF) >= 1 && + (Info->Flags & 0xF) <= 3) { + text[2] = "Deleted"; + } else text[2] = "Free"; + } else if ((Info->Flags & 0xF0) == 0x50) + text[2] = "Used"; + else { text[2] = "Free"; } + + text[0] = ""; + text[1] = Info->Title; + text[3] = Info->ID; + text[4] = Info->Name; + + gtk_clist_insert(GTK_CLIST(List), i-1, text); + + if (Info->IconCount == 0) continue; + + SetIcon(Info->Icon, List, i); + } +} + +void UpdateListItems(int mcd, GtkWidget *List) { + int i,j; + + for (i=1; i<16; i++) { + McdBlock *Info; + gchar *text[5]; + + Info = &Blocks[mcd-1][i-1]; + IconC[mcd-1][i-1] = 0; + + if ((Info->Flags & 0xF0) == 0xA0) { + if ((Info->Flags & 0xF) >= 1 && + (Info->Flags & 0xF) <= 3) { + text[2] = "Deleted"; + } else text[2] = "Free"; + } else if ((Info->Flags & 0xF0) == 0x50) + text[2] = "Used"; + else { text[2] = "Free"; } + + text[0] = ""; + text[1] = Info->Title; + text[3] = Info->ID; + text[4] = Info->Name; + + for (j=0; j<5; j++) + gtk_clist_set_text(GTK_CLIST(List), i-1, j, text[j]); + + if (Info->IconCount == 0) continue; + + SetIcon(Info->Icon, List, i); + } +} + +void LoadMcdDlg() { + int i; + + for (i=1; i<16; i++) GetMcdBlockInfo(1, i, &Blocks[0][i-1]); + for (i=1; i<16; i++) GetMcdBlockInfo(2, i, &Blocks[1][i-1]); + LoadListItems(1, List1); + LoadListItems(2, List2); +} + +void UpdateMcdDlg() { + int i; + + for (i=1; i<16; i++) GetMcdBlockInfo(1, i, &Blocks[0][i-1]); + for (i=1; i<16; i++) GetMcdBlockInfo(2, i, &Blocks[1][i-1]); + UpdateListItems(1, List1); + UpdateListItems(2, List2); +} + +void StopTimer() { + g_timer_stop(Gtimer); timer = 0; +} + +void OnMcd_Ok() { + char *tmp; + + StopTimer(); + + tmp = gtk_entry_get_text(GTK_ENTRY(Entry1)); + strcpy(Config.Mcd1, tmp); + tmp = gtk_entry_get_text(GTK_ENTRY(Entry2)); + strcpy(Config.Mcd2, tmp); + + SaveConfig(); + LoadMcds(Config.Mcd1, Config.Mcd2); + + gtk_widget_destroy(McdDlg); + if (Window != NULL) gtk_widget_set_sensitive(Window, TRUE); +// gtk_main_quit(); +} + +void OnMcd_Cancel() { + StopTimer(); + + LoadMcds(Config.Mcd1, Config.Mcd2); + + gtk_widget_destroy(McdDlg); + if (Window != NULL) gtk_widget_set_sensitive(Window, TRUE); +// gtk_main_quit(); +} + +void OnMcdFS1_Ok() { + gchar *File; + + File = gtk_file_selection_get_filename(GTK_FILE_SELECTION(FileSel)); + gtk_entry_set_text(GTK_ENTRY(Entry1), File); + + LoadMcd(1, File); + UpdateMcdDlg(); + + gtk_widget_destroy(FileSel); +} + +void OnMcdFS2_Ok() { + gchar *File; + + File = gtk_file_selection_get_filename(GTK_FILE_SELECTION(FileSel)); + gtk_entry_set_text(GTK_ENTRY(Entry2), File); + + LoadMcd(2, File); + UpdateMcdDlg(); + + gtk_widget_destroy(FileSel); +} + +void OnMcdFS_Cancel() { + gtk_widget_destroy(FileSel); +} + +void OnMcd_FS1() { + GtkWidget *Ok,*Cancel; + + FileSel = gtk_file_selection_new("Select Psx Mcd File"); + gtk_file_selection_set_filename(GTK_FILE_SELECTION(FileSel), gtk_entry_get_text(GTK_ENTRY(Entry1))); + + Ok = GTK_FILE_SELECTION(FileSel)->ok_button; + gtk_signal_connect (GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnMcdFS1_Ok), NULL); + gtk_widget_show(Ok); + + Cancel = GTK_FILE_SELECTION(FileSel)->cancel_button; + gtk_signal_connect (GTK_OBJECT(Cancel), "clicked", GTK_SIGNAL_FUNC(OnMcdFS_Cancel), NULL); + gtk_widget_show(Cancel); + + gtk_widget_show(FileSel); + gdk_window_raise(FileSel->window); +} + +void OnMcd_FS2() { + GtkWidget *Ok,*Cancel; + + FileSel = gtk_file_selection_new("Select Psx Mcd File"); + gtk_file_selection_set_filename(GTK_FILE_SELECTION(FileSel), gtk_entry_get_text(GTK_ENTRY(Entry2))); + + Ok = GTK_FILE_SELECTION(FileSel)->ok_button; + gtk_signal_connect (GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnMcdFS2_Ok), NULL); + gtk_widget_show(Ok); + + Cancel = GTK_FILE_SELECTION(FileSel)->cancel_button; + gtk_signal_connect (GTK_OBJECT(Cancel), "clicked", GTK_SIGNAL_FUNC(OnMcdFS_Cancel), NULL); + gtk_widget_show(Cancel); + + gtk_widget_show(FileSel); + gdk_window_raise(FileSel->window); +} + +GtkWidget *MsgBoxDlg; +int yes; + +void OnMsgBox_Yes() { + yes = 1; + gtk_widget_destroy(MsgBoxDlg); + gtk_main_quit(); +} + +void OnMsgBox_No() { + yes = 0; + gtk_widget_destroy(MsgBoxDlg); + gtk_main_quit(); +} + +int MessageBox(char *msg, char *title) { + GtkWidget *Ok,*Txt; + GtkWidget *Box,*Box1; + int w; + + if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = 0; + + w = strlen(msg) * 6 + 20; + + MsgBoxDlg = gtk_window_new (GTK_WINDOW_DIALOG); + gtk_widget_set_usize(MsgBoxDlg, w, 70); + gtk_window_set_position(GTK_WINDOW(MsgBoxDlg), GTK_WIN_POS_CENTER); + gtk_window_set_title(GTK_WINDOW(MsgBoxDlg), title); + gtk_container_set_border_width(GTK_CONTAINER(MsgBoxDlg), 0); + + Box = gtk_vbox_new(0, 0); + gtk_container_add(GTK_CONTAINER(MsgBoxDlg), Box); + gtk_widget_show(Box); + + Txt = gtk_label_new(msg); + + gtk_box_pack_start(GTK_BOX(Box), Txt, FALSE, FALSE, 5); + gtk_widget_show(Txt); + + Box1 = gtk_hbutton_box_new(); + gtk_box_pack_start(GTK_BOX(Box), Box1, FALSE, FALSE, 0); + gtk_widget_show(Box1); + + Ok = gtk_button_new_with_label("Yes"); + gtk_signal_connect (GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnMsgBox_Yes), NULL); + gtk_container_add(GTK_CONTAINER(Box1), Ok); + GTK_WIDGET_SET_FLAGS(Ok, GTK_CAN_DEFAULT); + gtk_widget_show(Ok); + + Ok = gtk_button_new_with_label("No"); + gtk_signal_connect (GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnMsgBox_No), NULL); + gtk_container_add(GTK_CONTAINER(Box1), Ok); + GTK_WIDGET_SET_FLAGS(Ok, GTK_CAN_DEFAULT); + gtk_widget_show(Ok); + + gtk_widget_show(MsgBoxDlg); + + gtk_main(); + + return yes; +} + +void OnMcd_Format1() { + char *str; + + if (MessageBox("Are you sure you want to format this Memory Card?", "Confirmation") == 0) return; + str = gtk_entry_get_text(GTK_ENTRY(Entry1)); + CreateMcd(str); + LoadMcd(1, str); + UpdateMcdDlg(); +} + +void OnMcd_Format2() { + char *str; + + if (MessageBox("Are you sure you want to format this Memory Card?", "Confirmation") == 0) return; + str = gtk_entry_get_text(GTK_ENTRY(Entry2)); + CreateMcd(str); + LoadMcd(2, str); + UpdateMcdDlg(); +} + +void OnMcd_Reload1() { + char *str; + + str = gtk_entry_get_text(GTK_ENTRY(Entry1)); + LoadMcd(1, str); + UpdateMcdDlg(); +} + +void OnMcd_Reload2() { + char *str; + + str = gtk_entry_get_text(GTK_ENTRY(Entry2)); + LoadMcd(2, str); + UpdateMcdDlg(); +} + +static int copy = 0, copymcd = 0; + +void OnMcd_CopyTo1() { + int i = GTK_CLIST(List2)->focus_row; + + copy = i; + copymcd = 1; + + gtk_widget_set_sensitive(BtnPaste, TRUE); +} + +void OnMcd_CopyTo2() { + int i = GTK_CLIST(List1)->focus_row; + + copy = i; + copymcd = 2; + + gtk_widget_set_sensitive(BtnPaste, TRUE); +} + +void OnMcd_Paste() { + int i; + char *str; + + if (MessageBox("Are you sure you want to paste this selection?", "Confirmation") == 0) return; + + if (copymcd == 1) { + str = gtk_entry_get_text(GTK_ENTRY(Entry1)); + i = GTK_CLIST(List1)->focus_row; + + // save dir data + save data + memcpy(Mcd1Data + (i+1) * 128, Mcd2Data + (copy+1) * 128, 128); + SaveMcd(str, Mcd1Data, (i+1) * 128, 128); + memcpy(Mcd1Data + (i+1) * 1024 * 8, Mcd2Data + (copy+1) * 1024 * 8, 1024 * 8); + SaveMcd(str, Mcd1Data, (i+1) * 1024 * 8, 1024 * 8); + } else { // 2 + str = gtk_entry_get_text(GTK_ENTRY(Entry2)); + i = GTK_CLIST(List2)->focus_row; + + // save dir data + save data + memcpy(Mcd2Data + (i+1) * 128, Mcd1Data + (copy+1) * 128, 128); + SaveMcd(str, Mcd2Data, (i+1) * 128, 128); + memcpy(Mcd2Data + (i+1) * 1024 * 8, Mcd1Data + (copy+1) * 1024 * 8, 1024 * 8); + SaveMcd(str, Mcd2Data, (i+1) * 1024 * 8, 1024 * 8); + } + + UpdateMcdDlg(); +} + +void OnMcd_Delete1() { + McdBlock *Info; + int mcd = 1; + int i, xor = 0, j; + unsigned char *data, *ptr; + char *str; + + str = gtk_entry_get_text(GTK_ENTRY(Entry1)); + i = GTK_CLIST(List1)->focus_row; + data = Mcd1Data; + + i++; + + ptr = data + i * 128; + + Info = &Blocks[mcd-1][i-1]; + + if ((Info->Flags & 0xF0) == 0xA0) { + if ((Info->Flags & 0xF) >= 1 && + (Info->Flags & 0xF) <= 3) { // deleted + *ptr = 0x50 | (Info->Flags & 0xF); + } else return; + } else if ((Info->Flags & 0xF0) == 0x50) { // used + *ptr = 0xA0 | (Info->Flags & 0xF); + } else { return; } + + for (j=0; j<127; j++) xor^=*ptr++; + *ptr = xor; + + SaveMcd(str, data, i * 128, 128); + UpdateMcdDlg(); +} + +void OnMcd_Delete2() { + McdBlock *Info; + int mcd = 2; + int i, xor = 0, j; + unsigned char *data, *ptr; + char *str; + + str = gtk_entry_get_text(GTK_ENTRY(Entry2)); + i = GTK_CLIST(List2)->focus_row; + data = Mcd2Data; + + i++; + + ptr = data + i * 128; + + Info = &Blocks[mcd-1][i-1]; + + if ((Info->Flags & 0xF0) == 0xA0) { + if ((Info->Flags & 0xF) >= 1 && + (Info->Flags & 0xF) <= 3) { // deleted + *ptr = 0x50 | (Info->Flags & 0xF); + } else return; + } else if ((Info->Flags & 0xF0) == 0x50) { // used + *ptr = 0xA0 | (Info->Flags & 0xF); + } else { return; } + + for (j=0; j<127; j++) xor^=*ptr++; + *ptr = xor; + + SaveMcd(str, data, i * 128, 128); + UpdateMcdDlg(); +} + +void UpdateMcdIcon(int mcd, GtkWidget *List) { + int i; + + for (i=1; i<16; i++) { + McdBlock *Info; + int *count; + + Info = &Blocks[mcd-1][i-1]; + count = &IconC[mcd-1][i-1]; + + if (Info->IconCount <= 1) continue; + + (*count)++; + if (*count == Info->IconCount) *count = 0; + + SetIcon(&Info->Icon[*count*16*16], List, i); + } +} + +void OnConf_Mcds() { + McdDlg = create_McdsDlg(); + gtk_window_set_title(GTK_WINDOW(McdDlg), "P©SX Memcard Manager"); + + Entry1 = lookup_widget(McdDlg, "GtkEntry_Mcd1"); + if (!strlen(Config.Mcd1)) strcpy(Config.Mcd1, "memcards/Mcd001.mcr"); + gtk_entry_set_text(GTK_ENTRY(Entry1), Config.Mcd1); + + Entry2 = lookup_widget(McdDlg, "GtkEntry_Mcd2"); + if (!strlen(Config.Mcd2)) strcpy(Config.Mcd2, "memcards/Mcd002.mcr"); + gtk_entry_set_text(GTK_ENTRY(Entry2), Config.Mcd2); + + List1 = lookup_widget(McdDlg, "GtkCList_McdList1"); + List2 = lookup_widget(McdDlg, "GtkCList_McdList2"); + + BtnPaste = lookup_widget(McdDlg, "GtkButton_McdPaste"); + gtk_widget_set_sensitive(BtnPaste, FALSE); + + gtk_clist_set_column_justification(GTK_CLIST(List1), 0, GTK_JUSTIFY_CENTER); + gtk_clist_set_column_justification(GTK_CLIST(List2), 0, GTK_JUSTIFY_CENTER); + gtk_clist_set_column_justification(GTK_CLIST(List1), 2, GTK_JUSTIFY_CENTER); + gtk_clist_set_column_justification(GTK_CLIST(List2), 2, GTK_JUSTIFY_CENTER); + + gtk_widget_show_all(McdDlg); + + LoadMcdDlg(); + + if (Window != NULL) gtk_widget_set_sensitive(Window, FALSE); + + Gtimer = g_timer_new(); timer = 1; + + while (gtk_events_pending()) gtk_main_iteration(); + + while (timer) { + unsigned long usecs; + + g_timer_elapsed(Gtimer, &usecs); + if (usecs > 250000) { + UpdateMcdIcon(1, List1); + UpdateMcdIcon(2, List2); + g_timer_reset(Gtimer); + } + + while (gtk_events_pending()) gtk_main_iteration(); + } +} + +GtkWidget *CpuDlg; +GtkWidget *PsxCombo; +GList *psxglist; +char *psxtypes[] = { + "NTSC", + "PAL" +}; + +void OnCpu_Ok() { + GtkWidget *Btn; + char *tmp; + long t; + + tmp = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(PsxCombo)->entry)); + + if (!strcmp("NTSC",tmp)) Config.PsxType = 0; + else Config.PsxType = 1; // pal + + Btn = lookup_widget(CpuDlg, "GtkCheckButton_Xa"); + Config.Xa = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(Btn)); + + Btn = lookup_widget(CpuDlg, "GtkCheckButton_Sio"); + Config.Sio = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(Btn)); + + Btn = lookup_widget(CpuDlg, "GtkCheckButton_Mdec"); + Config.Mdec = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(Btn)); + + Btn = lookup_widget(CpuDlg, "GtkCheckButton_Cdda"); + Config.Cdda = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(Btn)); + + Btn = lookup_widget(CpuDlg, "GtkCheckButton_PsxAuto"); + Config.PsxAuto = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(Btn)); + + t = Config.Cpu; + Btn = lookup_widget(CpuDlg, "GtkCheckButton_Cpu"); + Config.Cpu = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(Btn)); + if (t != Config.Cpu) { + psxCpu->Shutdown(); + if (Config.Cpu) + psxCpu = &psxInt; + else psxCpu = &psxRec; + if (psxCpu->Init() == -1) { + SysClose(); + exit(1); + } + psxCpu->Reset(); + } + + Btn = lookup_widget(CpuDlg, "GtkCheckButton_PsxOut"); + Config.PsxOut = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(Btn)); + + Btn = lookup_widget(CpuDlg, "GtkCheckButton_SpuIrq"); + Config.SpuIrq = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(Btn)); + + Btn = lookup_widget(CpuDlg, "GtkCheckButton_CdTiming"); + Config.CdTiming = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(Btn)); + + gtk_widget_destroy(CpuDlg); + + SaveConfig(); + if (Window != NULL) gtk_widget_set_sensitive(Window, TRUE); + gtk_main_quit(); +} + +void OnCpu_Cancel() { + gtk_widget_destroy(CpuDlg); + if (Window != NULL) gtk_widget_set_sensitive(Window, TRUE); + gtk_main_quit(); +} + + +void OnConf_Cpu() { + GtkWidget *Btn; + int i; + + CpuDlg = create_CpuDlg(); + gtk_window_set_title(GTK_WINDOW(CpuDlg), "P©SX Configuration"); + + psxglist = NULL; + for (i=0;i<2;i++) + psxglist = g_list_append(psxglist, psxtypes[i]); + PsxCombo = lookup_widget(CpuDlg, "GtkCombo_PsxType"); + gtk_combo_set_popdown_strings(GTK_COMBO(PsxCombo), psxglist); + gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(PsxCombo)->entry), psxtypes[Config.PsxType]); + + Btn = lookup_widget(CpuDlg, "GtkCheckButton_Xa"); + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(Btn), Config.Xa); + + Btn = lookup_widget(CpuDlg, "GtkCheckButton_Sio"); + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(Btn), Config.Sio); + + Btn = lookup_widget(CpuDlg, "GtkCheckButton_Mdec"); + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(Btn), Config.Mdec); + + Btn = lookup_widget(CpuDlg, "GtkCheckButton_Cdda"); + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(Btn), Config.Cdda); + + Btn = lookup_widget(CpuDlg, "GtkCheckButton_PsxAuto"); + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(Btn), Config.PsxAuto); + + Btn = lookup_widget(CpuDlg, "GtkCheckButton_Cpu"); + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(Btn), Config.Cpu); + + Btn = lookup_widget(CpuDlg, "GtkCheckButton_PsxOut"); + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(Btn), Config.PsxOut); + + Btn = lookup_widget(CpuDlg, "GtkCheckButton_SpuIrq"); + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(Btn), Config.SpuIrq); + + Btn = lookup_widget(CpuDlg, "GtkCheckButton_CdTiming"); + gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(Btn), Config.CdTiming); + + gtk_widget_show_all(CpuDlg); + if (Window != NULL) gtk_widget_set_sensitive(Window, FALSE); + gtk_main(); +} + +#define FindComboText(combo,list,conf) \ + if (strlen(conf) > 0) { \ + int i; \ + for (i=2;i<255;i+=2) { \ + if (!strcmp(conf, list[i-2])) { \ + gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(combo)->entry), list[i-1]); \ + break; \ + } \ + } \ + } + +#define GetComboText(combo,list,conf) \ + { \ + int i; \ + char *tmp = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo)->entry)); \ + for (i=2;i<255;i+=2) { \ + if (!strcmp(tmp, list[i-1])) { \ + strcpy(conf, list[i-2]); \ + break; \ + } \ + } \ + } + +void OnConfConf_Ok() { + GetComboText(GpuConfS.Combo, GpuConfS.plist, Config.Gpu); + GetComboText(SpuConfS.Combo, SpuConfS.plist, Config.Spu); + GetComboText(CdrConfS.Combo, CdrConfS.plist, Config.Cdr); + GetComboText(Pad1ConfS.Combo, Pad1ConfS.plist, Config.Pad1); + GetComboText(Pad2ConfS.Combo, Pad2ConfS.plist, Config.Pad2); + GetComboText(BiosConfS.Combo, BiosConfS.plist, Config.Bios); + + SaveConfig(); + + ReleasePlugins(); + LoadPlugins(); + + needreset = 1; + gtk_widget_destroy(ConfDlg); + if (Window != NULL) gtk_widget_set_sensitive(Window, TRUE); + gtk_main_quit(); +} + +void OnConfConf_Cancel() { + gtk_widget_destroy(ConfDlg); + if (Window != NULL) gtk_widget_set_sensitive(Window, TRUE); + gtk_main_quit(); +} + +#define ConfPlugin(src, confs, plugin, name) \ + void *drv; \ + src conf; \ + char file[256]; \ + \ + GetComboText(confs.Combo, confs.plist, plugin); \ + strcpy(file, Config.PluginsDir); \ + strcat(file, plugin); \ + gtk_widget_set_sensitive(ConfDlg, FALSE); \ + drv = SysLoadLibrary(file); \ + if (drv == NULL) return; \ + conf = (src) SysLoadSym(drv, name); \ + if (SysLibError() == NULL) conf(); \ + else SysMessage("Plugin doesn't needs to be configured"); \ + SysCloseLibrary(drv); \ + gtk_widget_set_sensitive(ConfDlg, TRUE); + +#define TestPlugin(src, confs, plugin, name) \ + void *drv; \ + src conf; \ + int ret = 0; \ + char file[256]; \ + \ + GetComboText(confs.Combo, confs.plist, plugin); \ + strcpy(file, Config.PluginsDir); \ + strcat(file, plugin); \ + gtk_widget_set_sensitive(ConfDlg, FALSE); \ + drv = SysLoadLibrary(file); \ + if (drv == NULL) return; \ + conf = (src) SysLoadSym(drv, name); \ + if (SysLibError() == NULL) ret = conf(); \ + SysCloseLibrary(drv); \ + SysMessage("This plugin reports that should %swork correctly", ret == 0 ? "" : "not "); \ + gtk_widget_set_sensitive(ConfDlg, TRUE); + +void OnConfConf_GpuConf() { + ConfPlugin(GPUconfigure, GpuConfS, Config.Gpu, "GPUconfigure"); +} + +void OnConfConf_GpuTest() { + TestPlugin(GPUtest, GpuConfS, Config.Gpu, "GPUtest"); +} + +void OnConfConf_GpuAbout() { + ConfPlugin(GPUabout, GpuConfS, Config.Gpu, "GPUabout"); +} + +void OnConfConf_SpuConf() { + ConfPlugin(SPUconfigure, SpuConfS, Config.Spu, "SPUconfigure"); +} + +void OnConfConf_SpuTest() { + TestPlugin(SPUtest, SpuConfS, Config.Spu, "SPUtest"); +} + +void OnConfConf_SpuAbout() { + ConfPlugin(SPUabout, SpuConfS, Config.Spu, "SPUabout"); +} + +void OnConfConf_CdrConf() { + ConfPlugin(CDRconfigure, CdrConfS, Config.Cdr, "CDRconfigure"); +} + +void OnConfConf_CdrTest() { + TestPlugin(CDRtest, CdrConfS, Config.Cdr, "CDRtest"); +} + +void OnConfConf_CdrAbout() { + ConfPlugin(CDRabout, CdrConfS, Config.Cdr, "CDRabout"); +} + +void OnConfConf_Pad1Conf() { + ConfPlugin(PADconfigure, Pad1ConfS, Config.Pad1, "PADconfigure"); +} + +void OnConfConf_Pad1Test() { + TestPlugin(PADtest, Pad1ConfS, Config.Pad1, "PADtest"); +} + +void OnConfConf_Pad1About() { + ConfPlugin(PADabout, Pad1ConfS, Config.Pad1, "PADabout"); +} + +void OnConfConf_Pad2Conf() { + ConfPlugin(PADconfigure, Pad2ConfS, Config.Pad2, "PADconfigure"); +} + +void OnConfConf_Pad2Test() { + TestPlugin(PADtest, Pad2ConfS, Config.Pad2, "PADtest"); +} + +void OnConfConf_Pad2About() { + ConfPlugin(PADabout, Pad2ConfS, Config.Pad2, "PADabout"); +} + +void OnPluginsPath_Ok() { + gchar *File; + + File = gtk_file_selection_get_filename(GTK_FILE_SELECTION(FileSel)); + strcpy(Config.PluginsDir, File); + if (Config.PluginsDir[strlen(Config.PluginsDir)-1] != '/') + strcat(Config.PluginsDir, "/"); + + FindPlugins(); + + gtk_widget_destroy(FileSel); +} + +void OnPluginsPath_Cancel() { + gtk_widget_destroy(FileSel); +} + +void OnConfConf_PluginsPath() { + GtkWidget *Ok,*Cancel; + + FileSel = gtk_file_selection_new("Select Plugins Directory"); + + Ok = GTK_FILE_SELECTION(FileSel)->ok_button; + gtk_signal_connect (GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnPluginsPath_Ok), NULL); + gtk_widget_show(Ok); + + Cancel = GTK_FILE_SELECTION(FileSel)->cancel_button; + gtk_signal_connect (GTK_OBJECT(Cancel), "clicked", GTK_SIGNAL_FUNC(OnPluginsPath_Cancel), NULL); + gtk_widget_show(Cancel); + + gtk_widget_show(FileSel); + gdk_window_raise(FileSel->window); +} + +void OnBiosPath_Ok() { + gchar *File; + + File = gtk_file_selection_get_filename(GTK_FILE_SELECTION(FileSel)); + strcpy(Config.BiosDir, File); + if (Config.BiosDir[strlen(Config.BiosDir)-1] != '/') + strcat(Config.BiosDir, "/"); + + FindPlugins(); + + gtk_widget_destroy(FileSel); +} + +void OnBiosPath_Cancel() { + gtk_widget_destroy(FileSel); +} + +void OnConfConf_BiosPath() { + GtkWidget *Ok,*Cancel; + + FileSel = gtk_file_selection_new("Select Bios Directory"); + + Ok = GTK_FILE_SELECTION(FileSel)->ok_button; + gtk_signal_connect (GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnBiosPath_Ok), NULL); + gtk_widget_show(Ok); + + Cancel = GTK_FILE_SELECTION(FileSel)->cancel_button; + gtk_signal_connect (GTK_OBJECT(Cancel), "clicked", GTK_SIGNAL_FUNC(OnBiosPath_Cancel), NULL); + gtk_widget_show(Cancel); + + gtk_widget_show(FileSel); + gdk_window_raise(FileSel->window); +} + +void OnConf_Conf() { + ConfDlg = create_ConfDlg(); + gtk_window_set_title(GTK_WINDOW(ConfDlg), "P©SX Configuration"); + + FindPlugins(); + + gtk_widget_show_all(ConfDlg); + if (Window != NULL) gtk_widget_set_sensitive(Window, FALSE); + gtk_main(); +} + +void OnHelp_Help() { +} + +void OnHelpAbout_Ok() { + gtk_widget_destroy(AboutDlg); + if (Window != NULL) gtk_widget_set_sensitive(Window, TRUE); + gtk_main_quit(); +} + +void OnHelp_About() { + GtkWidget *Label; + + AboutDlg = create_AboutDlg(); + gtk_window_set_title(GTK_WINDOW(AboutDlg), "About P©SX"); + + Label = lookup_widget(AboutDlg, "GtkAbout_LabelVersion"); + gtk_label_set_text(GTK_LABEL(Label), + "P©SX For Linux\n" + "Version " PCSX_VERSION); + + Label = lookup_widget(AboutDlg, "GtkAbout_LabelAuthors"); + gtk_label_set_text(GTK_LABEL(Label), + "PCSX a psx emulator\n\n" + "written by:\n" + "main coder: linuzappz\n" + "co-coders: shadow\n" + "ex-coders: Nocomp, Pete Bernett, nik3d\n" + "Webmaster: AkumaX"); + + Label = lookup_widget(AboutDlg, "GtkAbout_LabelGreets"); + gtk_label_set_text(GTK_LABEL(Label), + "Greets to: Duddie, Tratax, Kazzuya, JNS, Bobbi, Psychojak and Shunt\n" + "Special thanks to:\n" + "Twin (we Love you twin0r), Roor (love for you too),\n" + "calb (Thanks for help :) ), now3d (for great help to my psxdev stuff :) )"); + + gtk_widget_show_all(AboutDlg); + if (Window != NULL) gtk_widget_set_sensitive(Window, FALSE); + gtk_main(); +} + +#define ComboAddPlugin(type) { \ + ##type##ConfS.plugins+=2; \ + strcpy(##type##ConfS.plist[##type##ConfS.plugins-1], name); \ + strcpy(##type##ConfS.plist[##type##ConfS.plugins-2], ent->d_name); \ + ##type##ConfS.glist = g_list_append(##type##ConfS.glist, ##type##ConfS.plist[##type##ConfS.plugins-1]); \ +} + +#define ConfCreatePConf(name, type) \ + if (type##ConfS.glist != NULL) { \ + type##ConfS.Combo = lookup_widget(ConfDlg, "GtkCombo_" name); \ + gtk_combo_set_popdown_strings(GTK_COMBO(type##ConfS.Combo), type##ConfS.glist); \ + FindComboText(type##ConfS.Combo, type##ConfS.plist, Config.##type##); \ + } + +void FindPlugins() { + DIR *dir; + struct dirent *ent; + void *Handle; + char plugin[256],name[256]; + + GpuConfS.plugins = 0; SpuConfS.plugins = 0; CdrConfS.plugins = 0; + Pad1ConfS.plugins = 0; Pad2ConfS.plugins = 0; BiosConfS.plugins = 0; + GpuConfS.glist = NULL; SpuConfS.glist = NULL; CdrConfS.glist = NULL; + Pad1ConfS.glist = NULL; Pad2ConfS.glist = NULL; BiosConfS.glist = NULL; + + dir = opendir(Config.PluginsDir); + if (dir == NULL) { + SysMessage("Could not open '%s' directory\n", Config.PluginsDir); + return; + } + while ((ent = readdir(dir)) != NULL) { + long type,v; + + sprintf(plugin, "%s%s", Config.PluginsDir, ent->d_name); + + if (strstr(plugin, ".so") == NULL) continue; + Handle = dlopen(plugin, RTLD_NOW); + if (Handle == NULL) continue; + + PSE_getLibType = (PSEgetLibType) dlsym(Handle, "PSEgetLibType"); + if (dlerror() != NULL) { + if (strstr(plugin, "gpu") != NULL) type = PSE_LT_GPU; + else if (strstr(plugin, "cdr") != NULL) type = PSE_LT_CDR; + else if (strstr(plugin, "spu") != NULL) type = PSE_LT_SPU; + else if (strstr(plugin, "pad") != NULL) type = PSE_LT_PAD; + else continue; + } + else type = PSE_getLibType(); + + PSE_getLibName = (PSEgetLibName) dlsym(Handle, "PSEgetLibName"); + if (dlerror() == NULL) { + sprintf(name, "%s", PSE_getLibName()); + PSE_getLibVersion = (PSEgetLibVersion) dlsym(Handle, "PSEgetLibVersion"); + if (dlerror() == NULL) { + char ver[32]; + + v = PSE_getLibVersion(); + sprintf(ver, " %ld.%ld.%ld",v>>16,(v>>8)&0xff,v&0xff); + strcat(name, ver); + } + } + else strcpy(name, ent->d_name); + + if (type & PSE_LT_CDR) { + ComboAddPlugin(Cdr); + } + if (type & PSE_LT_GPU) { + ComboAddPlugin(Gpu); + } + if (type & PSE_LT_SPU) { + ComboAddPlugin(Spu); + } + if (type & PSE_LT_PAD) { + PADquery query = (PADquery)dlsym(Handle, "PADquery"); + if (query() & 0x1) { + ComboAddPlugin(Pad1); + } + if (query() & 0x2) { + ComboAddPlugin(Pad2); + } + } + } + closedir(dir); + + ConfCreatePConf("Gpu", Gpu); + ConfCreatePConf("Spu", Spu); + ConfCreatePConf("Pad1", Pad1); + ConfCreatePConf("Pad2", Pad2); + ConfCreatePConf("Cdr", Cdr); + + BiosConfS.plugins+=2; + strcpy(BiosConfS.plist[BiosConfS.plugins-1], "Internal HLE Bios"); + strcpy(BiosConfS.plist[BiosConfS.plugins-2], "HLE"); + BiosConfS.glist = g_list_append(BiosConfS.glist, BiosConfS.plist[BiosConfS.plugins-1]); + + dir = opendir(Config.BiosDir); + if (dir == NULL) { + SysMessage("Could not open '%s' directory\n", Config.BiosDir); + return; + } + + while ((ent = readdir(dir)) != NULL) { + struct stat buf; + + sprintf (plugin, "%s%s", Config.BiosDir, ent->d_name); + if (stat(plugin, &buf) == -1) continue; + if (buf.st_size != (1024*512)) continue; + + BiosConfS.plugins+=2; + strcpy(BiosConfS.plist[BiosConfS.plugins-1], ent->d_name); + strcpy(BiosConfS.plist[BiosConfS.plugins-2], ent->d_name); + BiosConfS.glist = g_list_append(BiosConfS.glist, BiosConfS.plist[BiosConfS.plugins-1]); + } + closedir(dir); + + ConfCreatePConf("Bios", Bios); +} + +GtkWidget *MsgDlg; + +void OnMsg_Ok() { + gtk_widget_destroy(MsgDlg); + gtk_main_quit(); +} + +void SysMessage(char *fmt, ...) { + GtkWidget *Ok,*Txt; + GtkWidget *Box,*Box1; + va_list list; + char msg[512]; + + va_start(list, fmt); + vsprintf(msg, fmt, list); + va_end(list); + + if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = 0; + + if (!UseGui) { printf ("%s\n",msg); return; } + + MsgDlg = gtk_window_new (GTK_WINDOW_DIALOG); + gtk_window_set_position(GTK_WINDOW(MsgDlg), GTK_WIN_POS_CENTER); + gtk_window_set_title(GTK_WINDOW(MsgDlg), "P©SX Msg"); + gtk_container_set_border_width(GTK_CONTAINER(MsgDlg), 5); + + Box = gtk_vbox_new(5, 0); + gtk_container_add(GTK_CONTAINER(MsgDlg), Box); + gtk_widget_show(Box); + + Txt = gtk_label_new(msg); + + gtk_box_pack_start(GTK_BOX(Box), Txt, FALSE, FALSE, 5); + gtk_widget_show(Txt); + + Box1 = gtk_hbutton_box_new(); + gtk_box_pack_start(GTK_BOX(Box), Box1, FALSE, FALSE, 0); + gtk_widget_show(Box1); + + Ok = gtk_button_new_with_label("Ok"); + gtk_signal_connect (GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnMsg_Ok), NULL); + gtk_container_add(GTK_CONTAINER(Box1), Ok); + GTK_WIDGET_SET_FLAGS(Ok, GTK_CAN_DEFAULT); + gtk_widget_show(Ok); + + gtk_widget_show(MsgDlg); + + gtk_main(); +} + diff --git a/PcsxSrc/Linux/Linux.h b/PcsxSrc/Linux/Linux.h new file mode 100644 index 0000000..57a0d8c --- /dev/null +++ b/PcsxSrc/Linux/Linux.h @@ -0,0 +1,39 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __LINUX_H__ +#define __LINUX_H__ + +#include "PsxCommon.h" +#include "Plugin.h" + +extern int UseGui; +char cfgfile[256]; + +int LoadConfig(); +void SaveConfig(); + +void StartGui(); +void RunGui(); + +void ConfigurePlugins(); +void ConfigureMemcards(); + +void PADhandleKey(int key); + +#endif /* __LINUX_H__ */ diff --git a/PcsxSrc/Linux/LnxMain.c b/PcsxSrc/Linux/LnxMain.c new file mode 100644 index 0000000..e0012f6 --- /dev/null +++ b/PcsxSrc/Linux/LnxMain.c @@ -0,0 +1,197 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Linux.h" +#include "Sio.h" + +static char PcsxHelp[] = { + "Pcsx " PCSX_VERSION "\n" + " pcsx [options] [file]\n" + "\toptions:\n" + "\t-runcd\t\tRuns CdRom\n" + "\t-runcdbios\tRuns CdRom Through Bios\n" + "\t-nogui\t\tDon't open GtkGui\n" + "\t-cfg FILE\tLoads desired configuration file (def:Pcsx.cfg)\n" + "\t-psxout\t\tEnable psx output\n" + "\t-load STATENUM\tLoads savestate STATENUM (1-5)\n" + "\t-h -help\tThis help\n" + "\tfile\t\tLoads file\n" +}; + +int UseGui = 1; + +int main(int argc, char *argv[]) { + char *file = NULL; + int runcd = 0; + int loadst = 0; + int i; + + strcpy(cfgfile, "Pcsx.cfg"); + + for (i=1; iExecute(); + + return 0; +} + +int SysInit() { + +#ifdef GTE_DUMP + gteLog = fopen("gteLog.txt","wb"); + setvbuf(gteLog, NULL, _IONBF, 0); +#endif + +#ifdef EMU_LOG +#ifndef LOG_STDOUT + emuLog = fopen("emuLog.txt","wb"); +#else + emuLog = stdout; +#endif + setvbuf(emuLog, NULL, _IONBF, 0); +#endif + + psxInit(); + + LoadPlugins(); + LoadMcds(Config.Mcd1, Config.Mcd2); + + return 0; +} + +void SysReset() { + psxReset(); +} + +void SysClose() { + psxShutdown(); + ReleasePlugins(); + + if (emuLog != NULL) fclose(emuLog); +} + +void SysPrintf(char *fmt, ...) { + va_list list; + char msg[512]; + + va_start(list, fmt); + vsprintf(msg, fmt, list); + va_end(list); + + if (Config.PsxOut) printf ("%s", msg); +#ifdef EMU_LOG + fprintf(emuLog, "%s", msg); +#endif +} + +void *SysLoadLibrary(char *lib) { + return dlopen(lib, RTLD_NOW); +} + +void *SysLoadSym(void *lib, char *sym) { + return dlsym(lib, sym); +} + +char *SysLibError() { + return dlerror(); +} + +void SysCloseLibrary(void *lib) { + dlclose(lib); +} + +void SysUpdate() { + PADhandleKey(PAD1_keypressed()); + PADhandleKey(PAD2_keypressed()); +} + +void SysRunGui() { + RunGui(); +} \ No newline at end of file diff --git a/PcsxSrc/Linux/Makefile b/PcsxSrc/Linux/Makefile new file mode 100644 index 0000000..bbf1b70 --- /dev/null +++ b/PcsxSrc/Linux/Makefile @@ -0,0 +1,62 @@ +# +# PCSX Makefile for Linux +# + +MAJ = 1 +MIN = 3 +VERSION = ${MAJ}.${MIN} + +all: pcsx + +CPU = ix86 + +CC = gcc +NASM = nasm +RM = rm -f +STRIP = strip + +OPTIMIZE = -O2 -fomit-frame-pointer -finline-functions -ffast-math +FLAGS = -D__LINUX__ -DPCSX_VERSION=\"${VERSION}\" +# this includes the option -rdynamic and we don't want that +LIBST = $(shell gtk-config --libs) +LIBS = $(subst -rdynamic, , ${LIBST}) -lz + +OBJS = ../PsxBios.o ../CdRom.o ../PsxCounters.o ../PsxDma.o ../DisR3000A.o \ + ../Spu.o ../Sio.o ../PsxHw.o ../Mdec.o ../PsxMem.o ../Misc.o \ + ../plugins.o ../Decode_XA.o ../R3000A.o ../PsxInterpreter.o \ + ../Gte.o ../PsxHLE.o +OBJS+= LnxMain.o Plugin.o Config.o GtkGui.o +OBJS+= GladeGui.o GladeFuncs.o #GladeCalls.o + +ifeq (${CPU}, ix86) + CC = pgcc + OPTIMIZE = -O4 -fomit-frame-pointer -finline-functions -ffast-math -fno-exceptions -march=pentiumpro + OBJS+= ../ix86/iR3000A.o ../ix86/ix86.o + FLAGS+= -D__i386__ +endif + +CFLAGS = -Wall ${OPTIMIZE} -I. -I.. -I/usr/include/g++ ${FLAGS} +CFLAGS+= $(shell gtk-config --cflags) +ASMFLAGS = -f elf ${FLAGS} -i./ -i../ + +pcsx: ${OBJS} + ${CC} ${CFLAGS} ${OBJS} -o pcsx ${LIBS} + ${STRIP} pcsx + +.PHONY: clean pcsx + +clean: + ${RM} *.o ../*.o ../${CPU}/*.o pcsx + +../%.o: ../%.c + ${CC} ${CFLAGS} -c -o $@ $< + +../${CPU}/%.o: ../${CPU}/%.asm + ${NASM} ${ASMFLAGS} -o $@ $< + +%.o: %.c + ${CC} ${CFLAGS} -c -o $@ $< + +../Cpu/ix86/%.o: ../Cpu/ix86/%.c + ${CC} ${CFLAGS} -c -o $@ $< + diff --git a/PcsxSrc/Linux/Plugin.c b/PcsxSrc/Linux/Plugin.c new file mode 100644 index 0000000..c305950 --- /dev/null +++ b/PcsxSrc/Linux/Plugin.c @@ -0,0 +1,208 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +#include "Linux.h" +#include "plugins.h" +#include "Spu.h" + +void RunGui(); +void OnFile_Exit(); + +extern GPUopen GPU_open; + +unsigned long gpuDisp; + +extern CDRplay CDR_play; +extern CDRstop CDR_stop; + +extern SPUopen SPU_open; + +long SPU__open(void) { + return SPU_open(); +} + +extern PADopen PAD1_open; +extern PADreadPort1 PAD1_readPort1; +extern PADopen PAD2_open; +extern PADreadPort2 PAD2_readPort2; + +int StatesC = 0; +extern char CdromId[256]; +extern int UseGui; +int cdOpenCase = 0; + +void PADhandleKey(int key) { + char Text[255]; + int ret; + + switch (key) { + case 0: break; + case XK_F1: + sprintf (Text, "sstates/%s.%3.3d", CdromId, StatesC); + GPU_freeze(2, (GPUFreeze_t *)&StatesC); + ret = SaveState(Text); + sprintf (Text, "*PCSX*: %s State %d", !ret ? "Saved" : "Error Saving", StatesC+1); + GPU_displayText(Text); + break; + case XK_F2: + if (StatesC < 4) StatesC++; + else StatesC = 0; + GPU_freeze(2, (GPUFreeze_t *)&StatesC); + break; + case XK_F3: + sprintf (Text, "sstates/%s.%3.3d", CdromId, StatesC); + ret = LoadState(Text); + sprintf (Text, "*PCSX*: %s State %d", !ret ? "Loaded" : "Error Loading", StatesC+1); + GPU_displayText(Text); + break; + case XK_F4: + { + gzFile f; + static int ShowPic; + + if (!ShowPic) { + unsigned char *pMem; + + sprintf (Text, "sstates/%s.%3.3d", CdromId, StatesC); + f = gzopen(Text, "rb"); + if (f == NULL) break; + + gzseek(f, 32, SEEK_SET); // skip header + + pMem = (unsigned char *) malloc(128*96*3); + gzread(f, pMem, 128*96*3); + gzclose(f); + GPU_freeze(2, (GPUFreeze_t *)&StatesC); + GPU_showScreenPic(pMem); + free(pMem); + ShowPic = 1; + } + else { GPU_showScreenPic(NULL); ShowPic = 0; } + } + break; + case XK_F5: + Config.Sio ^= 0x1; + sprintf (Text, "*PCSX*: Sio Irq %sAlways Enabled", Config.Sio ? "" : "Not "); + GPU_displayText(Text); + break; + case XK_F6: + Config.Mdec ^= 0x1; + sprintf (Text, "*PCSX*: Black&White Mdecs Only %sabled", Config.Mdec ? "En" : "Dis"); + GPU_displayText(Text); + break; + case XK_F7: + Config.Xa ^= 0x1; + sprintf (Text, "*PCSX*: Xa %sabled", !Config.Xa ? "En" : "Dis"); + GPU_displayText(Text); + break; + case XK_F8: + GPU_makeSnapshot(); + break; + case XK_F9: + cdOpenCase = 1; + break; + case XK_F10: + cdOpenCase = 0; + break; + case XK_Escape: + ClosePlugins(); + if (!UseGui) OnFile_Exit(); + RunGui(); + break; + default: GPU_keypressed(key); + } +} + +long PAD1__open(void) { + return PAD1_open(&gpuDisp); +} + +long PAD2__open(void) { + return PAD2_open(&gpuDisp); +} + +void OnFile_Exit(); + +void SignalExit(int sig) { + ClosePlugins(); + OnFile_Exit(); +} + +void SPUirq(void); + +void OpenPlugins() { + int ret; + + signal(SIGINT, SignalExit); + signal(SIGPIPE, SignalExit); + ret = CDR_open(); + if (ret != 0) { SysMessage ("Error Opening CDR Plugin\n"); exit(1); } + ret = SPU_open(); + if (ret != 0) { SysMessage ("Error Opening SPU Plugin\n"); exit(1); } + SPU_registerCallback(SPUirq); + ret = GPU_open(&gpuDisp, "P©SX", NULL); + if (ret != 0) { SysMessage ("Error Opening GPU Plugin\n"); exit(1); } + ret = PAD1_open(&gpuDisp); + if (ret != 0) { SysMessage ("Error Opening PAD1 Plugin\n"); exit(1); } + ret = PAD2_open(&gpuDisp); + if (ret != 0) { SysMessage ("Error Opening PAD2 Plugin\n"); exit(1); } +} + +void ClosePlugins() { + int ret; + + signal(SIGINT, SIG_DFL); + signal(SIGPIPE, SIG_DFL); + ret = CDR_close(); + if (ret != 0) { SysMessage ("Error Closing CDR Plugin\n"); exit(1); } + ret = SPU_close(); + if (ret != 0) { SysMessage ("Error Closing SPU Plugin\n"); exit(1); } + ret = PAD1_close(); + if (ret != 0) { SysMessage ("Error Closing PAD1 Plugin\n"); exit(1); } + ret = PAD2_close(); + if (ret != 0) { SysMessage ("Error Closing PAD2 Plugin\n"); exit(1); } + ret = GPU_close(); + if (ret != 0) { SysMessage ("Error Closing GPU Plugin\n"); exit(1); } +} + +void ResetPlugins() { + int ret; + + CDR_shutdown(); + GPU_shutdown(); + SPU_shutdown(); + PAD1_shutdown(); + PAD2_shutdown(); + + ret = CDR_init(); + if (ret != 0) { SysMessage ("CDRinit error : %d\n",ret); exit(1); } + ret = GPU_init(); + if (ret != 0) { SysMessage ("GPUinit error : %d\n",ret); exit(1); } + ret = SPU_init(); + if (ret != 0) { SysMessage ("SPUinit error : %d\n",ret); exit(1); } + ret = PAD1_init(1); + if (ret != 0) { SysMessage ("PAD1init error : %d\n",ret); exit(1); } + ret = PAD2_init(2); + if (ret != 0) { SysMessage ("PAD2init error : %d\n",ret); exit(1); } +} diff --git a/PcsxSrc/Linux/Plugin.h b/PcsxSrc/Linux/Plugin.h new file mode 100644 index 0000000..ddda195 --- /dev/null +++ b/PcsxSrc/Linux/Plugin.h @@ -0,0 +1,38 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +// Linux Specifyc Plugin Functions + +#ifndef __PLUGIN_H__ +#define __PLUGIN_H__ + +typedef long (* GPUopen)(unsigned long *, char *, char *); + +long GPU__open(void); + +typedef long (* SPUopen)(void); + +long SPU__open(void); + +typedef long (* PADopen)(unsigned long *); + +long PAD1__open(void); + +long PAD2__open(void); + +#endif /* __PLUGIN_H__ */ diff --git a/PcsxSrc/Linux/pcsx.glade b/PcsxSrc/Linux/pcsx.glade new file mode 100644 index 0000000..fde893f --- /dev/null +++ b/PcsxSrc/Linux/pcsx.glade @@ -0,0 +1,2215 @@ + + + + + Pcsx + pcsx + + + .pixmaps + C + False + False + False + False + False + GladeGui.c + GladeGui.h + GladeCalls.c + GladeCalls.h + GladeFuncs.c + GladeFuncs.h + + + + GtkWindow + MainWindow + 350 + 200 + + destroy + OnDestroy + Tue, 19 Feb 2002 22:15:57 GMT + + PCSX + GTK_WINDOW_TOPLEVEL + GTK_WIN_POS_CENTER + False + False + False + False + + + GtkVBox + vbox1 + False + 0 + + + GtkMenuBar + menubar1 + GTK_SHADOW_OUT + + 0 + False + False + + + + GtkMenuItem + item1 + + False + + + GtkMenu + item1_menu + + + GtkMenuItem + RunCd + + activate + OnFile_RunCd + Thu, 06 Dec 2001 03:27:52 GMT + + + False + + + + GtkMenuItem + RunCdBiois + + activate + OnFile_RunCdBios + Thu, 06 Dec 2001 03:28:07 GMT + + + False + + + + GtkMenuItem + Run Exe + + activate + OnFile_RunExe + Thu, 06 Dec 2001 03:30:35 GMT + + + False + + + + GtkMenuItem + separator2 + False + + + + GtkMenuItem + exit2 + + activate + OnFile_Exit + Thu, 06 Dec 2001 03:20:01 GMT + + + False + + + + + + GtkMenuItem + emulator1 + + False + + + GtkMenu + emulator1_menu + + + GtkMenuItem + run1 + + activate + OnEmu_Run + Thu, 06 Dec 2001 03:37:32 GMT + + + False + + + + GtkMenuItem + reset1 + + activate + OnEmu_Reset + Thu, 06 Dec 2001 03:37:32 GMT + + + False + + + + + + GtkMenuItem + configuration1 + + False + + + GtkMenu + configuration1_menu + + + GtkMenuItem + plugins_&_bios1 + + activate + OnConf_Conf + Thu, 06 Dec 2001 03:37:32 GMT + + + False + + + + GtkMenuItem + separator3 + False + + + + GtkMenuItem + graphics1 + + activate + OnConf_Gpu + Thu, 06 Dec 2001 03:37:32 GMT + + + False + + + + GtkMenuItem + sound1 + + activate + OnConf_Spu + Thu, 06 Dec 2001 03:37:32 GMT + + + False + + + + GtkMenuItem + cd-rom1 + + activate + OnConf_Cdr + Thu, 06 Dec 2001 03:37:32 GMT + + + False + + + + GtkMenuItem + controllers1 + + activate + OnConf_Pads + Thu, 06 Dec 2001 03:37:32 GMT + + + False + + + + GtkMenuItem + separator4 + False + + + + GtkMenuItem + cpu1 + + activate + OnConf_Cpu + Thu, 06 Dec 2001 03:37:32 GMT + + + False + + + + GtkMenuItem + memory_cards1 + + activate + OnConf_Mcds + Thu, 06 Dec 2001 03:37:32 GMT + + + False + + + + + + GtkMenuItem + help1 + + False + + + GtkMenu + help1_menu + + + GtkMenuItem + about_pcsx1 + + activate + OnHelp_About + Thu, 06 Dec 2001 03:37:32 GMT + + + False + + + + + + + + + GtkWindow + AboutDlg + 10 + Pcsx About + GTK_WINDOW_DIALOG + GTK_WIN_POS_CENTER + False + False + True + False + + + GtkVBox + vbox2 + False + 0 + + + GtkPacker + packer1 + 0 + 0 + 0 + 0 + 0 + + 0 + False + False + + + + + GtkHBox + hbox1 + False + 0 + + 0 + True + True + + + + GtkVBox + vbox4 + False + 0 + + 0 + True + True + + + + GtkLabel + GtkAbout_LabelVersion + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkFrame + frame1 + 5 + 0 + GTK_SHADOW_ETCHED_IN + + 0 + False + False + + + + GtkVBox + vbox6 + 5 + False + 0 + + + GtkLabel + GtkAbout_LabelAuthors + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + + + + GtkPixmap + pixmap1 + pcsxAbout.xpm + 0.5 + 0.5 + 0 + 0 + True + + 0 + True + True + + + + + + GtkFrame + frame2 + 5 + 0 + GTK_SHADOW_ETCHED_IN + + 0 + False + False + + + + GtkVBox + vbox5 + 5 + False + 0 + + + GtkLabel + GtkAbout_LabelGreets + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + + + GtkHButtonBox + hbuttonbox1 + GTK_BUTTONBOX_DEFAULT_STYLE + 30 + 85 + 27 + 7 + 0 + + 0 + True + True + + + + GtkButton + button1 + True + True + + clicked + OnHelpAbout_Ok + Thu, 06 Dec 2001 03:47:23 GMT + + + GTK_RELIEF_NORMAL + + + + + + + GtkWindow + ConfDlg + 10 + Conf + GTK_WINDOW_DIALOG + GTK_WIN_POS_CENTER + False + False + True + False + + + GtkVBox + vbox12 + False + 0 + + + GtkTable + table2 + 9 + 2 + False + 0 + 15 + + 0 + True + True + + + + GtkCombo + GtkCombo_Pad1 + False + True + False + True + False + + + 0 + 1 + 4 + 5 + 0 + 0 + True + False + False + False + True + False + + + + GtkEntry + GtkCombo:entry + combo-entry4 + True + True + True + 0 + + + + + + GtkCombo + GtkCombo_Pad2 + False + True + False + True + False + + + 1 + 2 + 4 + 5 + 0 + 0 + True + False + False + False + True + False + + + + GtkEntry + GtkCombo:entry + combo-entry5 + True + True + True + 0 + + + + + + GtkCombo + GtkCombo_Cdr + False + True + False + True + False + + + 0 + 1 + 7 + 8 + 0 + 0 + True + False + False + False + True + False + + + + GtkEntry + GtkCombo:entry + combo-entry6 + True + True + True + 0 + + + + + + GtkCombo + GtkCombo_Bios + False + True + False + True + False + + + 1 + 2 + 7 + 8 + 0 + 0 + True + False + False + False + True + False + + + + GtkEntry + GtkCombo:entry + combo-entry7 + True + True + True + 0 + + + + + + GtkHButtonBox + hbuttonbox5 + GTK_BUTTONBOX_DEFAULT_STYLE + 0 + 85 + 27 + 7 + 0 + + 0 + 1 + 8 + 9 + 0 + 0 + False + True + False + False + True + True + + + + GtkButton + button6 + True + True + + clicked + OnConfConf_CdrConf + Tue, 25 Dec 2001 05:39:01 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button7 + True + True + + clicked + OnConfConf_CdrTest + Tue, 25 Dec 2001 05:38:44 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button8 + True + True + + clicked + OnConfConf_CdrAbout + Tue, 25 Dec 2001 05:39:14 GMT + + + GTK_RELIEF_NORMAL + + + + + GtkHButtonBox + hbuttonbox6 + GTK_BUTTONBOX_DEFAULT_STYLE + 0 + 85 + 27 + 7 + 0 + + 1 + 2 + 5 + 6 + 0 + 0 + False + True + False + False + True + True + + + + GtkButton + button9 + True + True + + clicked + OnConfConf_Pad2Conf + Tue, 25 Dec 2001 05:40:52 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button10 + True + True + + clicked + OnConfConf_Pad2Test + Tue, 25 Dec 2001 05:41:02 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button11 + True + True + + clicked + OnConfConf_Pad2About + Tue, 25 Dec 2001 05:41:18 GMT + + + GTK_RELIEF_NORMAL + + + + + GtkHButtonBox + hbuttonbox7 + GTK_BUTTONBOX_DEFAULT_STYLE + 0 + 85 + 27 + 7 + 0 + + 0 + 1 + 5 + 6 + 0 + 0 + False + False + False + False + True + True + + + + GtkButton + button12 + True + True + + clicked + OnConfConf_Pad1Conf + Tue, 25 Dec 2001 05:38:17 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button13 + True + True + + clicked + OnConfConf_Pad1Test + Tue, 25 Dec 2001 05:39:35 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button14 + True + True + + clicked + OnConfConf_Pad1About + Tue, 25 Dec 2001 05:39:58 GMT + + + GTK_RELIEF_NORMAL + + + + + GtkHButtonBox + hbuttonbox8 + GTK_BUTTONBOX_DEFAULT_STYLE + 0 + 85 + 27 + 7 + 0 + + 0 + 1 + 2 + 3 + 0 + 0 + False + True + False + False + True + True + + + + GtkButton + button15 + True + True + + clicked + OnConfConf_GpuConf + Tue, 25 Dec 2001 05:36:45 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button16 + True + True + + clicked + OnConfConf_GpuTest + Tue, 25 Dec 2001 05:38:00 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button17 + True + True + + clicked + OnConfConf_GpuAbout + Tue, 25 Dec 2001 05:37:45 GMT + + + GTK_RELIEF_NORMAL + + + + + GtkHButtonBox + hbuttonbox9 + GTK_BUTTONBOX_DEFAULT_STYLE + 0 + 85 + 27 + 7 + 0 + + 1 + 2 + 2 + 3 + 0 + 0 + False + False + False + False + True + True + + + + GtkButton + button18 + True + True + + clicked + OnConfConf_SpuConf + Tue, 25 Dec 2001 05:41:51 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button19 + True + True + + clicked + OnConfConf_SpuTest + Tue, 25 Dec 2001 05:41:39 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button20 + True + True + + clicked + OnConfConf_SpuAbout + Tue, 25 Dec 2001 05:41:29 GMT + + + GTK_RELIEF_NORMAL + + + + + GtkLabel + label2 + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + + 1 + 2 + 0 + 1 + 0 + 0 + False + False + False + False + False + False + + + + + GtkLabel + label1 + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + + 0 + 1 + 0 + 1 + 0 + 0 + False + False + False + False + False + False + + + + + GtkLabel + label3 + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + + 0 + 1 + 3 + 4 + 0 + 0 + False + False + False + False + False + False + + + + + GtkLabel + label5 + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + + 0 + 1 + 6 + 7 + 0 + 0 + False + False + False + False + False + False + + + + + GtkLabel + label6 + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + + 1 + 2 + 6 + 7 + 0 + 0 + False + False + False + False + False + False + + + + + GtkLabel + label4 + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + + 1 + 2 + 3 + 4 + 0 + 0 + False + False + False + False + False + False + + + + + GtkCombo + GtkCombo_Gpu + False + True + False + True + False + + + 0 + 1 + 1 + 2 + 0 + 0 + True + False + False + False + True + False + + + + GtkEntry + GtkCombo:entry + combo-entry2 + True + True + True + 0 + + + + + + GtkCombo + GtkCombo_Spu + False + True + False + True + False + + + 1 + 2 + 1 + 2 + 0 + 0 + True + False + False + False + True + False + + + + GtkEntry + GtkCombo:entry + combo-entry3 + True + True + True + 0 + + + + + + + GtkHBox + hbox5 + False + 14 + + 0 + True + True + + + + GtkHButtonBox + hbuttonbox11 + 169 + GTK_BUTTONBOX_DEFAULT_STYLE + 0 + 85 + 27 + 7 + 0 + + 0 + True + True + + + + GtkButton + button22 + 109 + True + True + + clicked + OnConfConf_PluginsPath + Mon, 14 Jan 2002 19:18:13 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button23 + True + True + + clicked + OnConfConf_BiosPath + Mon, 14 Jan 2002 19:12:02 GMT + + + GTK_RELIEF_NORMAL + + + + + GtkHButtonBox + hbuttonbox10 + GTK_BUTTONBOX_DEFAULT_STYLE + 0 + 85 + 27 + 7 + 0 + + 0 + True + True + + + + GtkButton + button4 + True + True + + clicked + OnConfConf_Ok + Tue, 25 Dec 2001 05:19:01 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button25 + True + True + + clicked + OnConfConf_Cancel + Tue, 25 Dec 2001 05:19:16 GMT + + + GTK_RELIEF_NORMAL + + + + + + + + GtkWindow + CpuDlg + 5 + Cpu + GTK_WINDOW_DIALOG + GTK_WIN_POS_CENTER + False + False + True + False + + + GtkVBox + vbox8 + False + 0 + + + GtkFrame + frame3 + 5 + + 0 + GTK_SHADOW_ETCHED_IN + + 0 + True + True + + + + GtkVBox + vbox15 + 5 + False + 0 + + + GtkTable + table1 + 4 + 2 + False + 0 + 0 + + 0 + True + True + + + + GtkCheckButton + GtkCheckButton_Xa + True + + False + True + + 0 + 1 + 0 + 1 + 0 + 0 + False + False + False + False + True + False + + + + + GtkCheckButton + GtkCheckButton_Cdda + True + + False + True + + 1 + 2 + 0 + 1 + 0 + 0 + False + False + False + False + True + False + + + + + GtkCheckButton + GtkCheckButton_Sio + True + + False + True + + 0 + 1 + 1 + 2 + 0 + 0 + False + False + False + False + True + False + + + + + GtkCheckButton + GtkCheckButton_Cpu + True + + False + True + + 1 + 2 + 1 + 2 + 0 + 0 + False + False + False + False + True + False + + + + + GtkCheckButton + GtkCheckButton_PsxOut + True + + False + True + + 1 + 2 + 2 + 3 + 0 + 0 + False + False + False + False + True + False + + + + + GtkCheckButton + GtkCheckButton_Mdec + True + + False + True + + 0 + 1 + 3 + 4 + 0 + 0 + False + False + False + False + True + False + + + + + GtkCheckButton + GtkCheckButton_SpuIrq + True + + False + True + + 0 + 1 + 2 + 3 + 0 + 0 + False + False + False + False + True + False + + + + + + GtkCheckButton + GtkCheckButton_CdTiming + True + + False + True + + 0 + False + False + + + + + + + GtkFrame + frame6 + 5 + + 0 + GTK_SHADOW_ETCHED_IN + + 0 + True + True + + + + GtkHBox + hbox4 + 5 + False + 0 + + + GtkCheckButton + GtkCheckButton_PsxAuto + 159 + True + + False + True + + 0 + False + False + + + + + GtkCombo + GtkCombo_PsxType + 154 + False + True + False + True + False + + + 0 + False + False + + + + GtkEntry + GtkCombo:entry + combo-entry1 + True + False + True + 0 + + + + + + + + GtkHButtonBox + hbuttonbox3 + GTK_BUTTONBOX_DEFAULT_STYLE + 30 + 85 + 27 + 7 + 0 + + 0 + True + True + + + + GtkButton + button2 + True + True + + clicked + OnCpu_Ok + Fri, 07 Dec 2001 04:34:39 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button3 + True + True + + clicked + OnCpu_Cancel + Fri, 07 Dec 2001 04:34:55 GMT + + + GTK_RELIEF_NORMAL + + + + + + + GtkWindow + McdsDlg + 5 + Mcds + GTK_WINDOW_DIALOG + GTK_WIN_POS_CENTER + False + False + True + False + + + GtkVBox + vbox10 + False + 5 + + + GtkHBox + hbox6 + False + 0 + + 0 + True + True + + + + GtkFrame + frame7 + 5 + + 0 + GTK_SHADOW_ETCHED_IN + + 0 + True + True + + + + GtkVBox + vbox13 + 5 + False + 0 + + + GtkScrolledWindow + scrolledwindow1 + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + 0 + True + True + + + + GtkCList + GtkCList_McdList1 + 180 + True + 5 + 25,180,50,80,80 + GTK_SELECTION_SINGLE + True + GTK_SHADOW_IN + + + GtkLabel + CList:title + label9 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + GtkLabel + CList:title + label10 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + GtkLabel + CList:title + label11 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + GtkLabel + CList:title + label15 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + GtkLabel + CList:title + label16 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + + + GtkHButtonBox + hbuttonbox12 + 240 + GTK_BUTTONBOX_DEFAULT_STYLE + 0 + 70 + 27 + 7 + 0 + + 0 + True + True + + + + GtkButton + GtkButton_SelMcd1 + True + True + + clicked + OnMcd_FS1 + Fri, 07 Dec 2001 04:23:51 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + GtkButton_Format1 + True + True + + clicked + OnMcd_Format1 + Tue, 22 Jan 2002 21:56:09 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + GtkButton_Reload1 + True + True + + clicked + OnMcd_Reload1 + Tue, 22 Jan 2002 21:56:34 GMT + + + GTK_RELIEF_NORMAL + + + + + GtkEntry + GtkEntry_Mcd1 + True + True + True + 0 + + + 0 + False + False + + + + + + + GtkVButtonBox + vbuttonbox1 + GTK_BUTTONBOX_SPREAD + 0 + 64 + 27 + 0 + 0 + + 0 + True + False + + + + GtkButton + button26 + True + True + + clicked + OnMcd_CopyTo2 + Mon, 04 Mar 2002 18:34:51 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button28 + True + True + + clicked + OnMcd_CopyTo1 + Mon, 04 Mar 2002 18:36:39 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + GtkButton_McdPaste + True + True + + clicked + OnMcd_Paste + Mon, 04 Mar 2002 18:18:17 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button29 + True + True + + clicked + OnMcd_Delete2 + Sun, 10 Mar 2002 19:44:00 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + button30 + True + True + + clicked + OnMcd_Delete1 + Sun, 10 Mar 2002 19:43:52 GMT + + + GTK_RELIEF_NORMAL + + + + + GtkFrame + frame8 + 5 + + 0 + GTK_SHADOW_ETCHED_IN + + 0 + True + True + + + + GtkVBox + vbox14 + 5 + False + 0 + + + GtkScrolledWindow + scrolledwindow2 + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + 0 + True + True + + + + GtkCList + GtkCList_McdList2 + 180 + True + 5 + 25,180,50,80,80 + GTK_SELECTION_SINGLE + True + GTK_SHADOW_IN + + + GtkLabel + CList:title + label12 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + GtkLabel + CList:title + label13 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + GtkLabel + CList:title + label14 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + GtkLabel + CList:title + label17 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + GtkLabel + CList:title + label18 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + + + GtkHButtonBox + hbuttonbox13 + 240 + GTK_BUTTONBOX_DEFAULT_STYLE + 0 + 70 + 27 + 7 + 0 + + 0 + True + True + + + + GtkButton + GtkButton_SelMcd2 + True + True + + clicked + OnMcd_FS2 + Fri, 07 Dec 2001 04:23:45 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + GtkButton_Format2 + True + True + + clicked + OnMcd_Format2 + Tue, 22 Jan 2002 21:56:45 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + GtkButton_Reload2 + True + True + + clicked + OnMcd_Reload2 + Tue, 22 Jan 2002 21:56:59 GMT + + + GTK_RELIEF_NORMAL + + + + + GtkEntry + GtkEntry_Mcd2 + True + True + True + 0 + + + 0 + False + False + + + + + + + + GtkHButtonBox + hbuttonbox2 + GTK_BUTTONBOX_DEFAULT_STYLE + 30 + 85 + 27 + 7 + 0 + + 0 + True + True + + + + GtkButton + GtkMcds_Ok + True + True + + clicked + OnMcd_Ok + Thu, 06 Dec 2001 04:39:55 GMT + + + GTK_RELIEF_NORMAL + + + + GtkButton + GtkMcds_Cancel + True + True + + clicked + OnMcd_Cancel + Thu, 06 Dec 2001 04:40:45 GMT + + + GTK_RELIEF_NORMAL + + + + + + diff --git a/PcsxSrc/Mdec.c b/PcsxSrc/Mdec.c new file mode 100644 index 0000000..7a6a5c7 --- /dev/null +++ b/PcsxSrc/Mdec.c @@ -0,0 +1,587 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* This code was based on the FPSE v0.08 Mdec decoder*/ + +#include +#include + +#include "PsxCommon.h" +#include "Mdec.h" + +#define FIXED + +#define CONST_BITS 8 +#define PASS1_BITS 2 + +#define FIX_1_082392200 (277) +#define FIX_1_414213562 (362) +#define FIX_1_847759065 (473) +#define FIX_2_613125930 (669) + +#define MULTIPLY(var,const) (DESCALE((var) * (const), CONST_BITS)) + +#define DEQUANTIZE(coef,quantval) (coef) + +#define DESCALE(x,n) ((x)>>(n)) +#define RANGE(n) (n) + +#define DCTSIZE 8 +#define DCTSIZE2 64 + +static void idct1(int *block) +{ + int val = RANGE(DESCALE(block[0], PASS1_BITS+3)); + int i; + for(i=0;i>16)*(bcr&0xffff); + + if (cmd==0x60000000) { + } else + if (cmd==0x40000001) { + u8 *p = (u8*)PSXM(adr); + iqtab_init(iq_y,p); + iqtab_init(iq_uv,p+64); + } else + if ((cmd&0xf5ff0000)==0x30000000) { + mdec.rl = (u16*)PSXM(adr); + } + else { + } +} + +void psxDma1(u32 adr, u32 bcr, u32 chcr) { + int blk[DCTSIZE2*6]; + unsigned short *image; + int size; + +#ifdef CDR_LOG + CDR_LOG("DMA1 %lx %lx %lx (cmd = %lx)\n", adr, bcr, chcr, mdec.command); +#endif + + if (chcr!=0x01000200) return; + + size = (bcr>>16)*(bcr&0xffff); + image = (u16*)PSXM(adr); + if (mdec.command&0x08000000) { + for (;size>0;size-=(16*16)/2,image+=(16*16)) { + mdec.rl = rl2blk(blk,mdec.rl); + yuv2rgb15(blk,image); + } + } else { + for (;size>0;size-=(24*16)/2,image+=(24*16)) { + mdec.rl = rl2blk(blk,mdec.rl); + yuv2rgb24(blk,(u8 *)image); + } + } +} + + +#define RUNOF(a) ((a)>>10) +#define VALOF(a) (((int)(a)<<(32-10))>>(32-10)) + +static int zscan[DCTSIZE2] = { + 0 ,1 ,8 ,16,9 ,2 ,3 ,10, + 17,24,32,25,18,11,4 ,5 , + 12,19,26,33,40,48,41,34, + 27,20,13,6 ,7 ,14,21,28, + 35,42,49,56,57,50,43,36, + 29,22,15,23,30,37,44,51, + 58,59,52,45,38,31,39,46, + 53,60,61,54,47,55,62,63 +}; + +static int aanscales[DCTSIZE2] = { + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, + 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, + 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, + 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, + 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, + 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, + 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247 +}; + +void iqtab_init(int *iqtab,unsigned char *iq_y) +{ +#define CONST_BITS14 14 +#define IFAST_SCALE_BITS 2 + int i; + + for(i=0;i>(CONST_BITS14-IFAST_SCALE_BITS); + } +} + +/* // From Filefrmt.pdf + + RL data syntax: + header + macroblock + ... + macroblock + footer + + header: + 16bit: magic (0x3800) + 16bit: size + + macroblock: + Cb block + Cr block + Y1 block + Y2 block + Y3 block + Y4 block + + block: + 5bit: quant, 10bit: dc + 5bit: run, 10bit: level + ... + 5bit: run, 10bit: level + nop (0xfe00) + + footer: + nop + + block conversion: + zigzag -> dequantize -> idct -> yuv2rgb + + zigzag transformation: + + the blk_zig value is the level value of the block + + blk_zig[0] = blk_dct[0]/iq_tab[0]; + for (i = 1; i < 64; i++) { + j = zscan[i]; + blk_zig[i] = blk_dct[j]*16/(iqtab[j]*q_scale); + } + + reverse it: + blk_dct[0] = blk_zig[0]*iq_tab[0]; + for (i = 1; i < 64; i++) { + j = zscan[i]; + blk_dct[j] = blk_zig[i]/(16/(iqtab[j]*q_scale)); + } + + (run, level) (the number of zeros preceding level, value of the element) + + run-level example: + -229 -19 0 -2 0 0 1 0 + (0,-229) (0,-19) (1,-2) (2,1) nop + + dequantization: + + quant = q_scale + + y[0] = x[0] * 16 / (iqtab[0] * 8); + for (i = 1; i < 64; i++) + y[i] = x[i] / (quant * Qtable[i]); + + reverse it: + x[0] = y[0] / (16 / (iqtab[0] * 8)); + for (i = 1; i < 64; i++) + x[i] = y[i] * (quant * Qtable[i]); + + idct: + + yuv2rgb: + + R = Y * 1.0 + Cb * 0 + Cr * 1.402 + G = Y * 1.0 + Cb * -0.3437 + Cr * -0.7143 + B = Y * 1.0 + Cb * 1.772 + Cr * 0 +*/ +#define NOP 0xfe00 +unsigned short* rl2blk(int *blk,unsigned short *mdec_rl) { + int i,k,q_scale,rl; + int *iqtab; + + memset (blk, 0, 6*DCTSIZE2*4); + iqtab = iq_uv; + for(i=0;i<6;i++) { // decode blocks (Cr,Cb,Y1,Y2,Y3,Y4) + if (i>1) iqtab = iq_y; + + // zigzag transformation + rl = *mdec_rl++; + q_scale = RUNOF(rl); + blk[0] = iqtab[0]*VALOF(rl); + for(k = 0;;) { + rl = *mdec_rl++; + if (rl==NOP) break; + k += RUNOF(rl)+1; // skip level zero-coefficients + if (k > 63) break; + blk[zscan[k]] = (VALOF(rl) * iqtab[k] * q_scale) / 8; // / 16; + } +// blk[0] = (blk[0] * iq_t[0] * 8) / 16; +// for(int j=1;j<64;j++) +// blk[j] = blk[j] * iq_t[j] * q_scale; + + // idct + idct(blk,k+1); + + blk+=DCTSIZE2; + } + return mdec_rl; +} + +#ifdef FIXED +#define MULR(a) ((((int)0x0000059B) * (a)) >> 10) +#define MULG(a) ((((int)0xFFFFFEA1) * (a)) >> 10) +#define MULG2(a) ((((int)0xFFFFFD25) * (a)) >> 10) +#define MULB(a) ((((int)0x00000716) * (a)) >> 10) +#else +#define MULR(a) ((int)((float)1.40200 * (a))) +#define MULG(a) ((int)((float)-0.3437 * (a))) +#define MULG2(a) ((int)((float)-0.7143 * (a))) +#define MULB(a) ((int)((float)1.77200 * (a))) +#endif + +#define MAKERGB15(r,g,b) ( (((r)>>3)<<10)|(((g)>>3)<<5)|((b)>>3) ) +#define ROUND(c) roundtbl[((c)+128+256)]//&0x3ff] +/*#define ROUND(c) round(c+128) +int round(int r) { + if (r<0) return 0; + if (r>255) return 255; + return r; +}*/ + +#define RGB15(n, Y) \ + image[n] = MAKERGB15(ROUND(Y + R),ROUND(Y + G),ROUND(Y + B)); + +#define RGB15BW(n, Y) \ + image[n] = MAKERGB15(ROUND(Y),ROUND(Y),ROUND(Y)); + +#define RGB24(n, Y) \ + image[n+2] = ROUND(Y + R); \ + image[n+1] = ROUND(Y + G); \ + image[n+0] = ROUND(Y + B); + +#define RGB24BW(n, Y) \ + image[n+2] = ROUND(Y); \ + image[n+1] = ROUND(Y); \ + image[n+0] = ROUND(Y); + +unsigned char roundtbl[256*3]; + +void round_init(void) { + int i; + for(i=0;i<256;i++) { + roundtbl[i]=0; + roundtbl[i+256]=i; + roundtbl[i+512]=255; + } +} + +void yuv2rgb15(int *blk,unsigned short *image) { + int x,y; + int *Yblk = blk+DCTSIZE2*2; + int Cb,Cr,R,G,B; + int *Cbblk = blk; + int *Crblk = blk+DCTSIZE2; + + if (!(Config.Mdec&0x1)) + for (y=0;y<16;y+=2,Crblk+=4,Cbblk+=4,Yblk+=8,image+=24) { + if (y==8) Yblk+=DCTSIZE2; + for (x=0;x<4;x++,image+=2,Crblk++,Cbblk++,Yblk+=2) { + Cr = *Crblk; + Cb = *Cbblk; + R = MULR(Cr); + G = MULG(Cb) + MULG2(Cr); + B = MULB(Cb); + + RGB15(0, Yblk[0]); + RGB15(1, Yblk[1]); + RGB15(16, Yblk[8]); + RGB15(17, Yblk[9]); + + Cr = *(Crblk+4); + Cb = *(Cbblk+4); + R = MULR(Cr); + G = MULG(Cb) + MULG2(Cr); + B = MULB(Cb); + + RGB15(8, Yblk[DCTSIZE2+0]); + RGB15(9, Yblk[DCTSIZE2+1]); + RGB15(24, Yblk[DCTSIZE2+8]); + RGB15(25, Yblk[DCTSIZE2+9]); + } + } else + for (y=0;y<16;y+=2,Yblk+=8,image+=24) { + if (y==8) Yblk+=DCTSIZE2; + for (x=0;x<4;x++,image+=2,Yblk+=2) { + RGB15BW(0, Yblk[0]); + RGB15BW(1, Yblk[1]); + RGB15BW(16, Yblk[8]); + RGB15BW(17, Yblk[9]); + + RGB15BW(8, Yblk[DCTSIZE2+0]); + RGB15BW(9, Yblk[DCTSIZE2+1]); + RGB15BW(24, Yblk[DCTSIZE2+8]); + RGB15BW(25, Yblk[DCTSIZE2+9]); + } + } +} + +void yuv2rgb24(int *blk,unsigned char *image) { + int x,y; + int *Yblk = blk+DCTSIZE2*2; + int Cb,Cr,R,G,B; + int *Cbblk = blk; + int *Crblk = blk+DCTSIZE2; + + if (!(Config.Mdec&0x1)) + for (y=0;y<16;y+=2,Crblk+=4,Cbblk+=4,Yblk+=8,image+=24*3) { + if (y==8) Yblk+=DCTSIZE2; + for (x=0;x<4;x++,image+=6,Crblk++,Cbblk++,Yblk+=2) { + Cr = *Crblk; + Cb = *Cbblk; + R = MULR(Cr); + G = MULG(Cb) + MULG2(Cr); + B = MULB(Cb); + + RGB24(0, Yblk[0]); + RGB24(1*3, Yblk[1]); + RGB24(16*3, Yblk[8]); + RGB24(17*3, Yblk[9]); + + Cr = *(Crblk+4); + Cb = *(Cbblk+4); + R = MULR(Cr); + G = MULG(Cb) + MULG2(Cr); + B = MULB(Cb); + + RGB24(8*3, Yblk[DCTSIZE2+0]); + RGB24(9*3, Yblk[DCTSIZE2+1]); + RGB24(24*3, Yblk[DCTSIZE2+8]); + RGB24(25*3, Yblk[DCTSIZE2+9]); + } + } else + for (y=0;y<16;y+=2,Yblk+=8,image+=24*3) { + if (y==8) Yblk+=DCTSIZE2; + for (x=0;x<4;x++,image+=6,Yblk+=2) { + RGB24BW(0, Yblk[0]); + RGB24BW(1*3, Yblk[1]); + RGB24BW(16*3, Yblk[8]); + RGB24BW(17*3, Yblk[9]); + + RGB24BW(8*3, Yblk[DCTSIZE2+0]); + RGB24BW(9*3, Yblk[DCTSIZE2+1]); + RGB24BW(24*3, Yblk[DCTSIZE2+8]); + RGB24BW(25*3, Yblk[DCTSIZE2+9]); + } + } +} + +int mdecFreeze(gzFile f, int Mode) { + char Unused[4096]; + + gzfreeze(&mdec, sizeof(mdec)); + gzfreezel(iq_y); + gzfreezel(iq_uv); + gzfreezel(Unused); + + return 0; +} + diff --git a/PcsxSrc/Mdec.h b/PcsxSrc/Mdec.h new file mode 100644 index 0000000..5d4e70d --- /dev/null +++ b/PcsxSrc/Mdec.h @@ -0,0 +1,31 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __MDEC_H__ +#define __MDEC_H__ + +void mdecInit(); +void mdecWrite0(u32 data); +void mdecWrite1(u32 data); +u32 mdecRead0(); +u32 mdecRead1(); +void psxDma0(u32 madr, u32 bcr, u32 chcr); +void psxDma1(u32 madr, u32 bcr, u32 chcr); +int mdecFreeze(gzFile f, int Mode); + +#endif /* __MDEC_H__ */ diff --git a/PcsxSrc/Misc.c b/PcsxSrc/Misc.c new file mode 100644 index 0000000..d3d4128 --- /dev/null +++ b/PcsxSrc/Misc.c @@ -0,0 +1,451 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#ifdef __LINUX__ +#define strnicmp strncasecmp +#endif + +#include "Coff.h" +#include "PsxCommon.h" +#include "plugins.h" + +int Log = 0; + +// LOAD STUFF + +typedef struct { + unsigned char id[8]; + unsigned long text; + unsigned long data; + unsigned long pc0; + unsigned long gp0; + unsigned long t_addr; + unsigned long t_size; + unsigned long d_addr; + unsigned long d_size; + unsigned long b_addr; + unsigned long b_size; + unsigned long S_addr;//normal must a s not a S but error (???) + unsigned long s_size; + unsigned long SavedSP; + unsigned long SavedFP; + unsigned long SavedGP; + unsigned long SavedRA; + unsigned long SavedS0; +} EXE_HEADER; + +#define ISODCL(from, to) (to - from + 1) + +struct iso_directory_record { + char length [ISODCL (1, 1)]; /* 711 */ + char ext_attr_length [ISODCL (2, 2)]; /* 711 */ + char extent [ISODCL (3, 10)]; /* 733 */ + char size [ISODCL (11, 18)]; /* 733 */ + char date [ISODCL (19, 25)]; /* 7 by 711 */ + char flags [ISODCL (26, 26)]; + char file_unit_size [ISODCL (27, 27)]; /* 711 */ + char interleave [ISODCL (28, 28)]; /* 711 */ + char volume_sequence_number [ISODCL (29, 32)]; /* 723 */ + unsigned char name_len [ISODCL (33, 33)]; /* 711 */ + char name [1]; +}; + +#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */ +#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */ + +void mmssdd( int block, char *p ) + { + int m, s, d; + + block += 150; + m = block / 4500; // minuten + block = block - m * 4500; // minuten rest + s = block / 75; // sekunden + d = block - s * 75; // sekunden rest + + m = ( ( m / 10 ) << 4 ) | m % 10; + s = ( ( s / 10 ) << 4 ) | s % 10; + d = ( ( d / 10 ) << 4 ) | d % 10; + + p[0] = m; + p[1] = s; + p[2] = d; +} + +int GetCdromFile(unsigned char *buf, unsigned char *time, char * filename) { + struct iso_directory_record *dir; + int i; + + i = 0; + while (i < 4096) { + dir = (struct iso_directory_record*) &buf[i]; + if (dir->length[0] == 0) { + return -1; + } + i += dir->length[0]; + + if (!strnicmp((char*)&dir->name[0],filename,strlen(filename))) { + mmssdd(*((int *)dir->extent), (char*)time); + break; + } + } + return 0; +} + +#define incTime() \ + time[0] = btoi(time[0]); time[1] = btoi(time[1]); time[2] = btoi(time[2]); \ + time[2]++; \ + if(time[2] == 75) { \ + time[2] = 0; \ + time[1]++; \ + if (time[1] == 60) { \ + time[1] = 0; \ + time[0]++; \ + } \ + } \ + time[0] = itob(time[0]); time[1] = itob(time[1]); time[2] = itob(time[2]); + +int LoadCdrom() { + EXE_HEADER tmpHead; + struct iso_directory_record *dir; + unsigned char time[4],*buf; + unsigned char mdir[4096]; + char exename[256]; + int i; + + if (!Config.HLE) { + psxRegs.pc = psxRegs.GPR.n.ra; + return 0; + } + + time[0] = itob(0); time[1] = itob(2); time[2] = itob(0x10); + + if (CDR_readTrack(time) == -1) return -1; + buf = CDR_getBuffer(); + + // skip head and sub, and go to the root directory record + dir = (struct iso_directory_record*) &buf[12+156]; + + mmssdd(*((int *)dir->extent), (char*)time); + + if (CDR_readTrack(time) == -1) return -1; + buf = CDR_getBuffer(); + memcpy(mdir, buf+12, 2048); + + incTime(); + if (CDR_readTrack(time) == -1) return -1; + buf = CDR_getBuffer(); + memcpy(mdir+2048, buf+12, 2048); + + if (GetCdromFile(mdir, time, "SYSTEM.CNF") == -1) { + if (GetCdromFile(mdir, time, "PSX.EXE") == -1) return -1; + + if (CDR_readTrack(time) == -1) return -1; + buf = CDR_getBuffer(); + } + else { + if (CDR_readTrack(time) == -1) return -1; + buf = CDR_getBuffer(); + + sscanf((char*)buf+12, "BOOT = cdrom:\\%s;2", exename); + if (GetCdromFile(mdir, time, exename) == -1) { + sscanf((char*)buf+12, "BOOT = cdrom:%s;2", exename); + if (GetCdromFile(mdir, time, exename) == -1) { + char *ptr = strstr(buf+12, "cdrom:"); + for (i=0; i<32; i++) { + if (ptr[i] == ' ') continue; + if (ptr[i] == '\\') continue; + } + strcpy(exename, ptr); + if (GetCdromFile(mdir, time, exename) == -1) + return -1; + } + } + + if (CDR_readTrack(time) == -1) return -1; + buf = CDR_getBuffer(); + } + + memcpy(&tmpHead, buf+12, sizeof(EXE_HEADER)); + + psxRegs.pc = tmpHead.pc0; + psxRegs.GPR.n.gp = tmpHead.gp0; + psxRegs.GPR.n.sp = tmpHead.S_addr; + if (psxRegs.GPR.n.sp == 0) psxRegs.GPR.n.sp = 0x801fff00; + + while (tmpHead.t_size) { + incTime(); + if (CDR_readTrack(time) == -1) return -1; + buf = CDR_getBuffer(); + + memcpy((void *)PSXM(tmpHead.t_addr), buf+12, 2048); + + tmpHead.t_size -= 2048; + tmpHead.t_addr += 2048; + } + + return 0; +} + +int CheckCdrom() { + struct iso_directory_record *dir; + unsigned char time[4],*buf; + unsigned char mdir[4096]; + char exename[256]; + int i; + + time[0] = itob(0); time[1] = itob(2); time[2] = itob(0x10); + + if (CDR_readTrack(time) == -1) return -1; + buf = CDR_getBuffer(); + + strncpy(CdromId, buf+52, 10); + + // skip head and sub, and go to the root directory record + dir = (struct iso_directory_record*) &buf[12+156]; + + mmssdd(*((int *)dir->extent), (char*)time); + + if (CDR_readTrack(time) == -1) return 0; + buf = CDR_getBuffer(); + memcpy(mdir, buf+12, 2048); + + incTime(); + if (CDR_readTrack(time) == -1) return 0; + buf = CDR_getBuffer(); + memcpy(mdir+2048, buf+12, 2048); + + if (GetCdromFile(mdir, time, "SYSTEM.CNF") != -1) { + if (CDR_readTrack(time) == -1) return 0; + buf = CDR_getBuffer(); + + sscanf((char*)buf+12, "BOOT = cdrom:\\%s;2", exename); + if (GetCdromFile(mdir, time, exename) == -1) { + sscanf((char*)buf+12, "BOOT = cdrom:%s;2", exename); + if (GetCdromFile(mdir, time, exename) == -1) { + char *ptr = strstr(buf+12, "cdrom:"); + for (i=0; i<32; i++) { + if (ptr[i] == ' ') continue; + if (ptr[i] == '\\') continue; + } + strcpy(exename, ptr); + if (GetCdromFile(mdir, time, exename) == -1) + return 0; + } + } + } + + if (Config.PsxAuto) { // autodetect system (pal or ntsc) + if (strstr(exename, "ES") != NULL) + Config.PsxType = 1; // pal + else Config.PsxType = 0; // ntsc + } + UpdateVSyncRate(); + + return 0; +} + +#define PSX_EXE 1 +#define CPE_EXE 2 +#define COFF_EXE 3 +#define INVALID_EXE 4 + +static int PSXGetFileType(FILE *f) { + unsigned long current; + unsigned long mybuf[2048]; + EXE_HEADER *exe_hdr; + FILHDR *coff_hdr; + + current = ftell(f); + fseek(f,0L,SEEK_SET); + fread(mybuf,2048,1,f); + fseek(f,current,SEEK_SET); + + exe_hdr = (EXE_HEADER *)mybuf; + if (memcmp(exe_hdr->id,"PS-X EXE",8)==0) + return PSX_EXE; + + if (mybuf[0]=='C' && mybuf[1]=='P' && mybuf[2]=='E') + return CPE_EXE; + + coff_hdr = (FILHDR *)mybuf; + if (coff_hdr->f_magic == 0x0162) + return COFF_EXE; + + return INVALID_EXE; +} + +int Load(char *ExePath) { + FILE *tmpFile; + EXE_HEADER tmpHead; + int type; + + strcpy(CdromId, "SLUS_999.99"); + + tmpFile = fopen(ExePath,"rb"); + if (tmpFile == NULL) { SysMessage("Error opening file: %s", ExePath); return 0; } + + type = PSXGetFileType(tmpFile); + switch (type) { + case PSX_EXE: + fread(&tmpHead,sizeof(EXE_HEADER),1,tmpFile); + fseek(tmpFile, 0x800, SEEK_SET); + fread((void *)PSXM(tmpHead.t_addr), tmpHead.t_size,1,tmpFile); + fclose(tmpFile); + psxRegs.pc = tmpHead.pc0; + psxRegs.GPR.n.gp = tmpHead.gp0; + psxRegs.GPR.n.sp = tmpHead.S_addr; + if (psxRegs.GPR.n.sp == 0) psxRegs.GPR.n.sp = 0x801fff00; + break; + case CPE_EXE: + SysMessage("Pcsx found that you wanna use a CPE file. CPE files not support yet"); + break; + case COFF_EXE: + SysMessage("Pcsx found that you wanna use a COFF file.COFF files not support yet"); + break; + case INVALID_EXE: + SysMessage("This file is not a psx file"); + break; + } + return 1; +} + +// STATES + +static const char PcsxHeader[32] = "STv3 PCSX v" PCSX_VERSION; + +int SaveState(char *file) { + gzFile f; + GPUFreeze_t *gpufP; + SPUFreeze_t *spufP; + int Size; + unsigned char *pMem; + + f = gzopen(file, "wb"); + if (f == NULL) return -1; + + gzwrite(f, (void*)PcsxHeader, 32); + + pMem = (unsigned char *) malloc(128*96*3); + if (pMem == NULL) return -1; + GPU_getScreenPic(pMem); + gzwrite(f, pMem, 128*96*3); + free(pMem); + + gzwrite(f, psxM, 0x00200000); + if (Config.HLE) psxBiosFreeze(1); + gzwrite(f, psxR, 0x00080000); + gzwrite(f, psxH, 0x00010000); + gzwrite(f, (void*)&psxRegs, sizeof(psxRegs)); + + // gpu + gpufP = (GPUFreeze_t *) malloc(sizeof(GPUFreeze_t)); + gpufP->ulFreezeVersion = 1; + GPU_freeze(1, gpufP); + gzwrite(f, gpufP, sizeof(GPUFreeze_t)); + free(gpufP); + + // spu + spufP = (SPUFreeze_t *) malloc(16); + SPU_freeze(2, spufP); + Size = spufP->Size; gzwrite(f, &Size, 4); + free(spufP); + spufP = (SPUFreeze_t *) malloc(Size); + SPU_freeze(1, spufP); + gzwrite(f, spufP, Size); + free(spufP); + + sioFreeze(f, 1); + cdrFreeze(f, 1); + psxHwFreeze(f, 1); + psxRcntFreeze(f, 1); + mdecFreeze(f, 1); + + gzclose(f); + + return 0; +} + + +int LoadState(char *file) { + gzFile f; + GPUFreeze_t *gpufP; + SPUFreeze_t *spufP; + int Size; + char header[32]; + + f = gzopen(file, "rb"); + if (f == NULL) return -1; + + psxCpu->Reset(); + + gzread(f, header, 32); + + if (strncmp("STv3 PCSX", header, 9)) return -1; + + gzseek(f, 128*96*3, SEEK_CUR); + + gzread(f, psxM, 0x00200000); + gzread(f, psxR, 0x00080000); + if (Config.HLE) psxBiosFreeze(0); + gzread(f, psxH, 0x00010000); + gzread(f, (void*)&psxRegs, sizeof(psxRegs)); + + // gpu + gpufP = (GPUFreeze_t *) malloc (sizeof(GPUFreeze_t)); + gzread(f, gpufP, sizeof(GPUFreeze_t)); + GPU_freeze(0, gpufP); + free(gpufP); + + // spu + gzread(f, &Size, 4); + spufP = (SPUFreeze_t *) malloc (Size); + gzread(f, spufP, Size); + SPU_freeze(0, spufP); + free(spufP); + + sioFreeze(f, 0); + cdrFreeze(f, 0); + psxHwFreeze(f, 0); + psxRcntFreeze(f, 0); + mdecFreeze(f, 0); + + gzclose(f); + + return 0; +} + +void __Log(char *fmt, ...) { + va_list list; +#ifdef LOG_STDOUT + char tmp[1024]; +#endif + + va_start(list, fmt); +#ifndef LOG_STDOUT + vfprintf(emuLog, fmt, list); +#else + vsprintf(tmp, fmt, list); + SysPrintf(tmp); +#endif + va_end(list); +} \ No newline at end of file diff --git a/PcsxSrc/Misc.h b/PcsxSrc/Misc.h new file mode 100644 index 0000000..1dd2480 --- /dev/null +++ b/PcsxSrc/Misc.h @@ -0,0 +1,31 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __MISC_H__ +#define __MISC_H__ + +char CdromId[256]; + +int LoadCdrom(); +int CheckCdrom(); +int Load(char *ExePath); + +int SaveState(char *file); +int LoadState(char *file); + +#endif /* __MISC_H__ */ diff --git a/PcsxSrc/PSEmu_Plugin_Defs.h b/PcsxSrc/PSEmu_Plugin_Defs.h new file mode 100644 index 0000000..47a1f55 --- /dev/null +++ b/PcsxSrc/PSEmu_Plugin_Defs.h @@ -0,0 +1,247 @@ +/* + PSEmu Plugin Developer Kit Header definition + + (C)1998 Vision Thing + + This file can be used only to develop PSEmu Plugins + Other usage is highly prohibited. +*/ + + +// IMPORTANT!!! + +// if you want to add return codes (any errors or warnings) just drop mail to +// plugin@psemu.com + +#ifndef _PSEMU_PLUGIN_DEFS_H +#define _PSEMU_PLUGIN_DEFS_H + + +// header version +#define _PPDK_HEADER_VERSION 3 + +#define PLUGIN_VERSION 1 + +// plugin type returned by PSEgetLibType (types can be merged if plugin is multi type!) +#define PSE_LT_CDR 1 +#define PSE_LT_GPU 2 +#define PSE_LT_SPU 4 +#define PSE_LT_PAD 8 + + +// every function in DLL if completed sucessfully should return this value +#define PSE_ERR_SUCCESS 0 + +// undefined error but fatal one, that kills all functionality +#define PSE_ERR_FATAL -1 + + + +// XXX_Init return values +// Those return values apply to all libraries +// currently obsolete - preserved for compatibilty + + +// initialization went OK +#define PSE_INIT_ERR_SUCCESS 0 + +// this driver is not configured +#define PSE_INIT_ERR_NOTCONFIGURED -2 + +// this driver can not operate properly on this hardware or hardware is not detected +#define PSE_INIT_ERR_NOHARDWARE -3 + + + +/* GPU PlugIn */ + + +// GPU_Test return values + +// sucess, everything configured, and went OK. +#define PSE_GPU_ERR_SUCCESS 0 + +// ERRORS +// this error might be returned as critical error but none of below +#define PSE_GPU_ERR -20 + + +// this driver is not configured +#define PSE_GPU_ERR_NOTCONFIGURED PSE_GPU_ERR - 1 +// this driver failed Init +#define PSE_GPU_ERR_INIT PSE_GPU_ERR - 2 + +// WARNINGS +// this warning might be returned as undefined warning but allowing driver to continue +#define PSE_GPU_WARN 20 + + + + +// GPU_Query - will be implemented soon + +typedef struct +{ + unsigned long flags; + unsigned long status; + HWND window; + unsigned char reserved[100]; +} gpuQueryS; + +// gpuQueryS.flags +// if driver can operate in both modes it must support GPU_changeMode(); +// this driver can operate in fullscreen mode +#define PSE_GPU_FLAGS_FULLSCREEN 1 +// this driver can operate in windowed mode +#define PSE_GPU_FLAGS_WINDOWED 2 + + +// gpuQueryS.status +// this driver cannot operate in this windowed mode +#define PSE_GPU_STATUS_WINDOWWRONG 1 + +// GPU_Query End - will be implemented in v2 + + + + +/* CDR PlugIn */ + +// CDR_Test return values + +// sucess, everything configured, and went OK. +#define PSE_CDR_ERR_SUCCESS 0 + +// general failure (error undefined) +#define PSE_CDR_ERR_FAILURE -1 + +// ERRORS +#define PSE_CDR_ERR -40 +// this driver is not configured +#define PSE_CDR_ERR_NOTCONFIGURED PSE_CDR_ERR - 0 +// if this driver is unable to read data from medium +#define PSE_CDR_ERR_NOREAD PSE_CDR_ERR - 1 + +// WARNINGS +#define PSE_CDR_WARN 40 +// if this driver emulates lame mode ie. can read only 2048 tracks and sector header is emulated +// this might happen to CDROMS that do not support RAW mode reading - surelly it will kill many games +#define PSE_CDR_WARN_LAMECD PSE_CDR_WARN + 0 + + + + +/* SPU PlugIn */ + +// some info retricted (now!) + +// sucess, everything configured, and went OK. +#define PSE_SPU_ERR_SUCCESS 0 + +// ERRORS +// this error might be returned as critical error but none of below +#define PSE_SPU_ERR -60 + +// this driver is not configured +#define PSE_SPU_ERR_NOTCONFIGURED PSE_SPU_ERR - 1 +// this driver failed Init +#define PSE_SPU_ERR_INIT PSE_SPU_ERR - 2 + + +// WARNINGS +// this warning might be returned as undefined warning but allowing driver to continue +#define PSE_SPU_WARN 60 + + + + +/* PAD PlugIn */ + +/* + + functions that must be exported from PAD Plugin + + long PADinit(long flags); // called only once when PSEmu Starts + void PADshutdown(void); // called when PSEmu exits + long PADopen(PadInitS *); // called when PSEmu is running program + long PADclose(void); + long PADconfigure(void); + void PADabout(void); + long PADtest(void); // called from Configure Dialog and after PADopen(); + long PADquery(void); + + long PADreadPort1(PadDataS *); + long PADreadPort2(PadDataS *); + +*/ + +// PADquery responses (notice - values ORed) +// PSEmu will use them also in PADinit to tell Plugin which Ports will use +// notice that PSEmu will call PADinit and PADopen only once when they are from +// same plugin + +// might be used in port 1 (must support PADreadPort1() function) +#define PSE_PAD_USE_PORT1 1 +// might be used in port 2 (must support PADreadPort2() function) +#define PSE_PAD_USE_PORT2 2 + + + +// MOUSE SCPH-1030 +#define PSE_PAD_TYPE_MOUSE 1 +// NEGCON - 16 button analog controller SLPH-00001 +#define PSE_PAD_TYPE_NEGCON 2 +// GUN CONTROLLER - gun controller SLPH-00014 from Konami +#define PSE_PAD_TYPE_GUN 3 +// STANDARD PAD SCPH-1080, SCPH-1150 +#define PSE_PAD_TYPE_STANDARD 4 +// ANALOG JOYSTICK SCPH-1110 +#define PSE_PAD_TYPE_ANALOGJOY 5 +// GUNCON - gun controller SLPH-00034 from Namco +#define PSE_PAD_TYPE_GUNCON 6 +// ANALOG CONTROLLER SCPH-1150 +#define PSE_PAD_TYPE_ANALOGPAD 7 + + +// sucess, everything configured, and went OK. +#define PSE_PAD_ERR_SUCCESS 0 +// general plugin failure (undefined error) +#define PSE_PAD_ERR_FAILURE -1 + + +// ERRORS +// this error might be returned as critical error but none of below +#define PSE_PAD_ERR -80 +// this driver is not configured +#define PSE_PAD_ERR_NOTCONFIGURED PSE_PAD_ERR - 1 +// this driver failed Init +#define PSE_PAD_ERR_INIT PSE_PAD_ERR - 2 + + +// WARNINGS +// this warning might be returned as undefined warning but allowing driver to continue +#define PSE_PAD_WARN 80 + + +typedef struct +{ + // controler type - fill it withe predefined values above + unsigned char controllerType; + + // status of buttons - every controller fills this field + unsigned short buttonStatus; + + // for analog pad fill those next 4 bytes + // values are analog in range 0-255 where 128 is center position + unsigned char rightJoyX, rightJoyY, leftJoyX, leftJoyY; + + // for mouse fill those next 2 bytes + // values are in range -128 - 127 + unsigned char moveX, moveY; + + unsigned char reserved[91]; + +} PadDataS; + + +#endif // _PSEMU_PLUGIN_DEFS_H diff --git a/PcsxSrc/PsxBios.c b/PcsxSrc/PsxBios.c new file mode 100644 index 0000000..5494a20 --- /dev/null +++ b/PcsxSrc/PsxBios.c @@ -0,0 +1,2164 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +#include "PsxCommon.h" +//We try to emulate bios :) HELP US :P + +char *biosA0n[256] = { +// 0x00 + "open", "lseek", "read", "write", + "close", "ioctl", "exit", "sys_a0_07", + "getc", "putc", "todigit", "atof", + "strtoul", "strtol", "abs", "labs", +// 0x10 + "atoi", "atol", "atob", "setjmp", + "longjmp", "strcat", "strncat", "strcmp", + "strncmp", "strcpy", "strncpy", "strlen", + "index", "rindex", "strchr", "strrchr", +// 0x20 + "strpbrk", "strspn", "strcspn", "strtok", + "strstr", "toupper", "tolower", "bcopy", + "bzero", "bcmp", "memcpy", "memset", + "memmove", "memcmp", "memchr", "rand", +// 0x30 + "srand", "qsort", "strtod", "malloc", + "free", "lsearch", "bsearch", "calloc", + "realloc", "InitHeap", "_exit", "getchar", + "putchar", "gets", "puts", "printf", +// 0x40 + "sys_a0_40", "LoadTest", "Load", "Exec", + "FlushCache", "InstallInterruptHandler", "GPU_dw", "mem2vram", + "SendGPUStatus", "GPU_cw", "GPU_cwb", "SendPackets", + "sys_a0_4c", "GetGPUStatus", "GPU_sync", "sys_a0_4f", +// 0x50 + "sys_a0_50", "LoadExec", "GetSysSp", "sys_a0_53", + "_96_init()", "_bu_init()", "_96_remove()", "sys_a0_57", + "sys_a0_58", "sys_a0_59", "sys_a0_5a", "dev_tty_init", + "dev_tty_open", "sys_a0_5d", "dev_tty_ioctl","dev_cd_open", +// 0x60 + "dev_cd_read", "dev_cd_close", "dev_cd_firstfile", "dev_cd_nextfile", + "dev_cd_chdir", "dev_card_open", "dev_card_read", "dev_card_write", + "dev_card_close", "dev_card_firstfile", "dev_card_nextfile","dev_card_erase", + "dev_card_undelete","dev_card_format", "dev_card_rename", "dev_card_6f", +// 0x70 + "_bu_init", "_96_init", "_96_remove", "sys_a0_73", + "sys_a0_74", "sys_a0_75", "sys_a0_76", "sys_a0_77", + "_96_CdSeekL", "sys_a0_79", "sys_a0_7a", "sys_a0_7b", + "_96_CdGetStatus", "sys_a0_7d", "_96_CdRead", "sys_a0_7f", +// 0x80 + "sys_a0_80", "sys_a0_81", "sys_a0_82", "sys_a0_83", + "sys_a0_84", "_96_CdStop", "sys_a0_86", "sys_a0_87", + "sys_a0_88", "sys_a0_89", "sys_a0_8a", "sys_a0_8b", + "sys_a0_8c", "sys_a0_8d", "sys_a0_8e", "sys_a0_8f", +// 0x90 + "sys_a0_90", "sys_a0_91", "sys_a0_92", "sys_a0_93", + "sys_a0_94", "sys_a0_95", "AddCDROMDevice", "AddMemCardDevide", + "DisableKernelIORedirection", "EnableKernelIORedirection", "sys_a0_9a", "sys_a0_9b", + "SetConf", "GetConf", "sys_a0_9e", "SetMem", +// 0xa0 + "_boot", "SystemError", "EnqueueCdIntr", "DequeueCdIntr", + "sys_a0_a4", "ReadSector", "get_cd_status", "bufs_cb_0", + "bufs_cb_1", "bufs_cb_2", "bufs_cb_3", "_card_info", + "_card_load", "_card_auto", "bufs_cd_4", "sys_a0_af", +// 0xb0 + "sys_a0_b0", "sys_a0_b1", "do_a_long_jmp", "sys_a0_b3", + "?? sub_function", +}; + +char *biosB0n[256] = { +// 0x00 + "SysMalloc", "sys_b0_01", "sys_b0_02", "sys_b0_03", + "sys_b0_04", "sys_b0_05", "sys_b0_06", "DeliverEvent", + "OpenEvent", "CloseEvent", "WaitEvent", "TestEvent", + "EnableEvent", "DisableEvent", "OpenTh", "CloseTh", +// 0x10 + "ChangeTh", "sys_b0_11", "InitPAD", "StartPAD", + "StopPAD", "PAD_init", "PAD_dr", "ReturnFromExecption", + "ResetEntryInt", "HookEntryInt", "sys_b0_1a", "sys_b0_1b", + "sys_b0_1c", "sys_b0_1d", "sys_b0_1e", "sys_b0_1f", +// 0x20 + "UnDeliverEvent", "sys_b0_21", "sys_b0_22", "sys_b0_23", + "sys_b0_24", "sys_b0_25", "sys_b0_26", "sys_b0_27", + "sys_b0_28", "sys_b0_29", "sys_b0_2a", "sys_b0_2b", + "sys_b0_2c", "sys_b0_2d", "sys_b0_2e", "sys_b0_2f", +// 0x30 + "sys_b0_30", "sys_b0_31", "open", "lseek", + "read", "write", "close", "ioctl", + "exit", "sys_b0_39", "getc", "putc", + "getchar", "putchar", "gets", "puts", +// 0x40 + "cd", "format", "firstfile", "nextfile", + "rename", "delete", "undelete", "AddDevice", + "RemoteDevice", "PrintInstalledDevices", "InitCARD", "StartCARD", + "StopCARD", "sys_b0_4d", "_card_write", "_card_read", +// 0x50 + "_new_card", "Krom2RawAdd", "sys_b0_52", "sys_b0_53", + "_get_errno", "_get_error", "GetC0Table", "GetB0Table", + "_card_chan", "sys_b0_59", "sys_b0_5a", "ChangeClearPAD", + "_card_status", "_card_wait", +}; + +char *biosC0n[256] = { +// 0x00 + "InitRCnt", "InitException", "SysEnqIntRP", "SysDeqIntRP", + "get_free_EvCB_slot", "get_free_TCB_slot", "ExceptionHandler", "InstallExeptionHandler", + "SysInitMemory", "SysInitKMem", "ChangeClearRCnt", "SystemError", + "InitDefInt", "sys_c0_0d", "sys_c0_0e", "sys_c0_0f", +// 0x10 + "sys_c0_10", "sys_c0_11", "InstallDevices", "FlushStfInOutPut", + "sys_c0_14", "_cdevinput", "_cdevscan", "_circgetc", + "_circputc", "ioabort", "sys_c0_1a", "KernelRedirect", + "PatchAOTable", +}; + +//#define r0 (psxRegs.GPR.n.r0) +#define at (psxRegs.GPR.n.at) +#define v0 (psxRegs.GPR.n.v0) +#define v1 (psxRegs.GPR.n.v1) +#define a0 (psxRegs.GPR.n.a0) +#define a1 (psxRegs.GPR.n.a1) +#define a2 (psxRegs.GPR.n.a2) +#define a3 (psxRegs.GPR.n.a3) +#define t0 (psxRegs.GPR.n.t0) +#define t1 (psxRegs.GPR.n.t1) +#define t2 (psxRegs.GPR.n.t2) +#define t3 (psxRegs.GPR.n.t3) +#define t4 (psxRegs.GPR.n.t4) +#define t5 (psxRegs.GPR.n.t5) +#define t6 (psxRegs.GPR.n.t6) +#define t7 (psxRegs.GPR.n.t7) +#define s0 (psxRegs.GPR.n.s0) +#define s1 (psxRegs.GPR.n.s1) +#define s2 (psxRegs.GPR.n.s2) +#define s3 (psxRegs.GPR.n.s3) +#define s4 (psxRegs.GPR.n.s4) +#define s5 (psxRegs.GPR.n.s5) +#define s6 (psxRegs.GPR.n.s6) +#define s7 (psxRegs.GPR.n.s7) +#define t8 (psxRegs.GPR.n.t6) +#define t9 (psxRegs.GPR.n.t7) +#define k0 (psxRegs.GPR.n.k0) +#define k1 (psxRegs.GPR.n.k1) +#define gp (psxRegs.GPR.n.gp) +#define sp (psxRegs.GPR.n.sp) +#define fp (psxRegs.GPR.n.s8) +#define ra (psxRegs.GPR.n.ra) +#define pc0 (psxRegs.pc) + +#define Ra0 ((char*)PSXM(a0)) +#define Ra1 ((char*)PSXM(a1)) +#define Ra2 ((char*)PSXM(a2)) +#define Ra3 ((char*)PSXM(a3)) +#define Rv0 ((char*)PSXM(v0)) +#define Rsp ((char*)PSXM(sp)) + + + +typedef struct _malloc_chunk { + unsigned long stat; + unsigned long size; + struct _malloc_chunk *fd; + struct _malloc_chunk *bk; +} malloc_chunk; + +#define INUSE 0x1 + +typedef struct { + u32 desc; + s32 status; + s32 mode; + u32 fhandler; +} EvCB[32]; + +#define EvStUNUSED 0x0000 +#define EvStWAIT 0x1000 +#define EvStACTIVE 0x2000 +#define EvStALREADY 0x4000 + +#define EvMdINTR 0x1000 +#define EvMdNOINTR 0x2000 + +typedef struct { + long next; + long func1; + long func2; + long pad; +} SysRPst; + +typedef struct { + s32 status; + s32 mode; + u32 reg[32]; + u32 func; +} TCB; + +typedef struct { + unsigned long _pc0; + unsigned long gp0; + unsigned long t_addr; + unsigned long t_size; + unsigned long d_addr; + unsigned long d_size; + unsigned long b_addr; + unsigned long b_size; + unsigned long S_addr; + unsigned long s_size; + unsigned long _sp,_fp,_gp,ret,base; +} EXEC; + +struct DIRENTRY { + char name[20]; + long attr; + long size; + struct DIRENTRY *next; + long head; + char system[4]; +}; + +typedef struct { + char name[32]; + u32 mode; + u32 offset; + u32 size; + u32 mcfile; +} FileDesc; + +static unsigned long *jmp_int = NULL; +static int *pad_buf = NULL; +static char *pad_buf1,*pad_buf2;//shadow add +static int pad_buf1len,pad_buf2len;//shadow add + + +static u32 regs[35]; +static EvCB *Event; +static EvCB *HwEV; // 0xf0 +static EvCB *EvEV; // 0xf1 +static EvCB *RcEV; // 0xf2 +static EvCB *UeEV; // 0xf3 +static EvCB *SwEV; // 0xf4 +static EvCB *ThEV; // 0xff +static u32 *heap_addr = NULL; +static u32 SysIntRP[8]; +static int CardState = -1; +static TCB Thread[8]; +static int CurThread = 0; +static FileDesc FDesc[32]; + +static __inline void softCall(u32 pc) { + pc0 = pc; + ra = 0x80001000; + while (pc0 != 0x80001000) psxCpu->ExecuteBlock(); +} + +static __inline void softCall2(u32 pc) { + u32 sra = ra; + pc0 = pc; + ra = 0x80001000; + while (pc0 != 0x80001000) psxCpu->ExecuteBlock(); + ra = sra; +} + +static __inline void DeliverEvent(u32 ev, u32 spec) { + if (Event[ev][spec].status != EvStACTIVE) return; + +// Event[ev][spec].status = EvStALREADY; + if (Event[ev][spec].mode == EvMdINTR) { + softCall2(Event[ev][spec].fhandler); + } else Event[ev][spec].status = EvStALREADY; +} + +/* * +// * +// * +// System calls A0 */ + + +void bios_abs() { // 0x0e + v0 = abs(a0); + pc0 = ra; +} + +void bios_labs() { // 0x0f + v0 = labs(a0); + pc0 = ra; +} + +void bios_atoi() { // 0x10 + v0 = atoi((char *)Ra0); + pc0 = ra; +} + +void bios_atol() { // 0x11 + v0 = atoi((char *)Ra0); + pc0 = ra; +} + +void bios_setjmp() { // 13 + u32 *jmp_buf= (u32*)Ra0; + int i; + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosA0n[0x13]); +#endif + + jmp_buf[0] = ra; + jmp_buf[1] = sp; + jmp_buf[2] = fp; + for (i=0; i<8; i++) // s0-s7 + jmp_buf[3+i] = psxRegs.GPR.r[16+i]; + jmp_buf[11] = gp; + + v0 = 0; pc0 = ra; +} + +void bios_longjmp() { //14 + u32 *jmp_buf= (u32*)Ra0; + int i; + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosA0n[0x14]); +#endif + + ra = jmp_buf[0]; /* ra */ + sp = jmp_buf[1]; /* sp */ + fp = jmp_buf[2]; /* fp */ + for (i=0; i<8; i++) // s0-s7 + psxRegs.GPR.r[16+i] = jmp_buf[3+i]; + gp = jmp_buf[11]; /* gp */ + + v0 = a1; pc0 = ra; +} + +void bios_strcat() { // 0x15 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %s, %s\n", biosA0n[0x15], Ra0, Ra1); +#endif + + strcat(Ra0, Ra1); + v0 = a0; pc0 = ra; +} + +/*0x16*/void bios_strncat() { strncat(Ra0, Ra1, a2); v0 = a0; pc0 = ra;} + +void bios_strcmp() { // 0x17 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %s (%lx), %s (%lx)\n", biosA0n[0x17], Ra0, a0, Ra1, a1); +#endif + + v0 = strcmp(Ra0, Ra1); + pc0 = ra; +} + +void bios_strncmp() { // 0x18 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %s (%lx), %s (%lx), %d\n", biosA0n[0x18], Ra0, a0, Ra1, a1, a2); +#endif + + v0 = strncmp(Ra0, Ra1, a2); + pc0 = ra; +} + +/*0x19*/void bios_strcpy() { strcpy(Ra0, Ra1); v0 = a0; pc0 = ra;} +/*0x1a*/void bios_strncpy() { strncpy(Ra0, Ra1, a2); v0 = a0; pc0 = ra;} +/*0x1b*/void bios_strlen() { v0 = strlen(Ra0); pc0 = ra;} + +void bios_index() { // 0x1c + char *pcA0 = (char *)Ra0; + char *pcRet = strchr(pcA0, a1); + if(pcRet) + v0 = a0 + pcRet - pcA0; + else + v0 = 0; + pc0 = ra; +} + +void bios_rindex() { // 0x1d + char *pcA0 = (char *)Ra0; + char *pcRet = strrchr(pcA0, a1); + if(pcRet) + v0 = a0 + pcRet - pcA0; + else + v0 = 0; + pc0 = ra; +} + +void bios_strchr() { // 0x1e + char *pcA0 = (char *)Ra0; + char *pcRet = strchr(pcA0, a1); + if(pcRet) + v0 = a0 + pcRet - pcA0; + else + v0 = 0; + pc0 = ra; +} + +void bios_strrchr() { // 0x1f + char *pcA0 = (char *)Ra0; + char *pcRet = strrchr(pcA0, a1); + if(pcRet) + v0 = a0 + pcRet - pcA0; + else + v0 = 0; + pc0 = ra; +} + +void bios_strpbrk() { // 0x20 + char *pcA0 = (char *)Ra0; + char *pcRet = strpbrk(pcA0, (char *)Ra1); + if(pcRet) + v0 = a0 + pcRet - pcA0; + else + v0 = 0; + pc0 = ra; +} + +void bios_strspn() { v0 = strspn ((char *)Ra0, (char *)Ra1); pc0 = ra;}/*21*/ +void bios_strcspn() { v0 = strcspn((char *)Ra0, (char *)Ra1); pc0 = ra;}/*22*/ + +void bios_strtok() { // 0x23 + char *pcA0 = (char *)Ra0; + char *pcRet = strtok(pcA0, (char *)Ra1); + if(pcRet) + v0 = a0 + pcRet - pcA0; + else + v0 = 0; + pc0 = ra; +} + +void bios_strstr() { // 0x24 + char *pcA0 = (char *)Ra0; + char *pcRet = strstr(pcA0, (char *)Ra1); + if(pcRet) + v0 = a0 + pcRet - pcA0; + else + v0 = 0; + pc0 = ra; +} + +/*0x25*/void bios_toupper() {v0 = toupper(a0); pc0 = ra;} +/*0x26*/void bios_tolower() {v0 = tolower(a0); pc0 = ra;} +/*0x27*/void bios_bcopy() {memcpy(Ra1,Ra0,a2); pc0=ra;} +/*0x28*/void bios_bzero() {memset(Ra0,0,a1); pc0=ra;} +/*0x29*/void bios_bcmp() {v0 = memcmp(Ra0,Ra1,a2); pc0=ra; } +/*0x2a*/void bios_memcpy() {memcpy(Ra0, Ra1, a2); v0 = a0; pc0 = ra;} +/*0x2b*/void bios_memset() {memset(Ra0, a1, a2); v0 = a0; pc0 = ra;} +/*0x2c*/void bios_memmove() {memmove(Ra0, Ra1, a2); v0 = a0; pc0 = ra;} +/*0x2d*/void bios_memcmp() {v0 = memcmp(Ra0, Ra1, a2); pc0 = ra;} + +void bios_memchr() { // 2e + void *ret = memchr(Ra0, a1, a2); + if (ret != NULL) v0 = (unsigned long)((char*)ret - Ra0) + a0; + else v0 = 0; + pc0 = ra; +} + +void bios_rand() { // 2f + v0 = 1+(int) (32767.0*rand()/(RAND_MAX+1.0)); + pc0 = ra; +} + +void bios_srand() { // 30 + srand(a0); pc0 = ra; +} + +void bios_malloc() { // 33 + malloc_chunk *chunk; + malloc_chunk *fd; + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosA0n[0x33]); +#endif + + chunk = (malloc_chunk *)heap_addr; + if (chunk == NULL) { v0 = 0; return; } + + for (; ((a0 > chunk->size) || (chunk->stat == INUSE)) || (chunk->fd != NULL); chunk = chunk->fd); +//printf ("chunk %lx\n",chunk->size); + /* split free chunk */ + fd = chunk + sizeof(malloc_chunk) + a0; + fd->stat = chunk->stat; + fd->size = chunk->size - a0; + fd->fd = chunk->fd; + fd->bk = chunk; + + /* set new chunk */ + chunk->stat = INUSE; + chunk->size = a0; + chunk->fd = fd; + + v0 = ((unsigned long)chunk - (unsigned long)psxM) + sizeof(malloc_chunk); + v0|= 0x80000000; +// printf ("malloc %lx,%lx\n", v0, a0); + pc0 = ra; +} + +void bios_InitHeap() { // 39 + malloc_chunk *chunk; + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosA0n[0x39]); +#endif + + heap_addr = (u32*)Ra0; + + chunk = (malloc_chunk *)heap_addr; + chunk->stat = 0; + if (((a0 & 0x1fffff) + a1)>= 0x200000) chunk->size = 0x1ffffc - (a0 & 0x1fffff); + else chunk->size = a1; + chunk->fd = NULL; + chunk->bk = NULL; + + SysPrintf("InitHeap %lx,%lx : %lx\n",a0,a1,chunk->size); + + pc0 = ra; +} + +void bios_getchar(){ v0 = getchar(); pc0=ra;} //0x3b + +void bios_printf() { // 3f + char tmp[1024]; + char tmp2[1024]; + unsigned long save[4]; + char *ptmp = tmp; + int n=1, i=0, j; + + memcpy(save, (char*)PSXM(sp), 4*4); + psxMu32(sp) = a0; + psxMu32(sp + 4) = a1; + psxMu32(sp + 8) = a2; + psxMu32(sp + 12) = a3; + + while (Ra0[i]) { + switch (Ra0[i]) { + case '%': + j = 0; + tmp2[j++] = '%'; +_start: + switch (Ra0[++i]) { + case '.': + case 'l': + tmp2[j++] = Ra0[i]; goto _start; + default: + if (Ra0[i] >= '0' && Ra0[i] <= '9') { + tmp2[j++] = Ra0[i]; + goto _start; + } + break; + } + tmp2[j++] = Ra0[i]; + tmp2[j] = 0; + + switch (Ra0[i]) { + case 'f': case 'F': + ptmp+= sprintf(ptmp, tmp2, (float)psxMu32(sp + n * 4)); n++; break; + case 'a': case 'A': + case 'e': case 'E': + case 'g': case 'G': + ptmp+= sprintf(ptmp, tmp2, (double)psxMu32(sp + n * 4)); n++; break; + case 'p': + case 'i': + case 'd': case 'D': + case 'o': case 'O': + case 'x': case 'X': + ptmp+= sprintf(ptmp, tmp2, (unsigned int)psxMu32(sp + n * 4)); n++; break; + case 'c': + ptmp+= sprintf(ptmp, tmp2, (unsigned char)psxMu32(sp + n * 4)); n++; break; + case 's': + ptmp+= sprintf(ptmp, tmp2, (char*)PSXM(psxMu32(sp + n * 4))); n++; break; + case '%': + *ptmp++ = Ra0[i]; break; + } + i++; + break; + default: + *ptmp++ = Ra0[i++]; + } + } + *ptmp = 0; + + memcpy((char*)PSXM(sp), save, 4*4); + + SysPrintf(tmp); + + pc0 = ra; +} + +/* + * int Exec(struct EXEC *header , int argc , char **argv); + */ + +void bios_Exec() { // 43 + EXEC *header = (EXEC*)Ra0; + u32 tmp; + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %x, %x, %x\n", biosA0n[0x43], a0, a1, a2); +#endif + + header->_sp = sp; + header->_fp = fp; + header->_sp = sp; + header->_gp = gp; + header->ret = ra; + header->base = s0; + + if (header->S_addr != 0) { + tmp = header->S_addr + header->s_size; + sp = tmp; + fp = sp; + } + + gp = header->gp0; + + s0 = a0; + + a0 = a1; + a1 = a2; + + ra = 0x8000; + pc0 = header->_pc0; +} + +void bios_FlushCache() { // 44 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosA0n[0x44]); +#endif + + pc0 = ra; +} + +void bios_GPU_dw() { // 0x46 + int size; + long *ptr; + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosA0n[0x46]); +#endif + + GPU_writeData(0xa0000000); + GPU_writeData((a1<<16)|(a0&0xffff)); + GPU_writeData((a3<<16)|(a2&0xffff)); + size = (a2*a3+1)/2; + ptr = (long*)PSXM(Rsp[4]); //that is correct? + do { + GPU_writeData(*ptr++); + } while(--size); + + pc0 = ra; +} + +void bios_mem2vram() { // 0x47 + int size; + + GPU_writeData(0xa0000000); + GPU_writeData((a1<<16)|(a0&0xffff)); + GPU_writeData((a3<<16)|(a2&0xffff)); + size = (a2*a3+1)/2; + GPU_writeStatus(0x04000002); + psxHwWrite32(0x1f8010f4,0); + psxHwWrite32(0x1f8010f0,psxHwRead32(0x1f8010f0)|0x800); + psxHwWrite32(0x1f8010a0,Rsp[4]);//might have a buggy... + psxHwWrite32(0x1f8010a4,((size/16)<<16)|16); + psxHwWrite32(0x1f8010a8,0x01000201); + + pc0 = ra; +} + +void bios_SendGPU() { // 0x48 + GPU_writeStatus(a0); + pc0 = ra; +} + +void bios_GPU_cw() { // 0x49 + GPU_writeData(a0); + pc0 = ra; +} + +void bios_GPU_cwb() { // 0x4a + long *ptr = (long*)Ra0; + int size = a1; + while(size--) { + GPU_writeData(*ptr++); + } + + pc0 = ra; +} + +void bios_GPU_SendPackets() { //4b: + GPU_writeStatus(0x04000002); + psxHwWrite32(0x1f8010f4,0); + psxHwWrite32(0x1f8010f0,psxHwRead32(0x1f8010f0)|0x800); + psxHwWrite32(0x1f8010a0,a0); + psxHwWrite32(0x1f8010a4,0); + psxHwWrite32(0x1f8010a8,0x010000401); + pc0 = ra; +} + +void bios_sys_a0_4c() { // 0x4c GPU relate + psxHwWrite32(0x1f8010a8,0x00000401); + GPU_writeData(0x0400000); + GPU_writeData(0x0200000); + GPU_writeData(0x0100000); + + pc0 = ra; +} + +void bios_GPU_GetGPUStatus() { // 0x4d + v0 = GPU_readStatus(); + pc0 = ra; +} + +void bios__bu_init() { // 70 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosA0n[0x70]); +#endif + + DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004 + DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004 + + pc0 = ra; +} + +void bios__96_remove() { // 72 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosA0n[0x72]); +#endif + + pc0 = ra; +} + +void bios__card_info() { // ab +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %x\n", biosA0n[0xab], a0); +#endif + +// DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004 + DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004 + + v0 = 1; pc0 = ra; +} + +void bios__card_load() { // ac +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %x\n", biosA0n[0xac], a0); +#endif + +// DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004 + DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004 + + v0 = 1; pc0 = ra; +} + +/* System calls B0 */ + +void bios_SetRCnt() { // 02 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosB0n[0x02]); +#endif + + a0&= 0x3; + if (a0 != 3) { + unsigned long mode=0; + + psxRcntWtarget(a0, a1); + if (a2&0x1000) mode|= 0x050; // Interrupt Mode + if (a2&0x0100) mode|= 0x008; // Count to 0xffff + if (a2&0x0010) mode|= 0x001; // Timer stop mode + if (a0 == 2) { if (a2&0x0001) mode|= 0x200; } // System Clock mode + else { if (a2&0x0001) mode|= 0x100; } // System Clock mode + + psxRcntWmode(a0, mode); + } + pc0 = ra; +} + +void bios_GetRCnt() { // 03 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosB0n[0x03]); +#endif + + a0&= 0x3; + if (a0 != 3) v0 = psxRcntRcount(a0); + else v0 = 0; + pc0 = ra; +} + +void bios_StartRCnt() { // 04 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosB0n[0x04]); +#endif + + a0&= 0x3; + if (a0 != 3) psxHu32(0x1074)|= (1<<(a0+4)); + else psxHu32(0x1074)|= 0x1; + v0 = 1; pc0 = ra; +} + +void bios_StopRCnt() { // 05 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosB0n[0x05]); +#endif + + a0&= 0x3; + if (a0 != 3) psxHu32(0x1074)&= ~(1<<(a0+4)); + else psxHu32(0x1074)&= ~0x1; + pc0 = ra; +} + +void bios_ResetRCnt() { // 06 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosB0n[0x06]); +#endif + + a0&= 0x3; + if (a0 != 3) { + psxRcntWmode(a0, 0); + psxRcntWtarget(a0, 0); + psxRcntWcount(a0, 0); + } + pc0 = ra; +} + + +/* gets ev for use with Event */ +#define GetEv() \ + ev = (a0 >> 24) & 0xf; \ + if (ev == 0xf) ev = 0x5; \ + ev*= 32; \ + ev+= a0&0x1f; + +/* gets spec for use with Event */ +#define GetSpec() \ + spec = 0; \ + switch (a1) { \ + case 0x0301: spec = 16; break; \ + case 0x0302: spec = 17; break; \ + default: \ + for (i=0; i<16; i++) if (a1 & (1 << i)) { spec = i; break; } \ + break; \ + } + +void bios_DeliverEvent() { // 07 + int ev, spec; + int i; + + GetEv(); + GetSpec(); + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s %x,%x\n", biosB0n[0x07], ev, spec); +#endif + + DeliverEvent(ev, spec); + + pc0 = ra; +} + +void bios_OpenEvent() { // 08 + int ev, spec; + int i; + + GetEv(); + GetSpec(); + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s %x,%x (class:%lx, spec:%lx, mode:%lx, func:%lx)\n", biosB0n[0x08], ev, spec, a0, a1, a2, a3); +#endif + + Event[ev][spec].status = EvStWAIT; + Event[ev][spec].mode = a2; + Event[ev][spec].fhandler = a3; + + v0 = ev | (spec << 8); + pc0 = ra; +} + +void bios_CloseEvent() { // 09 + int ev, spec; + + ev = a0 & 0xff; + spec = (a0 >> 8) & 0xff; + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s %x,%x\n", biosB0n[0x09], ev, spec); +#endif + + Event[ev][spec].status = EvStUNUSED; + + v0 = 1; pc0 = ra; +} + +void bios_WaitEvent() { // 0a + int ev, spec; + + ev = a0 & 0xff; + spec = (a0 >> 8) & 0xff; + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s %x,%x\n", biosB0n[0x0a], ev, spec); +#endif + + Event[ev][spec].status = EvStACTIVE; + + v0 = 1; pc0 = ra; +} + +void bios_TestEvent() { // 0b + int ev, spec; + + ev = a0 & 0xff; + spec = (a0 >> 8) & 0xff; + + if (Event[ev][spec].status == EvStALREADY) { + Event[ev][spec].status = EvStACTIVE; v0 = 1; + } else v0 = 0; + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s %x,%x: %x\n", biosB0n[0x0b], ev, spec, v0); +#endif + + pc0 = ra; +} + +void bios_EnableEvent() { // 0c + int ev, spec; + + ev = a0 & 0xff; + spec = (a0 >> 8) & 0xff; + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s %x,%x\n", biosB0n[0x0c], ev, spec); +#endif + + Event[ev][spec].status = EvStACTIVE; + + v0 = 1; pc0 = ra; +} + +void bios_DisableEvent() { // 0d + int ev, spec; + + ev = a0 & 0xff; + spec = (a0 >> 8) & 0xff; + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s %x,%x\n", biosB0n[0x0d], ev, spec); +#endif + + Event[ev][spec].status = EvStWAIT; + + v0 = 1; pc0 = ra; +} + +/* + * long OpenTh(long (*func)(), unsigned long sp, unsigned long gp); + */ + +void bios_OpenTh() { // 0e + int th; + + for (th=1; th<8; th++) + if (Thread[th].status == 0) break; + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %x\n", biosB0n[0x0e], th); +#endif + + Thread[th].status = 1; + Thread[th].func = a0; + Thread[th].reg[29] = a1; + Thread[th].reg[28] = a2; + + v0 = th; pc0 = ra; +} + +/* + * int CloseTh(long thread); + */ + +void bios_CloseTh() { // 0f + int th = a0 & 0xff; + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %x\n", biosB0n[0x0f], th); +#endif + + if (Thread[th].status == 0) { + v0 = 0; + } else { + Thread[th].status = 0; + v0 = 1; + } + + pc0 = ra; +} + +/* + * int ChangeTh(long thread); + */ + +void bios_ChangeTh() { // 10 + int th = a0 & 0xff; + +#ifdef PSXBIOS_LOG +// PSXBIOS_LOG("bios_%s: %x\n", biosB0n[0x10], th); +#endif + + if (Thread[th].status == 0 || CurThread == th) { + v0 = 0; + + pc0 = ra; + } else { + v0 = 1; + + if (Thread[CurThread].status == 2) { + Thread[CurThread].status = 1; + Thread[CurThread].func = ra; + memcpy(Thread[CurThread].reg, psxRegs.GPR.r, 32*4); + } + + memcpy(psxRegs.GPR.r, Thread[th].reg, 32*4); + pc0 = Thread[th].func; + Thread[th].status = 2; + CurThread = th; + } +} + +void bios_InitPAD() { // 0x12 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosB0n[0x12]); +#endif + + pad_buf1 = (char*)Ra0; + pad_buf1len = a1; + pad_buf2 = (char*)Ra2; + pad_buf2len = a3; + + v0 = 1; pc0 = ra; +} + +void bios_StartPAD() { // 13 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosB0n[0x13]); +#endif + + psxHwWrite16(0x1f801074, (unsigned short)(psxHwRead16(0x1f801074) | 0x1)); + psxRegs.CP0.n.Status |= 0x401; + pc0 = ra; +} + +void bios_StopPAD() { // 14 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosB0n[0x14]); +#endif + + pad_buf1 = NULL; + pad_buf2 = NULL; + pc0 = ra; +} + +void bios_PAD_init() { // 15 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosB0n[0x15]); +#endif + + psxHwWrite16(0x1f801074, (u16)(psxHwRead16(0x1f801074) | 0x1)); + pad_buf = (int*)Ra1; + *pad_buf = -1; + psxRegs.CP0.n.Status |= 0x401; + pc0 = ra; +} + +void bios_PAD_dr() { // 16 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosB0n[0x16]); +#endif + + v0 = -1; pc0 = ra; +} + +void bios_ReturnFromException() { // 17 + memcpy(psxRegs.GPR.r, regs, 32*4); + psxRegs.GPR.n.lo = regs[32]; + psxRegs.GPR.n.hi = regs[33]; + + pc0 = psxRegs.CP0.n.EPC; + if (psxRegs.CP0.n.Cause & 0x80000000) pc0+=4; + + psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status & 0xfffffff0) | + ((psxRegs.CP0.n.Status & 0x3c) >> 2); +} + +void bios_ResetEntryInt() { // 18 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosB0n[0x18]); +#endif + + jmp_int = NULL; + pc0 = ra; +} + +void bios_HookEntryInt() { // 19 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosB0n[0x19]); +#endif + + jmp_int = (u32*)Ra0; + pc0 = ra; +} + +void bios_UnDeliverEvent() { // 0x20 + int ev, spec; + int i; + + GetEv(); + GetSpec(); + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s %x,%x\n", biosB0n[0x07], ev, spec); +#endif + + if (Event[ev][spec].status == EvStALREADY && + Event[ev][spec].mode == EvMdNOINTR) + Event[ev][spec].status = EvStACTIVE; + + pc0 = ra; +} + +#define buopen(mcd) { \ + strcpy(FDesc[1 + mcd].name, Ra0+5); \ + FDesc[1 + mcd].offset = 0; \ + FDesc[1 + mcd].mode = a1; \ + \ + for (i=1; i<16; i++) { \ + ptr = Mcd##mcd##Data + 128 * i; \ + if ((*ptr & 0xF0) != 0x50) continue; \ + if (strcmp(FDesc[1 + mcd].name, ptr+0xa)) continue; \ + FDesc[1 + mcd].mcfile = i; \ + SysPrintf("open %s\n", ptr+0xa); \ + v0 = 1 + mcd; \ + break; \ + } \ + if (a1 & 0x200 && v0 == -1) { /* FCREAT */ \ + for (i=1; i<16; i++) { \ + int j, xor = 0; \ + \ + ptr = Mcd##mcd##Data + 128 * i; \ + if ((*ptr & 0xF0) == 0x50) continue; \ + ptr[0] = 0x50 | (u8)(a1 >> 16); \ + ptr[4] = 0x00; \ + ptr[5] = 0x20; \ + ptr[6] = 0x00; \ + ptr[7] = 0x00; \ + ptr[8] = 'B'; \ + ptr[9] = 'I'; \ + strcpy(ptr+0xa, FDesc[1 + mcd].name); \ + for (j=0; j<127; j++) xor^= ptr[j]; \ + ptr[127] = xor; \ + FDesc[1 + mcd].mcfile = i; \ + SysPrintf("openC %s\n", ptr); \ + v0 = 1 + mcd; \ + break; \ + } \ + } \ +} + +/* + * int open(char *name , int mode); + */ + +void bios_open() { // 0x32 + int i; + char *ptr; + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %s,%x\n", biosB0n[0x32], Ra0, a1); +#endif + + v0 = -1; + + if (!strncmp(Ra0, "bu00", 4)) { + buopen(1); + } + + if (!strncmp(Ra0, "bu10", 4)) { + buopen(2); + } + + pc0 = ra; +} + +/* + * int lseek(int fd , int offset , int whence); + */ + +void bios_lseek() { // 0x33 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %x, %x, %x\n", biosB0n[0x33], a0, a1, a2); +#endif + + switch (a2) { + case 0: // SEEK_SET + FDesc[a0].offset = a1; + v0 = a1; +// DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004 +// DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004 + break; + + case 1: // SEEK_CUR + FDesc[a0].offset+= a1; + v0 = FDesc[a0].offset; + break; + } + + pc0 = ra; +} + +#define buread(mcd) { \ + SysPrintf("read %d: %x,%x (%s)\n", FDesc[1 + mcd].mcfile, FDesc[1 + mcd].offset, a2, Mcd##mcd##Data + 128 * FDesc[1 + mcd].mcfile + 0xa); \ + ptr = Mcd##mcd##Data + 8192 * FDesc[1 + mcd].mcfile + FDesc[1 + mcd].offset; \ + memcpy(Ra1, ptr, a2); \ + if (FDesc[1 + mcd].mode & 0x8000) v0 = 0; \ + else v0 = a2; \ + DeliverEvent(0x11, 0x2); /* 0xf0000011, 0x0004 */ \ + DeliverEvent(0x81, 0x2); /* 0xf4000001, 0x0004 */ \ +} + +/* + * int read(int fd , void *buf , int nbytes); + */ + +void bios_read() { // 0x34 + char *ptr; + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %x, %x, %x\n", biosB0n[0x34], a0, a1, a2); +#endif + + v0 = -1; + + switch (a0) { + case 2: buread(1); break; + case 3: buread(2); break; + } + + pc0 = ra; +} + +#define buwrite(mcd) { \ + u32 offset = + 8192 * FDesc[1 + mcd].mcfile + FDesc[1 + mcd].offset; \ + SysPrintf("write %d: %x,%x\n", FDesc[1 + mcd].mcfile, FDesc[1 + mcd].offset, a2); \ + ptr = Mcd##mcd##Data + offset; \ + memcpy(ptr, Ra1, a2); \ + SaveMcd(Config.Mcd##mcd, Mcd##mcd##Data, offset, a2); \ + if (FDesc[1 + mcd].mode & 0x8000) v0 = 0; \ + else v0 = a2; \ + DeliverEvent(0x11, 0x2); /* 0xf0000011, 0x0004 */ \ + DeliverEvent(0x81, 0x2); /* 0xf4000001, 0x0004 */ \ +} + +/* + * int write(int fd , void *buf , int nbytes); + */ + +void bios_write() { // 0x35/0x03 + char *ptr; + + if (a0 == 1) { // stdout + char buf[1024]; + + memcpy(buf, Ra1, a2); + buf[a2] = 0; + SysPrintf(buf); + pc0 = ra; return; + } +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %x,%x,%x\n", biosB0n[0x35], a0, a1, a2); +#endif + + v0 = -1; + + switch (a0) { + case 2: buwrite(1); break; + case 3: buwrite(2); break; + } + + pc0 = ra; +} + +/* + * int close(int fd); + */ + +void bios_close() { // 0x36 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %x\n", biosB0n[0x36], a0); +#endif + + v0 = a0; pc0 = ra; +} + +void bios_putchar () { // 3d + char tmp[12]; + + sprintf (tmp,"%c",(char)a0); + SysPrintf(tmp); + + pc0 = ra; +} + +void bios_puts () { // 3e/3f + SysPrintf(Ra0); + + pc0 = ra; +} + +char ffile[64], *pfile; +int nfile; + +#define bufile(mcd) { \ + while (nfile < 16) { \ + int match=1; \ + \ + ptr = Mcd##mcd##Data + 128 * nfile; \ + nfile++; \ + if ((*ptr & 0xF0) != 0x50) continue; \ + ptr+= 0xa; \ + for (i=0; i<20; i++) { \ + if (pfile[i] == ptr[i]) { \ + dir->name[i] = ptr[i]; \ + if (ptr[i] == 0) break; else continue; } \ + if (pfile[i] == '?') { \ + dir->name[i] = ptr[i]; continue; } \ + if (pfile[i] == '*') { \ + strcpy(dir->name+i, ptr+i); break; } \ + match = 0; break; \ + } \ + SysPrintf("%d : %s = %s + %s (match=%d)\n", nfile, dir->name, pfile, ptr, match); \ + if (match == 0) continue; \ + dir->size = 8192; \ + v0 = _dir; \ + break; \ + } \ +} + +/* + * struct DIRENTRY* firstfile(char *name,struct DIRENTRY *dir); + */ + +void bios_firstfile() { // 42 + struct DIRENTRY *dir = (struct DIRENTRY *)Ra1; + u32 _dir = a1; + char *ptr; + int i; + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %s\n", biosB0n[0x42], Ra0); +#endif + + v0 = 0; + + strcpy(ffile, Ra0); + pfile = ffile+5; + nfile = 1; + if (!strncmp(Ra0, "bu00", 4)) { + bufile(1); + } + + if (!strncmp(Ra0, "bu10", 4)) { + bufile(2); + } + + pc0 = ra; +} + +/* + * struct DIRENTRY* nextfile(struct DIRENTRY *dir); + */ + +void bios_nextfile() { // 43 + struct DIRENTRY *dir = (struct DIRENTRY *)Ra0; + u32 _dir = a0; + char *ptr; + int i; + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %s\n", biosB0n[0x43], dir->name); +#endif + + v0 = 0; + + if (!strncmp(ffile, "bu00", 4)) { + bufile(1); + } + + if (!strncmp(ffile, "bu10", 4)) { + bufile(2); + } + + pc0 = ra; +} + +#define budelete(mcd) { \ + for (i=1; i<16; i++) { \ + ptr = Mcd##mcd##Data + 128 * i; \ + if ((*ptr & 0xF0) != 0x50) continue; \ + if (strcmp(Ra0+5, ptr+0xa)) continue; \ + *ptr = (*ptr & 0xf) | 0xA0; \ + SysPrintf("delete %s\n", ptr+0xa); \ + v0 = 1; \ + break; \ + } \ +} + +/* + * int delete(char *name); + */ + +void bios_delete() { // 45 + char *ptr; + int i; + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %s\n", biosB0n[0x45], Ra0); +#endif + + v0 = 0; + + if (!strncmp(Ra0, "bu00", 4)) { + budelete(1); + } + + if (!strncmp(Ra0, "bu10", 4)) { + budelete(2); + } + + pc0 = ra; +} + +void bios_InitCARD() { // 4a +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %x\n", biosB0n[0x4a], a0); +#endif + + CardState = 0; + + pc0 = ra; +} + +void bios_StartCARD() { // 4b +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosB0n[0x4b]); +#endif + + if (CardState == 0) CardState = 1; + + pc0 = ra; +} + +void bios_StopCARD() { // 4c +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosB0n[0x4c]); +#endif + + if (CardState == 1) CardState = 0; + + pc0 = ra; +} + +void bios__card_write() { // 0x4e + int port; + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %x,%x,%x\n", biosB0n[0x4e], a0, a1, a2); +#endif + + port = a0 >> 4; + + if (port == 0) { + memcpy(Mcd1Data + a1 * 128, Ra2, 128); + SaveMcd(Config.Mcd1, Mcd1Data, a1 * 128, 128); + } else { + memcpy(Mcd2Data + a1 * 128, Ra2, 128); + SaveMcd(Config.Mcd2, Mcd2Data, a1 * 128, 128); + } + + DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004 +// DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004 + + v0 = 1; pc0 = ra; +} + +void bios__card_read() { // 0x4f + int port; + +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosB0n[0x4f]); +#endif + + port = a0 >> 4; + + if (port == 0) { + memcpy(Ra2, Mcd1Data + a1 * 128, 128); + } else { + memcpy(Ra2, Mcd2Data + a1 * 128, 128); + } + + DeliverEvent(0x11, 0x2); // 0xf0000011, 0x0004 +// DeliverEvent(0x81, 0x2); // 0xf4000001, 0x0004 + + v0 = 1; pc0 = ra; +} + +void bios__new_card() { // 0x50 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosB0n[0x50]); +#endif + + pc0 = ra; +} + +void bios_GetC0Table() { // 56 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosB0n[0x56]); +#endif + + v0 = 0x674; pc0 = ra; +} + +void bios_GetB0Table() { // 57 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s\n", biosB0n[0x57]); +#endif + + v0 = 0x874; pc0 = ra; +} + +void bios_ChangeClearPad() { // 5b +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %x\n", biosB0n[0x5b], a0); +#endif + + pc0 = ra; +} + +/* System calls C0 */ + +/* + * int SysEnqIntRP(int index , long *queue); + */ + +void bios_SysEnqIntRP() { // 02 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %x\n", biosC0n[0x02] ,a0); +#endif + + SysIntRP[a0] = a1; + + v0 = 0; pc0 = ra; +} + +/* + * int SysDeqIntRP(int index , long *queue); + */ + +void bios_SysDeqIntRP() { // 03 +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %x\n", biosC0n[0x03] ,a0); +#endif + + SysIntRP[a0] = 0; + + v0 = 0; pc0 = ra; +} + +void bios_ChangeClearRCnt() { // 0a +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("bios_%s: %x\n", biosC0n[0x0a] ,a0); +#endif + + psxRegs.CP0.n.Status|= 0x404; + pc0 = ra; +} + +void bios_dummy() { +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("unk %lx call: %lx\n", pc0 & 0x1fffff, t1); +#endif + pc0 = ra; +} + +void (*biosA0[256])(); +void (*biosB0[256])(); +void (*biosC0[256])(); + +void psxBiosInit() { + u32 base, size; + u32 *ptr; + int i; + + for(i = 0; i < 256; i++) { + biosA0[i] = NULL; + biosB0[i] = NULL; + biosC0[i] = NULL; + } + biosA0[0x3e] = bios_puts; + biosA0[0x3f] = bios_printf; + + biosB0[0x3d] = bios_putchar; + biosB0[0x3f] = bios_puts; + + if (!Config.HLE) return; + + for(i = 0; i < 256; i++) { + if (biosA0[i] == NULL) biosA0[i] = bios_dummy; + if (biosB0[i] == NULL) biosB0[i] = bios_dummy; + if (biosC0[i] == NULL) biosC0[i] = bios_dummy; + } + + biosA0[0x00] = bios_open; + biosA0[0x01] = bios_lseek; + biosA0[0x02] = bios_read; + biosA0[0x03] = bios_write; + biosA0[0x04] = bios_close; + //biosA0[0x05] = bios_ioctl; + //biosA0[0x06] = bios_exit; + //biosA0[0x07] = bios_sys_a0_07; + //biosA0[0x08] = bios_getc; + //biosA0[0x09] = bios_putc; + //biosA0[0x0a] = bios_todigit; + //biosA0[0x0b] = bios_atof; + //biosA0[0x0c] = bios_strtoul; + //biosA0[0x0d] = bios_strtol; + biosA0[0x0e] = bios_abs; + biosA0[0x0f] = bios_labs; + biosA0[0x10] = bios_atoi; + biosA0[0x11] = bios_atol; + //biosA0[0x12] = bios_atob; + biosA0[0x13] = bios_setjmp; + biosA0[0x14] = bios_longjmp; + biosA0[0x15] = bios_strcat; + biosA0[0x16] = bios_strncat; + biosA0[0x17] = bios_strcmp; + biosA0[0x18] = bios_strncmp; + biosA0[0x19] = bios_strcpy; + biosA0[0x1a] = bios_strncpy; + biosA0[0x1b] = bios_strlen; + biosA0[0x1c] = bios_index; + biosA0[0x1d] = bios_rindex; + biosA0[0x1e] = bios_strchr; + biosA0[0x1f] = bios_strrchr; + biosA0[0x20] = bios_strpbrk; + biosA0[0x21] = bios_strspn; + biosA0[0x22] = bios_strcspn; + biosA0[0x23] = bios_strtok; + biosA0[0x24] = bios_strstr; + biosA0[0x25] = bios_toupper; + biosA0[0x26] = bios_tolower; + biosA0[0x27] = bios_bcopy; + biosA0[0x28] = bios_bzero; + biosA0[0x29] = bios_bcmp; + biosA0[0x2a] = bios_memcpy; + biosA0[0x2b] = bios_memset; + biosA0[0x2c] = bios_memmove; + biosA0[0x2d] = bios_memcmp; + biosA0[0x2e] = bios_memchr; + biosA0[0x2f] = bios_rand; + biosA0[0x30] = bios_srand; + //biosA0[0x31] = bios_qsort; + //biosA0[0x32] = bios_strtod; + biosA0[0x33] = bios_malloc; + //biosA0[0x34] = bios_free; + //biosA0[0x35] = bios_lsearch; + //biosA0[0x36] = bios_bsearch; + //biosA0[0x37] = bios_calloc; + //biosA0[0x38] = bios_realloc; + biosA0[0x39] = bios_InitHeap; + //biosA0[0x3a] = bios__exit; + biosA0[0x3b] = bios_getchar; + biosA0[0x3c] = bios_putchar; + //biosA0[0x3d] = bios_gets; + //biosA0[0x40] = bios_sys_a0_40; + //biosA0[0x41] = bios_LoadTest; + //biosA0[0x42] = bios_Load; + biosA0[0x43] = bios_Exec; + biosA0[0x44] = bios_FlushCache; + //biosA0[0x45] = bios_InstallInterruptHandler; + biosA0[0x46] = bios_GPU_dw; + biosA0[0x47] = bios_mem2vram; + biosA0[0x48] = bios_SendGPU; + biosA0[0x49] = bios_GPU_cw; + biosA0[0x4a] = bios_GPU_cwb; + biosA0[0x4b] = bios_GPU_SendPackets; + biosA0[0x4c] = bios_sys_a0_4c; + biosA0[0x4d] = bios_GPU_GetGPUStatus; + //biosA0[0x4e] = bios_GPU_sync; + //biosA0[0x4f] = bios_sys_a0_4f; + //biosA0[0x50] = bios_sys_a0_50; + //biosA0[0x51] = bios_LoadExec; + //biosA0[0x52] = bios_GetSysSp; + //biosA0[0x53] = bios_sys_a0_53; + //biosA0[0x54] = bios__96_init_a54; + //biosA0[0x55] = bios__bu_init_a55; + //biosA0[0x56] = bios__96_remove_a56; + //biosA0[0x57] = bios_sys_a0_57; + //biosA0[0x58] = bios_sys_a0_58; + //biosA0[0x59] = bios_sys_a0_59; + //biosA0[0x5a] = bios_sys_a0_5a; + //biosA0[0x5b] = bios_dev_tty_init; + //biosA0[0x5c] = bios_dev_tty_open; + //biosA0[0x5d] = bios_sys_a0_5d; + //biosA0[0x5e] = bios_dev_tty_ioctl; + //biosA0[0x5f] = bios_dev_cd_open; + //biosA0[0x60] = bios_dev_cd_read; + //biosA0[0x61] = bios_dev_cd_close; + //biosA0[0x62] = bios_dev_cd_firstfile; + //biosA0[0x63] = bios_dev_cd_nextfile; + //biosA0[0x64] = bios_dev_cd_chdir; + //biosA0[0x65] = bios_dev_card_open; + //biosA0[0x66] = bios_dev_card_read; + //biosA0[0x67] = bios_dev_card_write; + //biosA0[0x68] = bios_dev_card_close; + //biosA0[0x69] = bios_dev_card_firstfile; + //biosA0[0x6a] = bios_dev_card_nextfile; + //biosA0[0x6b] = bios_dev_card_erase; + //biosA0[0x6c] = bios_dev_card_undelete; + //biosA0[0x6d] = bios_dev_card_format; + //biosA0[0x6e] = bios_dev_card_rename; + //biosA0[0x6f] = bios_dev_card_6f; + biosA0[0x70] = bios__bu_init; + //biosA0[0x71] = bios__96_init; + biosA0[0x72] = bios__96_remove; + //biosA0[0x73] = bios_sys_a0_73; + //biosA0[0x74] = bios_sys_a0_74; + //biosA0[0x75] = bios_sys_a0_75; + //biosA0[0x76] = bios_sys_a0_76; + //biosA0[0x77] = bios_sys_a0_77; + //biosA0[0x78] = bios__96_CdSeekL; + //biosA0[0x79] = bios_sys_a0_79; + //biosA0[0x7a] = bios_sys_a0_7a; + //biosA0[0x7b] = bios_sys_a0_7b; + //biosA0[0x7c] = bios__96_CdGetStatus; + //biosA0[0x7d] = bios_sys_a0_7d; + //biosA0[0x7e] = bios__96_CdRead; + //biosA0[0x7f] = bios_sys_a0_7f; + //biosA0[0x80] = bios_sys_a0_80; + //biosA0[0x81] = bios_sys_a0_81; + //biosA0[0x82] = bios_sys_a0_82; + //biosA0[0x83] = bios_sys_a0_83; + //biosA0[0x84] = bios_sys_a0_84; + //biosA0[0x85] = bios__96_CdStop; + //biosA0[0x86] = bios_sys_a0_86; + //biosA0[0x87] = bios_sys_a0_87; + //biosA0[0x88] = bios_sys_a0_88; + //biosA0[0x89] = bios_sys_a0_89; + //biosA0[0x8a] = bios_sys_a0_8a; + //biosA0[0x8b] = bios_sys_a0_8b; + //biosA0[0x8c] = bios_sys_a0_8c; + //biosA0[0x8d] = bios_sys_a0_8d; + //biosA0[0x8e] = bios_sys_a0_8e; + //biosA0[0x8f] = bios_sys_a0_8f; + //biosA0[0x90] = bios_sys_a0_90; + //biosA0[0x91] = bios_sys_a0_91; + //biosA0[0x92] = bios_sys_a0_92; + //biosA0[0x93] = bios_sys_a0_93; + //biosA0[0x94] = bios_sys_a0_94; + //biosA0[0x95] = bios_sys_a0_95; + //biosA0[0x96] = bios_AddCDROMDevice; + //biosA0[0x97] = bios_AddMemCardDevide; + //biosA0[0x98] = bios_DisableKernelIORedirection; + //biosA0[0x99] = bios_EnableKernelIORedirection; + //biosA0[0x9a] = bios_sys_a0_9a; + //biosA0[0x9b] = bios_sys_a0_9b; + //biosA0[0x9c] = bios_SetConf; + //biosA0[0x9d] = bios_GetConf; + //biosA0[0x9e] = bios_sys_a0_9e; + //biosA0[0x9f] = bios_SetMem; + //biosA0[0xa0] = bios__boot; + //biosA0[0xa1] = bios_SystemError; + //biosA0[0xa2] = bios_EnqueueCdIntr; + //biosA0[0xa3] = bios_DequeueCdIntr; + //biosA0[0xa4] = bios_sys_a0_a4; + //biosA0[0xa5] = bios_ReadSector; + //biosA0[0xa6] = bios_get_cd_status; + //biosA0[0xa7] = bios_bufs_cb_0; + //biosA0[0xa8] = bios_bufs_cb_1; + //biosA0[0xa9] = bios_bufs_cb_2; + //biosA0[0xaa] = bios_bufs_cb_3; + biosA0[0xab] = bios__card_info; + biosA0[0xac] = bios__card_load; + //biosA0[0axd] = bios__card_auto; + //biosA0[0xae] = bios_bufs_cd_4; + //biosA0[0xaf] = bios_sys_a0_af; + //biosA0[0xb0] = bios_sys_a0_b0; + //biosA0[0xb1] = bios_sys_a0_b1; + //biosA0[0xb2] = bios_do_a_long_jmp + //biosA0[0xb3] = bios_sys_a0_b3; + //biosA0[0xb4] = bios_sub_function; +//*******************B0 CALLS**************************** + //biosB0[0x00] = bios_SysMalloc; + //biosB0[0x01] = bios_sys_b0_01; + biosB0[0x02] = bios_SetRCnt; + biosB0[0x03] = bios_GetRCnt; + biosB0[0x04] = bios_StartRCnt; + biosB0[0x05] = bios_StopRCnt; + biosB0[0x06] = bios_ResetRCnt; + biosB0[0x07] = bios_DeliverEvent; + biosB0[0x08] = bios_OpenEvent; + biosB0[0x09] = bios_CloseEvent; + biosB0[0x0a] = bios_WaitEvent; + biosB0[0x0b] = bios_TestEvent; + biosB0[0x0c] = bios_EnableEvent; + biosB0[0x0d] = bios_DisableEvent; + biosB0[0x0e] = bios_OpenTh; + biosB0[0x0f] = bios_CloseTh; + biosB0[0x10] = bios_ChangeTh; + //biosB0[0x11] = bios_bios_b0_11; + biosB0[0x12] = bios_InitPAD; + biosB0[0x13] = bios_StartPAD; + biosB0[0x14] = bios_StopPAD; + biosB0[0x15] = bios_PAD_init; + biosB0[0x16] = bios_PAD_dr; + biosB0[0x17] = bios_ReturnFromException; + biosB0[0x18] = bios_ResetEntryInt; + biosB0[0x19] = bios_HookEntryInt; + //biosB0[0x1a] = bios_sys_b0_1a; + //biosB0[0x1b] = bios_sys_b0_1b; + //biosB0[0x1c] = bios_sys_b0_1c; + //biosB0[0x1d] = bios_sys_b0_1d; + //biosB0[0x1e] = bios_sys_b0_1e; + //biosB0[0x1f] = bios_sys_b0_1f; + biosB0[0x20] = bios_UnDeliverEvent; + //biosB0[0x21] = bios_sys_b0_21; + //biosB0[0x22] = bios_sys_b0_22; + //biosB0[0x23] = bios_sys_b0_23; + //biosB0[0x24] = bios_sys_b0_24; + //biosB0[0x25] = bios_sys_b0_25; + //biosB0[0x26] = bios_sys_b0_26; + //biosB0[0x27] = bios_sys_b0_27; + //biosB0[0x28] = bios_sys_b0_28; + //biosB0[0x29] = bios_sys_b0_29; + //biosB0[0x2a] = bios_sys_b0_2a; + //biosB0[0x2b] = bios_sys_b0_2b; + //biosB0[0x2c] = bios_sys_b0_2c; + //biosB0[0x2d] = bios_sys_b0_2d; + //biosB0[0x2e] = bios_sys_b0_2e; + //biosB0[0x2f] = bios_sys_b0_2f; + //biosB0[0x30] = bios_sys_b0_30; + //biosB0[0x31] = bios_sys_b0_31; + biosB0[0x32] = bios_open; + biosB0[0x33] = bios_lseek; + biosB0[0x34] = bios_read; + biosB0[0x35] = bios_write; + biosB0[0x36] = bios_close; + //biosB0[0x37] = bios_ioctl; + //biosB0[0x38] = bios_exit; + //biosB0[0x39] = bios_sys_b0_39; + //biosB0[0x3a] = bios_getc; + //biosB0[0x3b] = bios_putc; + biosB0[0x3c] = bios_getchar; + //biosB0[0x3e] = bios_gets; + //biosB0[0x40] = bios_cd; + //biosB0[0x41] = bios_format; + biosB0[0x42] = bios_firstfile; + biosB0[0x43] = bios_nextfile; + //biosB0[0x44] = bios_rename; + biosB0[0x45] = bios_delete; + //biosB0[0x46] = bios_undelete; + //biosB0[0x47] = bios_AddDevice; + //biosB0[0x48] = bios_RemoteDevice; + //biosB0[0x49] = bios_PrintInstalledDevices; + biosB0[0x4a] = bios_InitCARD; + biosB0[0x4b] = bios_StartCARD; + biosB0[0x4c] = bios_StopCARD; + //biosB0[0x4d] = bios_sys_b0_4d; + biosB0[0x4e] = bios__card_write; + biosB0[0x4f] = bios__card_read; + biosB0[0x50] = bios__new_card; + //biosB0[0x51] = bios_Krom2RawAdd; + //biosB0[0x52] = bios_sys_b0_52; + //biosB0[0x53] = bios_sys_b0_53; + //biosB0[0x54] = bios__get_errno; + //biosB0[0x55] = bios__get_error; + biosB0[0x56] = bios_GetC0Table; + biosB0[0x57] = bios_GetB0Table; + //biosB0[0x58] = bios__card_chan; + //biosB0[0x59] = bios_sys_b0_59; + //biosB0[0x5a] = bios_sys_b0_5a; + biosB0[0x5b] = bios_ChangeClearPad; + //biosB0[0x5c] = bios__card_status; + //biosB0[0x5d] = bios__card_wait; +//*******************C0 CALLS**************************** + //biosC0[0x00] = bios_InitRCnt; + //biosC0[0x01] = bios_InitException; + biosC0[0x02] = bios_SysEnqIntRP; + biosC0[0x03] = bios_SysDeqIntRP; + //biosC0[0x04] = bios_get_free_EvCB_slot; + //biosC0[0x05] = bios_get_free_TCB_slot; + //biosC0[0x06] = bios_ExceptionHandler; + //biosC0[0x07] = bios_InstallExeptionHandler; + //biosC0[0x08] = bios_SysInitMemory; + //biosC0[0x09] = bios_SysInitKMem; + biosC0[0x0a] = bios_ChangeClearRCnt; + //biosC0[0x0b] = bios_SystemError; + //biosC0[0x0c] = bios_InitDefInt; + //biosC0[0x0d] = bios_sys_c0_0d; + //biosC0[0x0e] = bios_sys_c0_0e; + //biosC0[0x0f] = bios_sys_c0_0f; + //biosC0[0x10] = bios_sys_c0_10; + //biosC0[0x11] = bios_sys_c0_11; + //biosC0[0x12] = bios_InstallDevices; + //biosC0[0x13] = bios_FlushStfInOutPut; + //biosC0[0x14] = bios_sys_c0_14; + //biosC0[0x15] = bios__cdevinput; + //biosC0[0x16] = bios__cdevscan; + //biosC0[0x17] = bios__circgetc; + //biosC0[0x18] = bios__circputc; + //biosC0[0x19] = bios_ioabort; + //biosC0[0x1a] = bios_sys_c0_1a + //biosC0[0x1b] = bios_KernelRedirect; + //biosC0[0x1c] = bios_PatchAOTable; +//************** THE END *************************************** + + base = 0x1000; + size = sizeof(EvCB) * 32; + Event = (void *)&psxR[base]; base+= size*6; + memset(Event, 0, size * 6); + HwEV = Event; + EvEV = Event + 32; + RcEV = Event + 32*2; + UeEV = Event + 32*3; + SwEV = Event + 32*4; + ThEV = Event + 32*5; + + ptr = (u32*)&psxM[0x0874]; // b0 table + ptr[0] = 0x4c54 - 0x884; + + ptr = (u32*)&psxM[0x0674]; // c0 table + ptr[6] = 0xc80; + + memset(SysIntRP, 0, sizeof(SysIntRP)); + memset(Thread, 0, sizeof(Thread)); + Thread[0].status = 2; // main thread + + psxMu32(0x0150) = 0x160; + psxMu32(0x0154) = 0x320; + psxMu32(0x0160) = 0x248; + strcpy(&psxM[0x248], "bu"); + + // opcode HLE + psxRu32(0x0000) = (0x3b << 26) | 4; + psxMu32(0x0000) = (0x3b << 26) | 0; + psxMu32(0x00a0) = (0x3b << 26) | 1; + psxMu32(0x00b0) = (0x3b << 26) | 2; + psxMu32(0x00c0) = (0x3b << 26) | 3; + psxMu32(0x4c54) = (0x3b << 26) | 0; + psxMu32(0x8000) = (0x3b << 26) | 5; + psxMu32(0x07a0) = (0x3b << 26) | 0; + psxMu32(0x0884) = (0x3b << 26) | 0; + psxMu32(0x0894) = (0x3b << 26) | 0; +} + +void psxBiosShutdown() { +} + +__inline void SaveRegs() { + memcpy(regs, psxRegs.GPR.r, 32*4); + regs[32] = psxRegs.GPR.n.lo; + regs[33] = psxRegs.GPR.n.hi; + regs[34] = psxRegs.pc; +} + +__inline void LoadRegs() { + memcpy(psxRegs.GPR.r, regs, 32*4); + psxRegs.GPR.n.lo = regs[32]; + psxRegs.GPR.n.hi = regs[33]; +} + +#define bios_PADpoll(pad) { \ + PAD##pad##_startPoll(pad); \ + pad_buf##pad[0] = 0; \ + pad_buf##pad[1] = PAD##pad##_poll(0x42); \ + if (!(pad_buf##pad[1] & 0x0f)) { \ + bufcount = 32; \ + } else { \ + bufcount = (pad_buf##pad[1] & 0x0f) * 2; \ + } \ + PAD##pad##_poll(0); \ + i = 2; \ + while (bufcount--) { \ + pad_buf##pad[i++] = PAD##pad##_poll(0); \ + } \ +} + +void biosInterrupt() { + int i, bufcount; + + if ((psxRegs.CP0.n.Status & 0x404) != 0x404) return; + +// if (psxHu32(0x1070) & 0x1) { // Vsync + if (pad_buf) { + PAD1_startPoll(1); + PAD1_poll(0x42); + PAD1_poll(0); + *pad_buf = PAD1_poll(0) << 8; + *pad_buf|= PAD1_poll(0); + PAD2_startPoll(2); + PAD2_poll(0x42); + PAD2_poll(0); + *pad_buf|= PAD2_poll(0) << 24; + *pad_buf|= PAD2_poll(0) << 16; + } + if (pad_buf1) { + bios_PADpoll(1); + } + + if (pad_buf2) { + bios_PADpoll(2); + } + + if (psxHu32(0x1070) & 0x1) { // Vsync + if (RcEV[3][1].status == EvStACTIVE) { + softCall(RcEV[3][1].fhandler); +// hwWrite32(0x1f801070, ~(1)); + } + } + + if (psxHu32(0x1070) & 0x70) { // Rcnt 0,1,2 + int i; + + for (i=0; i<3; i++) { + if (psxHu32(0x1070) & (1 << (i+4)) && psxCounters[i].mode & 0x50) { + if (RcEV[i][1].status == EvStACTIVE) { + softCall(RcEV[i][1].fhandler); + } + psxHwWrite32(0x1f801070, ~(1 << (i+4))); + } + } + } +} + +void psxBiosException() { + int i; + + switch ((psxRegs.CP0.n.Cause & 0x3c) >> 2) { + case 0: // Interrupt +#ifdef PSXCPU_LOG +// PSXCPU_LOG("interrupt\n"); +#endif + SaveRegs(); + + biosInterrupt(); + + for (i=0; i<8; i++) { + if (SysIntRP[i]) { + u32 *queue = (u32*)PSXM(SysIntRP[i]); + + s0 = queue[2]; + softCall(queue[1]); + } + } + + if (jmp_int != NULL) { + int i; + + psxHwWrite32(0x1f801070, 0xffffffff); + + ra = jmp_int[0]; + sp = jmp_int[1]; + fp = jmp_int[2]; + for (i=0; i<8; i++) // s0-s7 + psxRegs.GPR.r[16+i] = jmp_int[3+i]; + gp = jmp_int[11]; + + v0 = 1; + pc0 = ra; + return; + } + psxHwWrite16(0x1f801070, 0); + break; + case 8: // Syscall +#ifdef PSXCPU_LOG +// PSXCPU_LOG("syscall exp %x\n", a0); +#endif + switch (a0) { + case 1: // EnterCritical - disable irq's + psxRegs.CP0.n.Status&=~0x404; break; + case 2: // ExitCritical - enable irq's + psxRegs.CP0.n.Status|= 0x404; break; + } + pc0 = psxRegs.CP0.n.EPC + 4; + + psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status & 0xfffffff0) | + ((psxRegs.CP0.n.Status & 0x3c) >> 2); + return; + default: +#ifdef PSXCPU_LOG + PSXCPU_LOG("unk exp\n"); +#endif + break; + } + + pc0 = psxRegs.CP0.n.EPC; + if (psxRegs.CP0.n.Cause & 0x80000000) pc0+=4; + + psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status & 0xfffffff0) | + ((psxRegs.CP0.n.Status & 0x3c) >> 2); +} + +#define bfreeze(ptr, size) \ + if (Mode == 1) memcpy(&psxR[base], ptr, size); \ + if (Mode == 0) memcpy(ptr, &psxR[base], size); \ + base+=size; + +#define bfreezes(ptr) bfreeze(ptr, sizeof(ptr)) +#define bfreezel(ptr) bfreeze(ptr, 4) + +#define bfreezepsxMptr(ptr) \ + if (Mode == 1) { \ + if (ptr) psxRu32(base) = (u32)ptr - (u32)psxM; \ + else psxRu32(base) = 0; \ + } else { \ + if (psxRu32(base)) (u8*)ptr = (u8*)(psxM + psxRu32(base)); \ + else ptr = NULL; \ + } \ + base+=4; + +void psxBiosFreeze(int Mode) { + u32 base = 0x40000; + + bfreezepsxMptr(jmp_int); + bfreezepsxMptr(pad_buf); + bfreezepsxMptr(pad_buf1); + bfreezepsxMptr(pad_buf2); + bfreezepsxMptr(heap_addr); + bfreezel(&pad_buf1len); + bfreezel(&pad_buf2len); + bfreezes(regs); + bfreezes(SysIntRP); + bfreezel(&CardState); + bfreezes(Thread); + bfreezel(&CurThread); + bfreezes(FDesc); +} \ No newline at end of file diff --git a/PcsxSrc/PsxBios.h b/PcsxSrc/PsxBios.h new file mode 100644 index 0000000..47db9bc --- /dev/null +++ b/PcsxSrc/PsxBios.h @@ -0,0 +1,35 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __PSXBIOS_H__ +#define __PSXBIOS_H__ + +extern char *biosA0n[256]; +extern char *biosB0n[256]; +extern char *biosC0n[256]; + +void psxBiosInit(); +void psxBiosShutdown(); +void psxBiosException(); +void psxBiosFreeze(int Mode); + +extern void (*biosA0[256])(); +extern void (*biosB0[256])(); +extern void (*biosC0[256])(); + +#endif /* __PSXBIOS_H__ */ diff --git a/PcsxSrc/PsxCommon.h b/PcsxSrc/PsxCommon.h new file mode 100644 index 0000000..f45a510 --- /dev/null +++ b/PcsxSrc/PsxCommon.h @@ -0,0 +1,131 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __PSXCOMMON_H__ +#define __PSXCOMMON_H__ + +#include "System.h" +#include + +#if defined(__WIN32__) + +#include + +typedef struct { + HWND hWnd; // Main window handle + HINSTANCE hInstance; // Application instance + HMENU hMenu; // Main window menu +} AppData; + +#elif defined (__LINUX__) + +#include + +#define __inline inline + +#endif + +// Basic types +#if defined(__WIN32__) + +typedef __int8 s8; +typedef __int16 s16; +typedef __int32 s32; +typedef __int64 s64; + +typedef unsigned __int8 u8; +typedef unsigned __int16 u16; +typedef unsigned __int32 u32; +typedef unsigned __int64 u64; + +#elif defined(__LINUX__) + +typedef char s8; +typedef short s16; +typedef long s32; +typedef long long s64; + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned long u32; +typedef unsigned long long u64; + +#endif + +extern int Log; +void __Log(char *fmt, ...); + +typedef struct { + char Gpu[256]; + char Spu[256]; + char Cdr[256]; + char Pad1[256]; + char Pad2[256]; + char Mcd1[256]; + char Mcd2[256]; + char Bios[256]; + char BiosDir[256]; + char PluginsDir[256]; + long Xa; + long Sio; + long Mdec; + long PsxAuto; + long PsxType; // ntsc - 0 | pal - 1 + long QKeys; + long Cdda; + long HLE; + long Cpu; + long PsxOut; + long SpuIrq; + long CdTiming; +} PcsxConfig; + +PcsxConfig Config; + +extern long LoadCdBios; +extern int StatesC; +extern char CdromId[256]; +extern int cdOpenCase; + +#define gzfreeze(ptr, size) \ + if (Mode == 1) gzwrite(f, ptr, size); \ + if (Mode == 0) gzread(f, ptr, size); + +#define gzfreezel(ptr) gzfreeze(ptr, sizeof(ptr)) + +#define BIAS 4 +#define PSXCLK 33868800 /* 33.8688 Mhz */ + +#include "R3000A.h" +#include "PsxMem.h" +#include "PsxHw.h" +#include "PsxBios.h" +#include "PsxDma.h" +#include "PsxCounters.h" +#include "PsxHLE.h" +#include "Mdec.h" +#include "CdRom.h" +#include "Sio.h" +#include "Spu.h" +#include "plugins.h" +#include "Decode_XA.h" +#include "Misc.h" +#include "Debug.h" +#include "Gte.h" + +#endif /* __PSXCOMMON_H__ */ diff --git a/PcsxSrc/PsxCounters.c b/PcsxSrc/PsxCounters.c new file mode 100644 index 0000000..a9bdabf --- /dev/null +++ b/PcsxSrc/PsxCounters.c @@ -0,0 +1,202 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#include "PsxCommon.h" + +static int cnts = 4; + +static void psxRcntUpd(unsigned long index) { + psxCounters[index].sCycle = psxRegs.cycle; + if ((!(psxCounters[index].mode & 1)) || (index!=2)) { + if (psxCounters[index].mode & 0x08) { // Count to target + psxCounters[index].Cycle = ((psxCounters[index].target - psxCounters[index].count) * psxCounters[index].rate) / BIAS; + } + else { // Count to 0xffff + psxCounters[index].Cycle = ((0xffff - psxCounters[index].count) * psxCounters[index].rate) / BIAS; + } + } else psxCounters[index].Cycle = 0xffffffff; +} + +static void psxRcntReset(unsigned long index) { + psxCounters[index].count = 0; + psxRcntUpd(index); + + if ((psxCounters[index].mode & 0x50) == 0x50) psxHu32(0x1070)|= psxCounters[index].interrupt; +} + +static void psxRcntSet() { + int i; + + psxNextCounter = 0x7fffffff; + psxNextsCounter = psxRegs.cycle; + + for (i=0; i= psxCounters[3].Cycle) { + psxRcntReset(3); + GPU_updateLace(); // updateGPU + SysUpdate(); +#ifdef GTE_LOG + GTE_LOG("VSync\n"); +#endif + } + + if ((psxRegs.cycle - psxCounters[0].sCycle) >= psxCounters[0].Cycle) { + psxRcntReset(0); + } + + if ((psxRegs.cycle - psxCounters[1].sCycle) >= psxCounters[1].Cycle) { + psxRcntReset(1); + } + + if ((psxRegs.cycle - psxCounters[2].sCycle) >= psxCounters[2].Cycle) { + psxRcntReset(2); + } + + if (cnts >= 5) { + if ((psxRegs.cycle - psxCounters[4].sCycle) >= psxCounters[4].Cycle) { + if (SPU_update != NULL) + SPU_update(); + if (SPU_async != NULL) + SPU_async((psxRegs.cycle - psxCounters[4].sCycle) * BIAS); + psxRcntReset(4); + } + } + + psxRcntSet(); +} + +void psxRcntWcount(unsigned long index, unsigned long value) { +// SysPrintf("writeCcount[%d] = %x\n", index, value); +// PSXCPU_LOG("writeCcount[%d] = %x\n", index, value); + psxCounters[index].count = value; + psxRcntUpd(index); + psxRcntSet(); +} + +void psxRcntWmode(unsigned long index, unsigned long value) { +// SysPrintf("writeCmode[%ld] = %lx\n", index, value); + psxCounters[index].mode = value; + if(index == 0) { + switch (value & 0x300) { + case 0x100: + psxCounters[index].rate = ((psxCounters[3].rate /** BIAS*/) / 386) / 262; // seems ok + break; + default: + psxCounters[index].rate = 1; + } + } + else if(index == 1) { + switch (value & 0x300) { + case 0x100: + psxCounters[index].rate = (psxCounters[3].rate /** BIAS*/) / 262; // seems ok + break; + default: + psxCounters[index].rate = 1; + } + } + else if(index == 2) { + switch (value & 0x300) { + case 0x200: + psxCounters[index].rate = 8; // 1/8 speed + break; + default: + psxCounters[index].rate = 1; // normal speed + } + } + + // Need to set a rate and target + psxRcntUpd(index); + psxRcntSet(); +} + +void psxRcntWtarget(unsigned long index, unsigned long value) { +// SysPrintf("writeCtarget[%ld] = %lx\n", index, value); + psxCounters[index].target = value; + psxRcntUpd(index); + psxRcntSet(); +} + +unsigned long psxRcntRcount(unsigned long index) { +// if ((!(psxCounters[index].mode & 1)) || (index!=2)) { + return (psxCounters[index].count + BIAS * (psxRegs.cycle - psxCounters[index].sCycle) / psxCounters[index].rate) & 0xffff; +// } else return 0; +} + +int psxRcntFreeze(gzFile f, int Mode) { + char Unused[4096 - sizeof(psxCounter)]; + + gzfreezel(psxCounters); + gzfreezel(Unused); + + return 0; +} diff --git a/PcsxSrc/PsxCounters.h b/PcsxSrc/PsxCounters.h new file mode 100644 index 0000000..23d1235 --- /dev/null +++ b/PcsxSrc/PsxCounters.h @@ -0,0 +1,41 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __PSXCOUNTERS_H__ +#define __PSXCOUNTERS_H__ + +typedef struct { + unsigned long count, mode, target; + unsigned long sCycle, Cycle, rate, interrupt; +} psxCounter; + +psxCounter psxCounters[5]; + +unsigned long psxNextCounter, psxNextsCounter; + +void psxRcntInit(); +void psxRcntUpdate(); +void psxRcntWcount(unsigned long index, unsigned long value); +void psxRcntWmode(unsigned long index, unsigned long value); +void psxRcntWtarget(unsigned long index, unsigned long value); +unsigned long psxRcntRcount(unsigned long index); +int psxRcntFreeze(gzFile f, int Mode); + +void UpdateVSyncRate(); + +#endif /* __PSXCOUNTERS_H__ */ diff --git a/PcsxSrc/PsxDma.c b/PcsxSrc/PsxDma.c new file mode 100644 index 0000000..c765884 --- /dev/null +++ b/PcsxSrc/PsxDma.c @@ -0,0 +1,96 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "PsxCommon.h" + +// Dma0/1 in Mdec.c +// Dma3 in CdRom.c + +void psxDma4(u32 madr, u32 bcr, u32 chcr) { // SPU + switch (chcr) { + case 0x01000201: //cpu to spu transfer +#ifdef PSXDMA_LOG + PSXDMA_LOG("*** DMA 4 - SPU mem2spu *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); +#endif + SPU_writeDMAMem((u16 *)PSXM(madr), (bcr >> 16) * (bcr & 0xffff) * 2); + break; + case 0x01000200: //spu to cpu transfer +#ifdef PSXDMA_LOG + PSXDMA_LOG("*** DMA 4 - SPU spu2mem *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); +#endif + SPU_readDMAMem ((u16 *)PSXM(madr), (bcr >> 16) * (bcr & 0xffff) * 2); + break; +#ifdef PSXDMA_LOG + default: + PSXDMA_LOG("*** DMA 4 - SPU unknown *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); + break; +#endif + } +} + +void psxDma2(u32 madr, u32 bcr, u32 chcr) { // GPU + switch(chcr) { + case 0x01000200: // vram2mem +#ifdef PSXDMA_LOG + PSXDMA_LOG("*** DMA 2 - GPU vram2mem *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); +#endif + GPU_readDataMem((u32 *)PSXM(madr), (bcr >> 16) * (bcr & 0xffff)); + psxCpu->Clear(madr, ((bcr >> 16) * (bcr & 0xffff)) / 4); + break; + + case 0x01000201: // mem2vram +#ifdef PSXDMA_LOG + PSXDMA_LOG("*** DMA 2 - GPU mem2vram *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); +#endif + GPU_writeDataMem((u32 *)PSXM(madr), (bcr >> 16) * (bcr & 0xffff)); + break; + + case 0x01000401: // dma chain +#ifdef PSXDMA_LOG + PSXDMA_LOG("*** DMA 2 - GPU dma chain *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); +#endif + GPU_dmaChain((u32 *)psxM, madr & 0x1fffff); + break; +#ifdef PSXDMA_LOG + default: + PSXDMA_LOG("*** DMA 2 - GPU unknown *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); + break; +#endif + } +} + +void psxDma6(u32 madr, u32 bcr, u32 chcr) { + u32 *mem = (u32 *)PSXM(madr); + +#ifdef PSXDMA_LOG + PSXDMA_LOG("*** DMA 6 - OT *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); +#endif + + if (chcr == 0x11000002) { + while (bcr--) { + *mem-- = (madr - 4) & 0xffffff; + madr -= 4; + } + mem++; *mem = 0xffffff; + } else { + // Unknown option +#ifdef PSXDMA_LOG + PSXDMA_LOG("*** DMA 6 - OT unknown *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); +#endif + } +} diff --git a/PcsxSrc/PsxDma.h b/PcsxSrc/PsxDma.h new file mode 100644 index 0000000..0107f53 --- /dev/null +++ b/PcsxSrc/PsxDma.h @@ -0,0 +1,27 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __PSXDMA_H__ +#define __PSXDMA_H__ + +void psxDma2(u32 madr, u32 bcr, u32 chcr); +void psxDma3(u32 madr, u32 bcr, u32 chcr); +void psxDma4(u32 madr, u32 bcr, u32 chcr); +void psxDma6(u32 madr, u32 bcr, u32 chcr); + +#endif /* __PSXDMA_H__ */ diff --git a/PcsxSrc/PsxHLE.c b/PcsxSrc/PsxHLE.c new file mode 100644 index 0000000..17fb6bb --- /dev/null +++ b/PcsxSrc/PsxHLE.c @@ -0,0 +1,91 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "PsxCommon.h" + +static void hleDummy() { + psxRegs.pc = psxRegs.GPR.n.ra; + + psxBranchTest(); +} + +static void hleA0() { + u32 call = psxRegs.GPR.n.t1 & 0xff; + + if (biosA0[call]) biosA0[call](); + + psxBranchTest(); +} + +static void hleB0() { + u32 call = psxRegs.GPR.n.t1 & 0xff; + + if (biosB0[call]) biosB0[call](); + + psxBranchTest(); +} + +static void hleC0() { + u32 call = psxRegs.GPR.n.t1 & 0xff; + + if (biosC0[call]) biosC0[call](); + + psxBranchTest(); +} + +static void hleBootstrap() { // 0xbfc00000 + SysPrintf("hleBootstrap\n"); + CheckCdrom(); + LoadCdrom(); + SysPrintf("CdromId: \"%s\": PC = %8.8lx (SP = %8.8lx)\n", CdromId, psxRegs.pc, psxRegs.GPR.n.sp); +} + +typedef struct { + unsigned long _pc0; + unsigned long gp0; + unsigned long t_addr; + unsigned long t_size; + unsigned long d_addr; + unsigned long d_size; + unsigned long b_addr; + unsigned long b_size; + unsigned long S_addr; + unsigned long s_size; + unsigned long _sp,_fp,_gp,ret,base; +} EXEC; + +static void hleExecRet() { + EXEC *header = (EXEC*)PSXM(psxRegs.GPR.n.s0); + + SysPrintf("ExecRet %x: %x\n", psxRegs.GPR.n.s0, header->ret); + + psxRegs.GPR.n.ra = header->ret; + psxRegs.GPR.n.sp = header->_sp; + psxRegs.GPR.n.s8 = header->_fp; + psxRegs.GPR.n.gp = header->_gp; + psxRegs.GPR.n.s0 = header->base; + + psxRegs.GPR.n.v0 = 1; + psxRegs.pc = psxRegs.GPR.n.ra; +} + +void (*psxHLEt[256])() = { + hleDummy, hleA0, hleB0, hleC0, + hleBootstrap, hleExecRet +}; diff --git a/PcsxSrc/PsxHLE.h b/PcsxSrc/PsxHLE.h new file mode 100644 index 0000000..2cd7443 --- /dev/null +++ b/PcsxSrc/PsxHLE.h @@ -0,0 +1,24 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __PSXHLE_H__ +#define __PSXHLE_H__ + +extern void (*psxHLEt[256])(); + +#endif /* __PSXHLE_H__ */ diff --git a/PcsxSrc/PsxHw.c b/PcsxSrc/PsxHw.c new file mode 100644 index 0000000..dbfc6da --- /dev/null +++ b/PcsxSrc/PsxHw.c @@ -0,0 +1,756 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include "PsxCommon.h" + +#ifdef __WIN32__ +#pragma warning(disable:4244) +#endif + +#define HW_DMA0_MADR (psxHu32(0x1080)) // MDEC in DMA +#define HW_DMA0_BCR (psxHu32(0x1084)) +#define HW_DMA0_CHCR (psxHu32(0x1088)) + +#define HW_DMA1_MADR (psxHu32(0x1090)) // MDEC out DMA +#define HW_DMA1_BCR (psxHu32(0x1094)) +#define HW_DMA1_CHCR (psxHu32(0x1098)) + +#define HW_DMA2_MADR (psxHu32(0x10a0)) // GPU DMA +#define HW_DMA2_BCR (psxHu32(0x10a4)) +#define HW_DMA2_CHCR (psxHu32(0x10a8)) + +#define HW_DMA3_MADR (psxHu32(0x10b0)) // CDROM DMA +#define HW_DMA3_BCR (psxHu32(0x10b4)) +#define HW_DMA3_CHCR (psxHu32(0x10b8)) + +#define HW_DMA4_MADR (psxHu32(0x10c0)) // SPU DMA +#define HW_DMA4_BCR (psxHu32(0x10c4)) +#define HW_DMA4_CHCR (psxHu32(0x10c8)) + +#define HW_DMA6_MADR (psxHu32(0x10e0)) // GPU DMA (OT) +#define HW_DMA6_BCR (psxHu32(0x10e4)) +#define HW_DMA6_CHCR (psxHu32(0x10e8)) + +#define HW_DMA_PCR (psxHu32(0x10f0)) +#define HW_DMA_ICR (psxHu32(0x10f4)) + +void psxHwReset() { + if (Config.Sio) psxHu32(0x1070) |= 0x80; + if (Config.SpuIrq) psxHu32(0x1070) |= 0x200; + + memset(psxH, 0, 0x10000); + + mdecInit(); //intialize mdec decoder + cdrReset(); + psxRcntInit(); +} + +u8 psxHwRead8(u32 add) { + unsigned char hard; + + switch (add) { + case 0x1f801040: hard = sioRead8();break; + // case 0x1f801050: hard = serial_read8(); break;//for use of serial port ignore for now + case 0x1f801800: hard = cdrRead0(); break; + case 0x1f801801: hard = cdrRead1(); break; + case 0x1f801802: hard = cdrRead2(); break; + case 0x1f801803: hard = cdrRead3(); break; + default: + hard = psxHu8(add); +#ifdef PSXHW_LOG + PSXHW_LOG("*Unkwnown 8bit read at address %lx\n", add); +#endif + return hard; + } + +#ifdef PSXHW_LOG + PSXHW_LOG("*Known 8bit read at address %lx value %x\n", add, hard); +#endif + return hard; +} + +u16 psxHwRead16(u32 add) { + unsigned short hard; + + switch (add) { +#ifdef PSXHW_LOG + case 0x1f801070: PSXHW_LOG("IREG 16bit read %x\n", psxHu16(0x1070)); + return psxHu16(0x1070); +#endif +#ifdef PSXHW_LOG + case 0x1f801074: PSXHW_LOG("IMASK 16bit read %x\n", psxHu16(0x1074)); + return psxHu16(0x1074); +#endif + + case 0x1f801040: + hard = sioRead8(); + hard|= sioRead8() << 8; +#ifdef PAD_LOG + PAD_LOG("sio read16 %lx; ret = %x\n", add&0xf, hard); +#endif + return hard; + case 0x1f801044: + hard = StatReg; +#ifdef PAD_LOG + PAD_LOG("sio read16 %lx; ret = %x\n", add&0xf, hard); +#endif + return hard; + case 0x1f801048: + hard = ModeReg; +#ifdef PAD_LOG + PAD_LOG("sio read16 %lx; ret = %x\n", add&0xf, hard); +#endif + return hard; + case 0x1f80104a: + hard = CtrlReg; +#ifdef PAD_LOG + PAD_LOG("sio read16 %lx; ret = %x\n", add&0xf, hard); +#endif + return hard; + case 0x1f80104e: + hard = BaudReg; +#ifdef PAD_LOG + PAD_LOG("sio read16 %lx; ret = %x\n", add&0xf, hard); +#endif + return hard; + + //Serial port stuff not support now ;P + // case 0x1f801050: hard = serial_read16(); break; + // case 0x1f801054: hard = serial_status_read(); break; + // case 0x1f80105a: hard = serial_control_read(); break; + // case 0x1f80105e: hard = serial_baud_read(); break; + + case 0x1f801100: + hard = psxRcntRcount(0); +#ifdef PSXHW_LOG + PSXHW_LOG("T0 count read16: %x\n", hard); +#endif + return hard; + case 0x1f801104: + hard = psxCounters[0].mode; +#ifdef PSXHW_LOG + PSXHW_LOG("T0 mode read16: %x\n", hard); +#endif + return hard; + case 0x1f801108: + hard = psxCounters[0].target; +#ifdef PSXHW_LOG + PSXHW_LOG("T0 target read16: %x\n", hard); +#endif + return hard; + case 0x1f801110: + hard = psxRcntRcount(1); +#ifdef PSXHW_LOG + PSXHW_LOG("T1 count read16: %x\n", hard); +#endif + return hard; + case 0x1f801114: + hard = psxCounters[1].mode; +#ifdef PSXHW_LOG + PSXHW_LOG("T1 mode read16: %x\n", hard); +#endif + return hard; + case 0x1f801118: + hard = psxCounters[1].target; +#ifdef PSXHW_LOG + PSXHW_LOG("T1 target read16: %x\n", hard); +#endif + return hard; + case 0x1f801120: + hard = psxRcntRcount(2); +#ifdef PSXHW_LOG + PSXHW_LOG("T2 count read16: %x\n", hard); +#endif + return hard; + case 0x1f801124: + hard = psxCounters[2].mode; +#ifdef PSXHW_LOG + PSXHW_LOG("T2 mode read16: %x\n", hard); +#endif + return hard; + case 0x1f801128: + hard = psxCounters[2].target; +#ifdef PSXHW_LOG + PSXHW_LOG("T2 target read16: %x\n", hard); +#endif + return hard; + + //case 0x1f802030: hard = //int_2000???? + //case 0x1f802040: hard =//dip switches...?? + + default: + if (add>=0x1f801c00 && add<0x1f801e00) { + hard = SPU_readRegister(add); + } else { + hard = psxHu16(add); +#ifdef PSXHW_LOG + PSXHW_LOG("*Unkwnown 16bit read at address %lx\n", add); +#endif + } + return hard; + } + +#ifdef PSXHW_LOG + PSXHW_LOG("*Known 16bit read at address %lx value %x\n", add, hard); +#endif + return hard; +} + +u32 psxHwRead32(u32 add) { + u32 hard; + + switch (add) { + case 0x1f801040: + hard = sioRead8(); + hard|= sioRead8() << 8; + hard|= sioRead8() << 16; + hard|= sioRead8() << 24; +#ifdef PAD_LOG + PAD_LOG("sio read32 ;ret = %lx\n", hard); +#endif + return hard; + + // case 0x1f801050: hard = serial_read32(); break;//serial port +#ifdef PSXHW_LOG + case 0x1f801060: + PSXHW_LOG("RAM size read %lx\n", psxHu32(0x1060)); + return psxHu32(0x1060); +#endif +#ifdef PSXHW_LOG + case 0x1f801070: PSXHW_LOG("IREG 32bit read %x\n", psxHu32(0x1070)); + return psxHu32(0x1070); +#endif +#ifdef PSXHW_LOG + case 0x1f801074: PSXHW_LOG("IMASK 32bit read %x\n", psxHu32(0x1074)); + return psxHu32(0x1074); +#endif + + case 0x1f801810: + hard = GPU_readData(); +#ifdef PSXHW_LOG + PSXHW_LOG("GPU DATA 32bit read %lx\n", hard); +#endif + return hard; + case 0x1f801814: + hard = GPU_readStatus(); +#ifdef PSXHW_LOG + PSXHW_LOG("GPU STATUS 32bit read %lx\n", hard); +#endif + return hard; + + case 0x1f801820: hard = mdecRead0(); break; + case 0x1f801824: hard = mdecRead1(); break; + +#ifdef PSXHW_LOG + case 0x1f8010a0: + PSXHW_LOG("DMA2 MADR 32bit read %lx\n", psxHu32(0x10a0)); + return HW_DMA2_MADR; + case 0x1f8010a4: + PSXHW_LOG("DMA2 BCR 32bit read %lx\n", psxHu32(0x10a4)); + return HW_DMA2_BCR; + case 0x1f8010a8: + PSXHW_LOG("DMA2 CHCR 32bit read %lx\n", psxHu32(0x10a8)); + return HW_DMA2_CHCR; +#endif + +#ifdef PSXHW_LOG + case 0x1f8010b0: + PSXHW_LOG("DMA3 MADR 32bit read %lx\n", psxHu32(0x10b0)); + return HW_DMA3_MADR; + case 0x1f8010b4: + PSXHW_LOG("DMA3 BCR 32bit read %lx\n", psxHu32(0x10b4)); + return HW_DMA3_BCR; + case 0x1f8010b8: + PSXHW_LOG("DMA3 CHCR 32bit read %lx\n", psxHu32(0x10b8)); + return HW_DMA3_CHCR; +#endif + +#ifdef PSXHW_LOG +/* case 0x1f8010f0: + PSXHW_LOG("DMA PCR 32bit read %x\n", psxHu32(0x10f0)); + return HW_DMA_PCR; // dma rest channel + case 0x1f8010f4: + PSXHW_LOG("DMA ICR 32bit read %x\n", psxHu32(0x10f4)); + return HW_DMA_ICR; // interrupt enabler?*/ +#endif + + // time for rootcounters :) + case 0x1f801100: + hard = psxRcntRcount(0); +#ifdef PSXHW_LOG + PSXHW_LOG("T0 count read32: %lx\n", hard); +#endif + return hard; + case 0x1f801104: + hard = psxCounters[0].mode; +#ifdef PSXHW_LOG + PSXHW_LOG("T0 mode read32: %lx\n", hard); +#endif + return hard; + case 0x1f801108: + hard = psxCounters[0].target; +#ifdef PSXHW_LOG + PSXHW_LOG("T0 target read32: %lx\n", hard); +#endif + return hard; + case 0x1f801110: + hard = psxRcntRcount(1); +#ifdef PSXHW_LOG + PSXHW_LOG("T1 count read32: %lx\n", hard); +#endif + return hard; + case 0x1f801114: + hard = psxCounters[1].mode; +#ifdef PSXHW_LOG + PSXHW_LOG("T1 mode read32: %lx\n", hard); +#endif + return hard; + case 0x1f801118: + hard = psxCounters[1].target; +#ifdef PSXHW_LOG + PSXHW_LOG("T1 target read32: %lx\n", hard); +#endif + return hard; + case 0x1f801120: + hard = psxRcntRcount(2); +#ifdef PSXHW_LOG + PSXHW_LOG("T2 count read32: %lx\n", hard); +#endif + return hard; + case 0x1f801124: + hard = psxCounters[2].mode; +#ifdef PSXHW_LOG + PSXHW_LOG("T2 mode read32: %lx\n", hard); +#endif + return hard; + case 0x1f801128: + hard = psxCounters[2].target; +#ifdef PSXHW_LOG + PSXHW_LOG("T2 target read32: %lx\n", hard); +#endif + return hard; + + default: + hard = psxHu32(add); +#ifdef PSXHW_LOG + PSXHW_LOG("*Unkwnown 32bit read at address %lx\n", add); +#endif + return hard; + } +#ifdef PSXHW_LOG + PSXHW_LOG("*Known 32bit read at address %lx\n", add); +#endif + return hard; +} + +void psxHwWrite8(u32 add, u8 value) { + switch (add) { + case 0x1f801040: sioWrite8(value); break; + // case 0x1f801050: serial_write8(value); break;//serial port + case 0x1f801800: cdrWrite0(value); break; + case 0x1f801801: cdrWrite1(value); break; + case 0x1f801802: cdrWrite2(value); break; + case 0x1f801803: cdrWrite3(value); break; + + default: + psxHu8(add) = value; +#ifdef PSXHW_LOG + PSXHW_LOG("*Unknown 8bit write at address %lx value %x\n", add, value); +#endif + return; + } + psxHu8(add) = value; +#ifdef PSXHW_LOG + PSXHW_LOG("*Known 8bit write at address %lx value %x\n", add, value); +#endif +} + +void psxHwWrite16(u32 add, u16 value) { + switch (add) { + case 0x1f801040: + sioWrite8((unsigned char)value); + sioWrite8((unsigned char)(value>>8)); +#ifdef PAD_LOG + PAD_LOG ("sio write16 %lx, %x\n", add&0xf, value); +#endif + return; + case 0x1f801044: +#ifdef PAD_LOG + PAD_LOG ("sio write16 %lx, %x\n", add&0xf, value); +#endif + return; + case 0x1f801048: + ModeReg = value; +#ifdef PAD_LOG + PAD_LOG ("sio write16 %lx, %x\n", add&0xf, value); +#endif + return; + case 0x1f80104a: // control register + sioWriteCtrl16(value); +#ifdef PAD_LOG + PAD_LOG ("sio write16 %lx, %x\n", add&0xf, value); +#endif + return; + case 0x1f80104e: // baudrate register + BaudReg = value; +#ifdef PAD_LOG + PAD_LOG ("sio write16 %lx, %x\n", add&0xf, value); +#endif + return; + + //serial port ;P + // case 0x1f801050: serial_write16(value); break; + // case 0x1f80105a: serial_control_write(value);break; + // case 0x1f80105e: serial_baud_write(value); break; + // case 0x1f801054: serial_status_write(value); break; + + case 0x1f801070: +#ifdef PSXHW_LOG + PSXHW_LOG("IREG 16bit write %x\n", value); +#endif + if (Config.Sio) psxHu16(0x1070) |= 0x80; + if (Config.SpuIrq) psxHu16(0x1070) |= 0x200; + psxHu16(0x1070) &= (psxHu16(0x1074) & value); + return; +#ifdef PSXHW_LOG + case 0x1f801074: PSXHW_LOG("IMASK 16bit write %x\n", value); + psxHu16(0x1074) = value; + return; +#endif + + case 0x1f801100: +#ifdef PSXHW_LOG + PSXHW_LOG("COUNTER 0 COUNT 16bit write %x\n", value); +#endif + psxRcntWcount(0, value); return; + case 0x1f801104: +#ifdef PSXHW_LOG + PSXHW_LOG("COUNTER 0 MODE 16bit write %x\n", value); +#endif + psxRcntWmode(0, value); return; + case 0x1f801108: +#ifdef PSXHW_LOG + PSXHW_LOG("COUNTER 0 TARGET 16bit write %x\n", value); +#endif + psxRcntWtarget(0, value); return; + + case 0x1f801110: +#ifdef PSXHW_LOG + PSXHW_LOG("COUNTER 1 COUNT 16bit write %x\n", value); +#endif + psxRcntWcount(1, value); return; + case 0x1f801114: +#ifdef PSXHW_LOG + PSXHW_LOG("COUNTER 1 MODE 16bit write %x\n", value); +#endif + psxRcntWmode(1, value); return; + case 0x1f801118: +#ifdef PSXHW_LOG + PSXHW_LOG("COUNTER 1 TARGET 16bit write %x\n", value); +#endif + psxRcntWtarget(1, value); return; + + case 0x1f801120: +#ifdef PSXHW_LOG + PSXHW_LOG("COUNTER 2 COUNT 16bit write %x\n", value); +#endif + psxRcntWcount(2, value); return; + case 0x1f801124: +#ifdef PSXHW_LOG + PSXHW_LOG("COUNTER 2 MODE 16bit write %x\n", value); +#endif + psxRcntWmode(2, value); return; + case 0x1f801128: +#ifdef PSXHW_LOG + PSXHW_LOG("COUNTER 2 TARGET 16bit write %x\n", value); +#endif + psxRcntWtarget(2, value); return; + + default: + if (add>=0x1f801c00 && add<0x1f801e00) { + SPU_writeRegister(add, value); + return; + } + + psxHu16(add) = value; +#ifdef PSXHW_LOG + PSXHW_LOG("*Unknown 16bit write at address %lx value %x\n", add, value); +#endif + return; + } + psxHu16(add) = value; +#ifdef PSXHW_LOG + PSXHW_LOG("*Known 16bit write at address %lx value %x\n", add, value); +#endif +} + +#define DMA_INTERRUPT(n) \ + if (HW_DMA_ICR & (1 << (16 + n))) { \ + HW_DMA_ICR|= (1 << (24 + n)); \ + psxHu32(0x1070) |= 8; \ + } + +#define DmaExec(n) { \ + if (HW_DMA##n##_CHCR & 0x01000000 && HW_DMA_PCR & (8 << (n * 4))) { \ + psxDma##n##(HW_DMA##n##_MADR, HW_DMA##n##_BCR, HW_DMA##n##_CHCR); \ + HW_DMA##n##_CHCR &= ~0x01000000; \ + DMA_INTERRUPT(n); \ + } \ +} + +void psxHwWrite32(u32 add, u32 value) { + switch (add) { + case 0x1f801040: + sioWrite8((unsigned char)value); + sioWrite8((unsigned char)((value&0xff) >> 8)); + sioWrite8((unsigned char)((value&0xff) >> 16)); + sioWrite8((unsigned char)((value&0xff) >> 24)); +#ifdef PAD_LOG + PAD_LOG("sio write32 %lx\n", value); +#endif + return; + // case 0x1f801050: serial_write32(value); break;//serial port +#ifdef PSXHW_LOG + case 0x1f801060: + PSXHW_LOG("RAM size write %lx\n", value); + psxHu32(add) = value; + return; // Ram size +#endif + + case 0x1f801070: +#ifdef PSXHW_LOG + PSXHW_LOG("IREG 32bit write %lx\n", value); +#endif + if (Config.Sio) psxHu32(0x1070) |= 0x80; + if (Config.SpuIrq) psxHu32(0x1070) |= 0x200; + psxHu32(0x1070) &= (psxHu32(0x1074) & value); + return; +#ifdef PSXHW_LOG + case 0x1f801074: + PSXHW_LOG("IMASK 32bit write %lx\n", value); + psxHu32(0x1074) = value; + return; +#endif + +#ifdef PSXHW_LOG + case 0x1f801080: + PSXHW_LOG("DMA0 MADR 32bit write %lx\n", value); + HW_DMA0_MADR = value; return; // DMA0 madr + case 0x1f801084: + PSXHW_LOG("DMA0 BCR 32bit write %lx\n", value); + HW_DMA0_BCR = value; return; // DMA0 bcr +#endif + case 0x1f801088: +#ifdef PSXHW_LOG + PSXHW_LOG("DMA0 CHCR 32bit write %lx\n", value); +#endif + HW_DMA0_CHCR = value; // DMA0 chcr (MDEC in DMA) + DmaExec(0); + return; + +#ifdef PSXHW_LOG + case 0x1f801090: + PSXHW_LOG("DMA1 MADR 32bit write %lx\n", value); + HW_DMA1_MADR = value; return; // DMA1 madr + case 0x1f801094: + PSXHW_LOG("DMA1 BCR 32bit write %lx\n", value); + HW_DMA1_BCR = value; return; // DMA1 bcr +#endif + case 0x1f801098: +#ifdef PSXHW_LOG + PSXHW_LOG("DMA1 CHCR 32bit write %lx\n", value); +#endif + HW_DMA1_CHCR = value; // DMA1 chcr (MDEC out DMA) + DmaExec(1); + return; + +#ifdef PSXHW_LOG + case 0x1f8010a0: + PSXHW_LOG("DMA2 MADR 32bit write %lx\n", value); + HW_DMA2_MADR = value; return; // DMA2 madr + case 0x1f8010a4: + PSXHW_LOG("DMA2 BCR 32bit write %lx\n", value); + HW_DMA2_BCR = value; return; // DMA2 bcr +#endif + case 0x1f8010a8: +#ifdef PSXHW_LOG + PSXHW_LOG("DMA2 CHCR 32bit write %lx\n", value); +#endif + HW_DMA2_CHCR = value; // DMA2 chcr (GPU DMA) + DmaExec(2); + return; + +#ifdef PSXHW_LOG + case 0x1f8010b0: + PSXHW_LOG("DMA3 MADR 32bit write %lx\n", value); + HW_DMA3_MADR = value; return; // DMA3 madr + case 0x1f8010b4: + PSXHW_LOG("DMA3 BCR 32bit write %lx\n", value); + HW_DMA3_BCR = value; return; // DMA3 bcr +#endif + case 0x1f8010b8: +#ifdef PSXHW_LOG + PSXHW_LOG("DMA3 CHCR 32bit write %lx\n", value); +#endif + HW_DMA3_CHCR = value; // DMA3 chcr (CDROM DMA) + DmaExec(3); + + return; + +#ifdef PSXHW_LOG + case 0x1f8010c0: + PSXHW_LOG("DMA4 MADR 32bit write %lx\n", value); + HW_DMA4_MADR = value; return; // DMA4 madr + case 0x1f8010c4: + PSXHW_LOG("DMA4 BCR 32bit write %lx\n", value); + HW_DMA4_BCR = value; return; // DMA4 bcr +#endif + case 0x1f8010c8: +#ifdef PSXHW_LOG + PSXHW_LOG("DMA4 CHCR 32bit write %lx\n", value); +#endif + HW_DMA4_CHCR = value; // DMA4 chcr (SPU DMA) + DmaExec(4); + return; + +#if 0 + case 0x1f8010d0: break; //DMA5write_madr(); + case 0x1f8010d4: break; //DMA5write_bcr(); + case 0x1f8010d8: break; //DMA5write_chcr(); // Not yet needed?? +#endif + +#ifdef PSXHW_LOG + case 0x1f8010e0: + PSXHW_LOG("DMA6 MADR 32bit write %lx\n", value); + HW_DMA6_MADR = value; return; // DMA6 bcr + case 0x1f8010e4: + PSXHW_LOG("DMA6 BCR 32bit write %lx\n", value); + HW_DMA6_BCR = value; return; // DMA6 bcr +#endif + case 0x1f8010e8: +#ifdef PSXHW_LOG + PSXHW_LOG("DMA6 CHCR 32bit write %lx\n", value); +#endif + HW_DMA6_CHCR = value; // DMA6 chcr (OT clear) + DmaExec(6); + return; + +#ifdef PSXHW_LOG + case 0x1f8010f0: + PSXHW_LOG("DMA PCR 32bit write %lx\n", value); + HW_DMA_PCR = value; + return; +#endif + + case 0x1f8010f4: +#ifdef PSXHW_LOG + PSXHW_LOG("DMA ICR 32bit write %lx\n", value); +#endif + { + u32 tmp = (~value) & HW_DMA_ICR; + HW_DMA_ICR = ((tmp ^ value) & 0xffffff) ^ tmp; + return; + } + + case 0x1f801810: +#ifdef PSXHW_LOG + PSXHW_LOG("GPU DATA 32bit write %lx\n", value); +#endif + GPU_writeData(value); return; + case 0x1f801814: +#ifdef PSXHW_LOG + PSXHW_LOG("GPU STATUS 32bit write %lx\n", value); +#endif + GPU_writeStatus(value); return; + + case 0x1f801820: + mdecWrite0(value); break; + case 0x1f801824: + mdecWrite1(value); break; + + case 0x1f801100: +#ifdef PSXHW_LOG + PSXHW_LOG("COUNTER 0 COUNT 32bit write %lx\n", value); +#endif + psxRcntWcount(0, value & 0xffff); return; + case 0x1f801104: +#ifdef PSXHW_LOG + PSXHW_LOG("COUNTER 0 MODE 32bit write %lx\n", value); +#endif + psxRcntWmode(0, value); return; + case 0x1f801108: +#ifdef PSXHW_LOG + PSXHW_LOG("COUNTER 0 TARGET 32bit write %lx\n", value); +#endif + psxRcntWtarget(0, value & 0xffff); return; // HW_DMA_ICR&= (~value)&0xff000000; + + case 0x1f801110: +#ifdef PSXHW_LOG + PSXHW_LOG("COUNTER 1 COUNT 32bit write %lx\n", value); +#endif + psxRcntWcount(1, value & 0xffff); return; + case 0x1f801114: +#ifdef PSXHW_LOG + PSXHW_LOG("COUNTER 1 MODE 32bit write %lx\n", value); +#endif + psxRcntWmode(1, value); return; + case 0x1f801118: +#ifdef PSXHW_LOG + PSXHW_LOG("COUNTER 1 TARGET 32bit write %lx\n", value); +#endif + psxRcntWtarget(1, value & 0xffff); return; + + case 0x1f801120: +#ifdef PSXHW_LOG + PSXHW_LOG("COUNTER 2 COUNT 32bit write %lx\n", value); +#endif + psxRcntWcount(2, value & 0xffff); return; + case 0x1f801124: +#ifdef PSXHW_LOG + PSXHW_LOG("COUNTER 2 MODE 32bit write %lx\n", value); +#endif + psxRcntWmode(2, value); return; + case 0x1f801128: +#ifdef PSXHW_LOG + PSXHW_LOG("COUNTER 2 TARGET 32bit write %lx\n", value); +#endif + psxRcntWtarget(2, value & 0xffff); return; + + default: + psxHu32(add) = value; +#ifdef PSXHW_LOG + PSXHW_LOG("*Unknown 32bit write at address %lx value %lx\n", add, value); +#endif + return; + } + psxHu32(add) = value; +#ifdef PSXHW_LOG + PSXHW_LOG("*Known 32bit write at address %lx value %lx\n", add, value); +#endif +} + +int psxHwFreeze(gzFile f, int Mode) { + char Unused[4096]; + + gzfreezel(Unused); + + return 0; +} diff --git a/PcsxSrc/PsxHw.h b/PcsxSrc/PsxHw.h new file mode 100644 index 0000000..a27ec9c --- /dev/null +++ b/PcsxSrc/PsxHw.h @@ -0,0 +1,31 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __PSXHW_H__ +#define __PSXHW_H__ + +void psxHwReset(); +u8 psxHwRead8 (u32 add); +u16 psxHwRead16(u32 add); +u32 psxHwRead32(u32 add); +void psxHwWrite8 (u32 add, u8 value); +void psxHwWrite16(u32 add, u16 value); +void psxHwWrite32(u32 add, u32 value); +int psxHwFreeze(gzFile f, int Mode); + +#endif /* __PSXHW_H__ */ diff --git a/PcsxSrc/PsxInterpreter.c b/PcsxSrc/PsxInterpreter.c new file mode 100644 index 0000000..ddf1d84 --- /dev/null +++ b/PcsxSrc/PsxInterpreter.c @@ -0,0 +1,471 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include + +#include "PsxCommon.h" + +static int branch = 0; +static int branch2 = 0; +static u32 branchPC; + +// These macros are used to assemble the repassembler functions + +#ifdef PSXCPU_LOG +#define debugI() \ + if (Log) { \ + PSXCPU_LOG("%s\n", disR3000AF(psxRegs.code, psxRegs.pc)); \ + } +#else +#define debugI() +#endif + +#define execI() { \ + psxRegs.code = PSXMu32(psxRegs.pc); \ + \ + debugI(); \ + \ + psxRegs.pc+= 4; \ + psxRegs.cycle++; \ + \ + psxBSC[psxRegs.code >> 26](); \ +} + +#define doBranch(tar) { \ + branch2 = branch = 1; \ + branchPC = tar; \ + execI(); \ + branch = 0; \ + psxRegs.pc = branchPC; \ + \ + psxBranchTest(); \ +} + +// Subsets +void (*psxBSC[64])(); +void (*psxSPC[64])(); +void (*psxREG[32])(); +void (*psxCP0[32])(); +void (*psxCP2[64])(); +void (*psxCP2BSC[32])(); + +/********************************************************* +* Arithmetic with immediate operand * +* Format: OP rt, rs, immediate * +*********************************************************/ +void psxADDI() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) + _Imm_ ; } // Rt = Rs + Im (Exception on Integer Overflow) +void psxADDIU() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) + _Imm_ ; } // Rt = Rs + Im +void psxANDI() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) & _ImmU_; } // Rt = Rs And Im +void psxORI() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) | _ImmU_; } // Rt = Rs Or Im +void psxXORI() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) ^ _ImmU_; } // Rt = Rs Xor Im +void psxSLTI() { if (!_Rt_) return; _rRt_ = _i32(_rRs_) < _Imm_ ; } // Rt = Rs < Im (Signed) +void psxSLTIU() { if (!_Rt_) return; _rRt_ = _u32(_rRs_) < _ImmU_; } // Rt = Rs < Im (Unsigned) + +/********************************************************* +* Register arithmetic * +* Format: OP rd, rs, rt * +*********************************************************/ +void psxADD() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) + _u32(_rRt_); } // Rd = Rs + Rt (Exception on Integer Overflow) +void psxADDU() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) + _u32(_rRt_); } // Rd = Rs + Rt +void psxSUB() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) - _u32(_rRt_); } // Rd = Rs - Rt (Exception on Integer Overflow) +void psxSUBU() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) - _u32(_rRt_); } // Rd = Rs - Rt +void psxAND() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) & _u32(_rRt_); } // Rd = Rs And Rt +void psxOR() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) | _u32(_rRt_); } // Rd = Rs Or Rt +void psxXOR() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) ^ _u32(_rRt_); } // Rd = Rs Xor Rt +void psxNOR() { if (!_Rd_) return; _rRd_ =~(_u32(_rRs_) | _u32(_rRt_)); }// Rd = Rs Nor Rt +void psxSLT() { if (!_Rd_) return; _rRd_ = _i32(_rRs_) < _i32(_rRt_); } // Rd = Rs < Rt (Signed) +void psxSLTU() { if (!_Rd_) return; _rRd_ = _u32(_rRs_) < _u32(_rRt_); } // Rd = Rs < Rt (Unsigned) + +/********************************************************* +* Register mult/div & Register trap logic * +* Format: OP rs, rt * +*********************************************************/ +void psxDIV() { + if (_i32(_rRt_) != 0) { + _i32(_rLo_) = _i32(_rRs_) / _i32(_rRt_); + _i32(_rHi_) = _i32(_rRs_) % _i32(_rRt_); + } +} + +void psxDIVU() { + if (_rRt_ != 0) { + _rLo_ = _rRs_ / _rRt_; + _rHi_ = _rRs_ % _rRt_; + } +} + +void psxMULT() { + u64 res = (s64)((s64)_i32(_rRs_) * (s64)_i32(_rRt_)); + + psxRegs.GPR.n.lo = (unsigned long)(res & 0xffffffff); + psxRegs.GPR.n.hi = (unsigned long)((res >> 32) & 0xffffffff); +} + +void psxMULTU() { + u64 res = (u64)((u64)_u32(_rRs_) * (u64)_u32(_rRt_)); + + psxRegs.GPR.n.lo = (unsigned long)(res & 0xffffffff); + psxRegs.GPR.n.hi = (unsigned long)((res >> 32) & 0xffffffff); +} + +/********************************************************* +* Register branch logic * +* Format: OP rs, offset * +*********************************************************/ +#define RepZBranchi32(op) if(_i32(_rRs_) op 0) doBranch(_BranchTarget_); +#define RepZBranchLinki32(op) if(_i32(_rRs_) op 0) { _SetLink(31); doBranch(_BranchTarget_); } + +void psxBGEZ() { RepZBranchi32(>=) } // Branch if Rs >= 0 +void psxBGEZAL() { RepZBranchLinki32(>=) } // Branch if Rs >= 0 and link +void psxBGTZ() { RepZBranchi32(>) } // Branch if Rs > 0 +void psxBLEZ() { RepZBranchi32(<=) } // Branch if Rs <= 0 +void psxBLTZ() { RepZBranchi32(<) } // Branch if Rs < 0 +void psxBLTZAL() { RepZBranchLinki32(<) } // Branch if Rs < 0 and link + +/********************************************************* +* Shift arithmetic with constant shift * +* Format: OP rd, rt, sa * +*********************************************************/ +void psxSLL() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) << _Sa_; } // Rd = Rt << sa +void psxSRA() { if (!_Rd_) return; _i32(_rRd_) = _i32(_rRt_) >> _Sa_; } // Rd = Rt >> sa (arithmetic) +void psxSRL() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) >> _Sa_; } // Rd = Rt >> sa (logical) + +/********************************************************* +* Shift arithmetic with variant register shift * +* Format: OP rd, rt, rs * +*********************************************************/ +void psxSLLV() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) << _u32(_rRs_); } // Rd = Rt << rs +void psxSRAV() { if (!_Rd_) return; _i32(_rRd_) = _i32(_rRt_) >> _u32(_rRs_); } // Rd = Rt >> rs (arithmetic) +void psxSRLV() { if (!_Rd_) return; _u32(_rRd_) = _u32(_rRt_) >> _u32(_rRs_); } // Rd = Rt >> rs (logical) + +/********************************************************* +* Load higher 16 bits of the first word in GPR with imm * +* Format: OP rt, immediate * +*********************************************************/ +void psxLUI() { if (!_Rt_) return; _u32(_rRt_) = psxRegs.code << 16; } // Upper halfword of Rt = Im + +/********************************************************* +* Move from HI/LO to GPR * +* Format: OP rd * +*********************************************************/ +void psxMFHI() { if (!_Rd_) return; _rRd_ = _rHi_; } // Rd = Hi +void psxMFLO() { if (!_Rd_) return; _rRd_ = _rLo_; } // Rd = Lo + +/********************************************************* +* Move to GPR to HI/LO & Register jump * +* Format: OP rs * +*********************************************************/ +void psxMTHI() { _rHi_ = _rRs_; } // Hi = Rs +void psxMTLO() { _rLo_ = _rRs_; } // Lo = Rs + +/********************************************************* +* Special purpose instructions * +* Format: OP * +*********************************************************/ +void psxBREAK() { + // Break exception - psx rom doens't handles this +} + +void psxSYSCALL() { + psxRegs.pc -= 4; + psxException(0x20, branch); +} + +void psxRFE() { + psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status & 0xfffffff0) | + ((psxRegs.CP0.n.Status & 0x3c) >> 2); +} + +/********************************************************* +* Register branch logic * +* Format: OP rs, rt, offset * +*********************************************************/ +#define RepBranchi32(op) if(_i32(_rRs_) op _i32(_rRt_)) doBranch(_BranchTarget_); + +void psxBEQ() { RepBranchi32(==) } // Branch if Rs == Rt +void psxBNE() { RepBranchi32(!=) } // Branch if Rs != Rt + +/********************************************************* +* Jump to target * +* Format: OP target * +*********************************************************/ +void psxJ() { doBranch(_JumpTarget_); } +void psxJAL() { _SetLink(31); doBranch(_JumpTarget_); } + +/********************************************************* +* Register jump * +* Format: OP rs, rd * +*********************************************************/ +void psxJR() { doBranch(_u32(_rRs_)); } +void psxJALR() { if (_Rd_) { _SetLink(_Rd_); } doBranch(_u32(_rRs_)); } + +/********************************************************* +* Load and store for GPR * +* Format: OP rt, offset(base) * +*********************************************************/ + +#define _oB_ (_u32(_rRs_) + _Imm_) + +void psxLB() { + if (_Rt_) { + _i32(_rRt_) = (char)psxMemRead8(_oB_); + } else { + psxMemRead8(_oB_); + } +} + +void psxLBU() { + if (_Rt_) { + _u32(_rRt_) = psxMemRead8(_oB_); + } else { + psxMemRead8(_oB_); + } +} + +void psxLH() { + if (_Rt_) { + _i32(_rRt_) = (short)psxMemRead16(_oB_); + } else { + psxMemRead16(_oB_); + } +} + +void psxLHU() { + if (_Rt_) { + _u32(_rRt_) = psxMemRead16(_oB_); + } else { + psxMemRead16(_oB_); + } +} + +void psxLW() { + if (_Rt_) { + _u32(_rRt_) = psxMemRead32(_oB_); + } else { + psxMemRead32(_oB_); + } +} + +void psxLWL() { + u32 shift = (_oB_ & 3) << 3; + u32 mem = psxMemRead32(_oB_ & 0xfffffffc); + + if (!_Rt_) return; + _u32(_rRt_) = ( _u32(_rRt_) & (0x00ffffff >> shift) ) | + ( mem << (24 - shift) ); + + /* + Mem = 1234. Reg = abcd + + 0 4bcd (mem << 24) | (reg & 0x00ffffff) + 1 34cd (mem << 16) | (reg & 0x0000ffff) + 2 234d (mem << 8) | (reg & 0x000000ff) + 3 1234 (mem ) | (reg & 0x00000000) + + */ +} + +void psxLWR() { + u32 shift = (_oB_ & 3) << 3; + u32 mem = psxMemRead32(_oB_ & 0xfffffffc); + + if (!_Rt_) return; + _u32(_rRt_) = ( _u32(_rRt_) & (0xffffff00 << (24 - shift)) ) | + ( mem >> shift ); + + /* + Mem = 1234. Reg = abcd + + 0 1234 (mem ) | (reg & 0x00000000) + 1 a123 (mem >> 8) | (reg & 0xff000000) + 2 ab12 (mem >> 16) | (reg & 0xffff0000) + 3 abc1 (mem >> 24) | (reg & 0xffffff00) + + */ +} + +void psxSB() { psxMemWrite8 (_oB_, _u8 (_rRt_)); } +void psxSH() { psxMemWrite16(_oB_, _u16(_rRt_)); } +void psxSW() { psxMemWrite32(_oB_, _u32(_rRt_)); } + +void psxSWL() { + u32 shift = (_oB_ & 3) << 3; + u32 mem = psxMemRead32(_oB_ & 0xfffffffc); + + psxMemWrite32((_oB_ & 0xfffffffc), ( ( _u32(_rRt_) >> (24 - shift) ) ) | + ( mem & (0xffffff00 << shift) )); + /* + Mem = 1234. Reg = abcd + + 0 123a (reg >> 24) | (mem & 0xffffff00) + 1 12ab (reg >> 16) | (mem & 0xffff0000) + 2 1abc (reg >> 8) | (mem & 0xff000000) + 3 abcd (reg ) | (mem & 0x00000000) + + */ +} + +void psxSWR() { + u32 shift = (_oB_ & 3) << 3; + u32 mem = psxMemRead32(_oB_ & 0xfffffffc); + + psxMemWrite32((_oB_ & 0xfffffffc), ( ( _u32(_rRt_) << shift ) | + (mem & (0x00ffffff >> (24 - shift)) ) ) ); + /* + Mem = 1234. Reg = abcd + + 0 abcd (reg ) | (mem & 0x00000000) + 1 bcd4 (reg << 8) | (mem & 0x000000ff) + 2 cd34 (reg << 16) | (mem & 0x0000ffff) + 3 d234 (reg << 24) | (mem & 0x00ffffff) + + */ +} + +/********************************************************* +* Moves between GPR and COPx * +* Format: OP rt, fs * +*********************************************************/ +void psxMFC0() { if (!_Rt_) return; _i32(_rRt_) = (int)_rFs_; } +void psxCFC0() { if (!_Rt_) return; _i32(_rRt_) = (int)_rFs_; } + +void psxMTC0() { _rFs_ = _u32(_rRt_); } +void psxCTC0() { _rFs_ = _u32(_rRt_); } + +/********************************************************* +* Unknow instruction (would generate an exception) * +* Format: ? * +*********************************************************/ +void psxNULL() { +#ifdef PSXCPU_LOG + PSXCPU_LOG("psx: Unimplemented op %x\n", psxRegs.code); +#endif +} + +void psxSPECIAL() { + psxSPC[_Funct_](); +} + +void psxREGIMM() { + psxREG[_Rt_](); +} + +void psxCOP0() { + psxCP0[_Rs_](); +} + +void psxCOP2() { + psxCP2[_Funct_](); +} + +void psxBASIC() { + psxCP2BSC[_Rs_](); +} + +void psxHLE() { + psxHLEt[psxRegs.code & 0xff](); +} + +void (*psxBSC[64])() = { + psxSPECIAL, psxREGIMM, psxJ , psxJAL , psxBEQ , psxBNE , psxBLEZ, psxBGTZ, + psxADDI , psxADDIU , psxSLTI, psxSLTIU, psxANDI, psxORI , psxXORI, psxLUI , + psxCOP0 , psxNULL , psxCOP2, psxNULL , psxNULL, psxNULL, psxNULL, psxNULL, + psxNULL , psxNULL , psxNULL, psxNULL , psxNULL, psxNULL, psxNULL, psxNULL, + psxLB , psxLH , psxLWL , psxLW , psxLBU , psxLHU , psxLWR , psxNULL, + psxSB , psxSH , psxSWL , psxSW , psxNULL, psxNULL, psxSWR , psxNULL, + psxNULL , psxNULL , gteLWC2, psxNULL , psxNULL, psxNULL, psxNULL, psxNULL, + psxNULL , psxNULL , gteSWC2, psxHLE , psxNULL, psxNULL, psxNULL, psxNULL +}; + + +void (*psxSPC[64])() = { + psxSLL , psxNULL , psxSRL , psxSRA , psxSLLV , psxNULL , psxSRLV, psxSRAV, + psxJR , psxJALR , psxNULL, psxNULL, psxSYSCALL, psxBREAK, psxNULL, psxNULL, + psxMFHI, psxMTHI , psxMFLO, psxMTLO, psxNULL , psxNULL , psxNULL, psxNULL, + psxMULT, psxMULTU, psxDIV , psxDIVU, psxNULL , psxNULL , psxNULL, psxNULL, + psxADD , psxADDU , psxSUB , psxSUBU, psxAND , psxOR , psxXOR , psxNOR , + psxNULL, psxNULL , psxSLT , psxSLTU, psxNULL , psxNULL , psxNULL, psxNULL, + psxNULL, psxNULL , psxNULL, psxNULL, psxNULL , psxNULL , psxNULL, psxNULL, + psxNULL, psxNULL , psxNULL, psxNULL, psxNULL , psxNULL , psxNULL, psxNULL +}; + +void (*psxREG[32])() = { + psxBLTZ , psxBGEZ , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, + psxNULL , psxNULL , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, + psxBLTZAL, psxBGEZAL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, + psxNULL , psxNULL , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL +}; + +void (*psxCP0[32])() = { + psxMFC0, psxNULL, psxCFC0, psxNULL, psxMTC0, psxNULL, psxCTC0, psxNULL, + psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, + psxRFE , psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, + psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL +}; + +void (*psxCP2[64])() = { + psxBASIC, gteRTPS , psxNULL , psxNULL, psxNULL, psxNULL , gteNCLIP, psxNULL, // 00 + psxNULL , psxNULL , psxNULL , psxNULL, gteOP , psxNULL , psxNULL , psxNULL, // 08 + gteDPCS , gteINTPL, gteMVMVA, gteNCDS, gteCDP , psxNULL , gteNCDT , psxNULL, // 10 + psxNULL , psxNULL , psxNULL , gteNCCS, gteCC , psxNULL , gteNCS , psxNULL, // 18 + gteNCT , psxNULL , psxNULL , psxNULL, psxNULL, psxNULL , psxNULL , psxNULL, // 20 + gteSQR , gteDCPL , gteDPCT , psxNULL, psxNULL, gteAVSZ3, gteAVSZ4, psxNULL, // 28 + gteRTPT , psxNULL , psxNULL , psxNULL, psxNULL, psxNULL , psxNULL , psxNULL, // 30 + psxNULL , psxNULL , psxNULL , psxNULL, psxNULL, gteGPF , gteGPL , gteNCCT // 38 +}; + +void (*psxCP2BSC[32])() = { + gteMFC2, psxNULL, gteCFC2, psxNULL, gteMTC2, psxNULL, gteCTC2, psxNULL, + psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, + psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, + psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL, psxNULL +}; + + +/////////////////////////////////////////// + +static int intInit() { + return 0; +} + +static void intReset() { +} + +static void intExecute() { + for (;;) execI(); +} + +static void intExecuteBlock() { + branch2 = 0; + while (!branch2) execI(); +} + +static void intClear(u32 Addr, u32 Size) { +} + +static void intShutdown() { +} + +R3000Acpu psxInt = { + intInit, + intReset, + intExecute, + intExecuteBlock, + intClear, + intShutdown +}; diff --git a/PcsxSrc/PsxMem.c b/PcsxSrc/PsxMem.c new file mode 100644 index 0000000..b30aa22 --- /dev/null +++ b/PcsxSrc/PsxMem.c @@ -0,0 +1,250 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include "PsxCommon.h" + + +int psxMemInit() { + int i; + + psxMemLUT = (long*)malloc(0x10000 * 4); + memset(psxMemLUT, 0, 0x10000 * 4); + + psxM = (char*)malloc(0x00200000); + psxP = (char*)malloc(0x00010000); + psxH = (char*)malloc(0x00010000); + psxR = (char*)malloc(0x00080000); + if (psxMemLUT == NULL || psxM == NULL || psxP == NULL || psxH == NULL || psxR == NULL) { + SysMessage("Error allocating memory"); return -1; + } + + for (i=0; i<0x80; i++) psxMemLUT[i + 0x0000] = (u32)&psxM[(i & 0x1f) << 16]; + memcpy(psxMemLUT + 0x8000, psxMemLUT, 0x80 * 4); + memcpy(psxMemLUT + 0xa000, psxMemLUT, 0x80 * 4); + + for (i=0; i<0x01; i++) psxMemLUT[i + 0x1f00] = (u32)&psxP[i << 16]; + + for (i=0; i<0x01; i++) psxMemLUT[i + 0x1f80] = (u32)&psxH[i << 16]; + + for (i=0; i<0x08; i++) psxMemLUT[i + 0xbfc0] = (u32)&psxR[i << 16]; + + return 0; +} + +void psxMemReset() { + FILE *f = NULL; + char Bios[256]; + + memset(psxM, 0, 0x00200000); + memset(psxP, 0, 0x00010000); + + if (strcmp(Config.Bios, "HLE")) { + sprintf(Bios, "%s%s", Config.BiosDir, Config.Bios); + f = fopen(Bios, "rb"); + + if (f == NULL) { + SysMessage ("Could not open bios:\"%s\". Enabling HLE Bios\n", Bios); + memset(psxR, 0, 0x80000); + Config.HLE = 1; + } + else { + fread(psxR, 1, 0x80000, f); + fclose(f); + Config.HLE = 0; + } + } else Config.HLE = 1; +} + +void psxMemShutdown() { + free(psxM); + free(psxP); + free(psxH); + free(psxR); + free(psxMemLUT); +} + +static int writeok=1; + +u8 psxMemRead8(u32 mem) { + char *p; + u32 t; + + t = mem >> 16; + if (t == 0x1f80) { + if (mem < 0x1f801000) + return psxHu8(mem); + else + return psxHwRead8(mem); + } else { + p = (char *)(psxMemLUT[t]); + if (p != NULL) { + return *(u8 *)(p + (mem & 0xffff)); + } else { +#ifdef PSXMEM_LOG + PSXMEM_LOG("err lb %8.8lx\n", mem); +#endif + return 0; + } + } +} + +u16 psxMemRead16(u32 mem) { + char *p; + u32 t; + + t = mem >> 16; + if (t == 0x1f80) { + if (mem < 0x1f801000) + return psxHu16(mem); + else + return psxHwRead16(mem); + } else { + p = (char *)(psxMemLUT[t]); + if (p != NULL) { + return *(u16 *)(p + (mem & 0xffff)); + } else { +#ifdef PSXMEM_LOG + PSXMEM_LOG("err lh %8.8lx\n", mem); +#endif + return 0; + } + } +} + +u32 psxMemRead32(u32 mem) { + char *p; + u32 t; + + t = mem >> 16; + if (t == 0x1f80) { + if (mem < 0x1f801000) + return psxHu32(mem); + else + return psxHwRead32(mem); + } else { + p = (char *)(psxMemLUT[t]); + if (p != NULL) { + return *(u32 *)(p + (mem & 0xffff)); + } else { +#ifdef PSXMEM_LOG + if (writeok) PSXMEM_LOG("err lw %8.8lx\n", mem); +#endif + return 0; + } + } +} + +void psxMemWrite8(u32 mem, u8 value) { + char *p; + u32 t; + + t = mem >> 16; + if (t == 0x1f80) { + if (mem < 0x1f801000) + psxHu8(mem) = value; + else + psxHwWrite8(mem, value); + } else { + p = (char *)(psxMemLUT[t]); + if (p != NULL) { + *(u8 *)(p + (mem & 0xffff)) = value; + psxCpu->Clear(mem, 1); + } else { +#ifdef PSXMEM_LOG + PSXMEM_LOG("err sb %8.8lx\n", mem); +#endif + } + } +} + +void psxMemWrite16(u32 mem, u16 value) { + char *p; + u32 t; + + t = mem >> 16; + if (t == 0x1f80) { + if (mem < 0x1f801000) + psxHu16(mem) = value; + else + psxHwWrite16(mem, value); + } else { + p = (char *)(psxMemLUT[t]); + if (p != NULL) { + *(u16 *)(p + (mem & 0xffff)) = value; + psxCpu->Clear(mem, 1); + } else { +#ifdef PSXMEM_LOG + PSXMEM_LOG("err sh %8.8lx\n", mem); +#endif + } + } +} + +void psxMemWrite32(u32 mem, u32 value) { + char *p; + u32 t; + + t = mem >> 16; + if (t == 0x1f80) { + if (mem < 0x1f801000) + psxHu32(mem) = value; + else + psxHwWrite32(mem, value); + } else { + p = (char *)(psxMemLUT[t]); + if (p != NULL) { + *(u32 *)(p + (mem & 0xffff)) = value; + psxCpu->Clear(mem, 1); + } else { + if (mem != 0xfffe0130) { + if (!writeok) psxCpu->Clear(mem, 1); +#ifdef PSXMEM_LOG + if (writeok) { PSXMEM_LOG("err sw %8.8lx\n", mem); } +#endif + } else { + int i; + + switch (value) { + case 0x800: case 0x804: + if (writeok == 0) break; + writeok = 0; + memset(psxMemLUT + 0x0000, 0, 0x80 * 4); + memset(psxMemLUT + 0x8000, 0, 0x80 * 4); + memset(psxMemLUT + 0xa000, 0, 0x80 * 4); + break; + case 0x1e988: + if (writeok == 1) break; + writeok = 1; + for (i=0; i<0x80; i++) psxMemLUT[i + 0x0000] = (u32)&psxM[(i & 0x1f) << 16]; + memcpy(psxMemLUT + 0x8000, psxMemLUT, 0x80 * 4); + memcpy(psxMemLUT + 0xa000, psxMemLUT, 0x80 * 4); + break; + default: +#ifdef PSXMEM_LOG + PSXMEM_LOG("unk %8.8lx = %x\n", mem, value); +#endif + break; + } + } + } + } +} + diff --git a/PcsxSrc/PsxMem.h b/PcsxSrc/PsxMem.h new file mode 100644 index 0000000..c8608da --- /dev/null +++ b/PcsxSrc/PsxMem.h @@ -0,0 +1,75 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __PSXMEMORY_H__ +#define __PSXMEMORY_H__ + +s8 *psxM; +#define psxMs8(mem) psxM[(mem) & 0x1fffff] +#define psxMs16(mem) (*(s16*)&psxM[(mem) & 0x1fffff]) +#define psxMs32(mem) (*(s32*)&psxM[(mem) & 0x1fffff]) +#define psxMu8(mem) (*(u8*) &psxM[(mem) & 0x1fffff]) +#define psxMu16(mem) (*(u16*)&psxM[(mem) & 0x1fffff]) +#define psxMu32(mem) (*(u32*)&psxM[(mem) & 0x1fffff]) + +s8 *psxP; +#define psxPs8(mem) psxP[(mem) & 0xffff] +#define psxPs16(mem) (*(s16*)&psxP[(mem) & 0xffff]) +#define psxPs32(mem) (*(s32*)&psxP[(mem) & 0xffff]) +#define psxPu8(mem) (*(u8*) &psxP[(mem) & 0xffff]) +#define psxPu16(mem) (*(u16*)&psxP[(mem) & 0xffff]) +#define psxPu32(mem) (*(u32*)&psxP[(mem) & 0xffff]) + +s8 *psxR; +#define psxRs8(mem) psxR[(mem) & 0x7ffff] +#define psxRs16(mem) (*(s16*)&psxR[(mem) & 0x7ffff]) +#define psxRs32(mem) (*(s32*)&psxR[(mem) & 0x7ffff]) +#define psxRu8(mem) (*(u8* )&psxR[(mem) & 0x7ffff]) +#define psxRu16(mem) (*(u16*)&psxR[(mem) & 0x7ffff]) +#define psxRu32(mem) (*(u32*)&psxR[(mem) & 0x7ffff]) + +s8 *psxH; +#define psxHs8(mem) psxH[(mem) & 0xffff] +#define psxHs16(mem) (*(s16*)&psxH[(mem) & 0xffff]) +#define psxHs32(mem) (*(s32*)&psxH[(mem) & 0xffff]) +#define psxHu8(mem) (*(u8*) &psxH[(mem) & 0xffff]) +#define psxHu16(mem) (*(u16*)&psxH[(mem) & 0xffff]) +#define psxHu32(mem) (*(u32*)&psxH[(mem) & 0xffff]) + +u32 *psxMemLUT; + +#define PSXM(mem) (psxMemLUT[(mem) >> 16] == 0 ? NULL : (void*)(psxMemLUT[(mem) >> 16] + ((mem) & 0xffff))) +#define PSXMs8(mem) (*(s8 *)PSXM(mem)) +#define PSXMs16(mem) (*(s16*)PSXM(mem)) +#define PSXMs32(mem) (*(s32*)PSXM(mem)) +#define PSXMu8(mem) (*(u8 *)PSXM(mem)) +#define PSXMu16(mem) (*(u16*)PSXM(mem)) +#define PSXMu32(mem) (*(u32*)PSXM(mem)) + +int psxMemInit(); +void psxMemReset(); +void psxMemShutdown(); + +u8 psxMemRead8 (u32 mem); +u16 psxMemRead16(u32 mem); +u32 psxMemRead32(u32 mem); +void psxMemWrite8 (u32 mem, u8 value); +void psxMemWrite16(u32 mem, u16 value); +void psxMemWrite32(u32 mem, u32 value); + +#endif /* __PSXMEMORY_H__ */ diff --git a/PcsxSrc/R3000A.c b/PcsxSrc/R3000A.c new file mode 100644 index 0000000..ab6aea2 --- /dev/null +++ b/PcsxSrc/R3000A.c @@ -0,0 +1,168 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include + +#include "PsxCommon.h" + +int psxInit() { + + if (Config.Cpu) psxCpu = &psxInt; +#ifdef __i386__ + else psxCpu = &psxRec; +#endif + Log=0; + + if (psxMemInit() == -1) return -1; + + return psxCpu->Init(); +} + +void psxReset() { + + psxCpu->Reset(); + + psxMemReset(); + + memset(&psxRegs, 0, sizeof(psxRegs)); + + psxRegs.pc = 0xbfc00000; // Start in bootstrap + + psxRegs.CP0.r[12] = 0x10900000; // COP0 enabled | BEV = 1 | TS = 1 + psxRegs.CP0.r[15] = 0x00000002; // PRevID = Revision ID, same as R3000A + + psxHwReset(); + psxBiosInit(); + + if (!Config.HLE) psxExecuteBios(); + +#ifdef PSX_LOG + PSX_LOG("*BIOS END*\n"); +#endif + Log=0; +} + +void psxShutdown() { + psxMemShutdown(); + psxBiosShutdown(); + + psxCpu->Shutdown(); +} + +void psxException(u32 code, u32 bd) { + // Set the Cause + psxRegs.CP0.n.Cause = code; + +#ifdef PSXCPU_LOG + if (bd) PSXCPU_LOG("bd set\n"); +#endif + // Set the EPC & PC + if (bd) { + psxRegs.CP0.n.Cause|= 0x80000000; + psxRegs.CP0.n.EPC = (psxRegs.pc - 4); + } else + psxRegs.CP0.n.EPC = (psxRegs.pc); + + if (psxRegs.CP0.n.Status & 0x400000) + psxRegs.pc = 0xbfc00180; + else + psxRegs.pc = 0x80000080; + + // Set the Status + psxRegs.CP0.n.Status = (psxRegs.CP0.n.Status &~0x3f) | + ((psxRegs.CP0.n.Status & 0xf) << 2); + + if (!Config.HLE && (((PSXMu32(psxRegs.CP0.n.EPC) >> 24) & 0xfe) == 0x4a)) { + // "hokuto no ken" / "Crash Bandicot 2" ... fix + PSXMu32(psxRegs.CP0.n.EPC)&= ~0x02000000; + } + + if (Config.HLE) psxBiosException(); +} + +void psxBranchTest() { + if ((psxRegs.cycle - psxNextsCounter) >= psxNextCounter) + psxRcntUpdate(); + + if (psxRegs.interrupt) { + if ((psxRegs.interrupt & 0x80) && (!Config.Sio)) { // sio + if ((psxRegs.cycle - psxRegs.intCycle[7]) >= psxRegs.intCycle[7+1]) { + psxRegs.interrupt&=~0x80; + sioInterrupt(); + } + } + if (psxRegs.interrupt & 0x04) { // cdr + if ((psxRegs.cycle - psxRegs.intCycle[2]) >= psxRegs.intCycle[2+1]) { + psxRegs.interrupt&=~0x04; + cdrInterrupt(); + } + } + if (psxRegs.interrupt & 0x040000) { // cdr read + if ((psxRegs.cycle - psxRegs.intCycle[2+16]) >= psxRegs.intCycle[2+16+1]) { + psxRegs.interrupt&=~0x040000; + cdrReadInterrupt(); + } + } + } + + if (psxHu32(0x1070) & psxHu32(0x1074)) { + if ((psxRegs.CP0.n.Status & 0x401) == 0x401) { +#ifdef PSXCPU_LOG +// PSXCPU_LOG("Interrupt: %x %x\n", HWMu32(0x1070), HWMu32(0x1074)); +#endif + psxException(0x400, 0); + } + } + + if (!Config.HLE && Config.PsxOut) { + u32 call = psxRegs.GPR.n.t1 & 0xff; + switch (psxRegs.pc & 0x1fffff) { + case 0xa0: +#ifdef PSXBIOS_LOG + if (call != 0x28 && call != 0xe) { + PSXBIOS_LOG("Bios call a0: %s (%x) %x,%x,%x,%x\n", biosA0n[call], call, psxRegs.GPR.n.a0, psxRegs.GPR.n.a1, psxRegs.GPR.n.a2, psxRegs.GPR.n.a3); } +#endif + if (biosA0[call]) + biosA0[call](); + break; + case 0xb0: +#ifdef PSXBIOS_LOG + if (call != 0x17 && call != 0xb) { + PSXBIOS_LOG("Bios call b0: %s (%x) %x,%x,%x,%x\n", biosB0n[call], call, psxRegs.GPR.n.a0, psxRegs.GPR.n.a1, psxRegs.GPR.n.a2, psxRegs.GPR.n.a3); } +#endif + if (biosB0[call]) + biosB0[call](); + break; + case 0xc0: +#ifdef PSXBIOS_LOG + PSXBIOS_LOG("Bios call c0: %s (%x) %x,%x,%x,%x\n", biosC0n[call], call, psxRegs.GPR.n.a0, psxRegs.GPR.n.a1, psxRegs.GPR.n.a2, psxRegs.GPR.n.a3); +#endif + if (biosC0[call]) + biosC0[call](); + break; + } + } +} + +void psxExecuteBios() { + while (psxRegs.pc != 0x80030000) + psxCpu->ExecuteBlock(); +} + diff --git a/PcsxSrc/R3000A.h b/PcsxSrc/R3000A.h new file mode 100644 index 0000000..67c4cc6 --- /dev/null +++ b/PcsxSrc/R3000A.h @@ -0,0 +1,186 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __R3000A_H__ +#define __R3000A_H__ + +#include + +#include "PsxCommon.h" + +typedef struct { + int (*Init)(); + void (*Reset)(); + void (*Execute)(); /* executes up to a break */ + void (*ExecuteBlock)(); /* executes up to a jump */ + void (*Clear)(u32 Addr, u32 Size); + void (*Shutdown)(); +} R3000Acpu; + +R3000Acpu *psxCpu; +extern R3000Acpu psxInt; +#ifdef __i386__ +extern R3000Acpu psxRec; +#endif + +typedef union { + struct { + unsigned long r0, at, v0, v1, a0, a1, a2, a3, + t0, t1, t2, t3, t4, t5, t6, t7, + s0, s1, s2, s3, s4, s5, s6, s7, + t8, t9, k0, k1, gp, sp, s8, ra, lo, hi; + } n; + unsigned long r[34]; /* Lo, Hi in r[33] and r[34] */ +} psxGPRRegs; + +typedef union { + struct { + unsigned long Index, Random, EntryLo0, EntryLo1, + Context, PageMask, Wired, Reserved0, + BadVAddr, Count, EntryHi, Compare, + Status, Cause, EPC, PRid, + Config, LLAddr, WatchLO, WatchHI, + XContext, Reserved1, Reserved2, Reserved3, + Reserved4, Reserved5, ECC, CacheErr, + TagLo, TagHi, ErrorEPC, Reserved6; + } n; + unsigned long r[32]; +} psxCP0Regs; + +typedef struct { + short x, y; +} SVector2D; + +typedef struct { + short z, pad; +} SVector2Dz; + +typedef struct { + short x, y, z, pad; +} SVector3D; + +typedef struct { + short x, y, z, pad; +} LVector3D; + +typedef struct { + unsigned char r, g, b, c; +} CBGR; + +typedef struct { + short m11, m12, m13, m21, m22, m23, m31, m32, m33, pad; +} SMatrix3D; + +typedef union { + struct { + SVector3D v0, v1, v2; + CBGR rgb; + long otz; + long ir0, ir1, ir2, ir3; + SVector2D sxy0, sxy1, sxy2, sxyp; + SVector2Dz sz0, sz1, sz2, sz3; + CBGR rgb0, rgb1, rgb2; + long reserved; + long mac0, mac1, mac2, mac3; + unsigned long irgb, orgb; + long lzcs, lzcr; + } n; + unsigned long r[32]; +} psxCP2Data; + +typedef union { + struct { + SMatrix3D rMatrix; + long trX, trY, trZ; + SMatrix3D lMatrix; + long rbk, gbk, bbk; + SMatrix3D cMatrix; + long rfc, gfc, bfc; + long ofx, ofy; + long h; + long dqa, dqb; + long zsf3, zsf4; + long flag; + } n; + unsigned long r[32]; +} psxCP2Ctrl; + +typedef struct { + psxGPRRegs GPR; /* General Purpose Registers */ + psxCP0Regs CP0; /* Coprocessor0 Registers */ + psxCP2Data CP2D; /* Cop2 data registers */ + psxCP2Ctrl CP2C; /* Cop2 control registers */ + u32 pc; /* Program counter */ + u32 code; /* The instruction */ + u32 cycle; + u32 interrupt; + u32 intCycle[32]; +} psxRegisters; + +psxRegisters psxRegs; + +#define _i32(x) (long)x +#define _u32(x) x + +#define _i16(x) (short)x +#define _u16(x) (unsigned short)x + +#define _i8(x) (char)x +#define _u8(x) (unsigned char)x + +/**** R3000A Instruction Macros ****/ +#define _PC_ psxRegs.pc // The next PC to be executed + +#define _Funct_ ((psxRegs.code ) & 0x3F) // The funct part of the instruction register +#define _Rd_ ((psxRegs.code >> 11) & 0x1F) // The rd part of the instruction register +#define _Rt_ ((psxRegs.code >> 16) & 0x1F) // The rt part of the instruction register +#define _Rs_ ((psxRegs.code >> 21) & 0x1F) // The rs part of the instruction register +#define _Sa_ ((psxRegs.code >> 6) & 0x1F) // The sa part of the instruction register +#define _Im_ ((u16)psxRegs.code) // The immediate part of the instruction register +#define _Target_ (psxRegs.code & 0x03ffffff) // The target part of the instruction register + +#define _Imm_ ((s16)psxRegs.code) // sign-extended immediate +#define _ImmU_ (psxRegs.code&0xffff) // zero-extended immediate + +#define _rRs_ psxRegs.GPR.r[_Rs_] // Rs register +#define _rRt_ psxRegs.GPR.r[_Rt_] // Rt register +#define _rRd_ psxRegs.GPR.r[_Rd_] // Rd register +#define _rSa_ psxRegs.GPR.r[_Sa_] // Sa register +#define _rFs_ psxRegs.CP0.r[_Rd_] // Fs register + +#define _c2dRs_ psxRegs.CP2D.r[_Rs_] // Rs cop2 data register +#define _c2dRt_ psxRegs.CP2D.r[_Rt_] // Rt cop2 data register +#define _c2dRd_ psxRegs.CP2D.r[_Rd_] // Rd cop2 data register +#define _c2dSa_ psxRegs.CP2D.r[_Sa_] // Sa cop2 data register + +#define _rHi_ psxRegs.GPR.n.hi // The HI register +#define _rLo_ psxRegs.GPR.n.lo // The LO register + +#define _JumpTarget_ ((_Target_ * 4) + (_PC_ & 0xf0000000)) // Calculates the target during a jump instruction +#define _BranchTarget_ ((s16)_Im_ * 4 + _PC_) // Calculates the target during a branch instruction + +#define _SetLink(x) psxRegs.GPR.r[x] = _PC_ + 4; // Sets the return address in the link register + +int psxInit(); +void psxReset(); +void psxShutdown(); +void psxException(u32 code, u32 bd); +void psxBranchTest(); +void psxExecuteBios(); + +#endif /* __R3000A_H__ */ diff --git a/PcsxSrc/Sio.c b/PcsxSrc/Sio.c new file mode 100644 index 0000000..36f09b8 --- /dev/null +++ b/PcsxSrc/Sio.c @@ -0,0 +1,577 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include + +#include "PsxCommon.h" + +#ifdef __WIN32__ +#pragma warning(disable:4244) +#endif + +// *** FOR WORKS ON PADS AND MEMORY CARDS ***** + +static unsigned char buf[256]; +unsigned char cardh[4] = { 0x00, 0x00, 0x5a, 0x5d }; + +//static unsigned short StatReg = 0x002b; +// Transfer(?) Ready and the Buffer is Empty +unsigned short StatReg = TX_RDY | TX_EMPTY; +unsigned short ModeReg; +unsigned short CtrlReg; +unsigned short BaudReg; + +static unsigned long bufcount; +static unsigned long parp; +static unsigned long mcdst,rdwr; +static unsigned char adrH,adrL; +static unsigned long padst; + +PadDataS pad; + +char Mcd1Data[MCD_SIZE], Mcd2Data[MCD_SIZE]; + +// clk cycle byte +// 4us * 8bits = ((PSXCLK / 1000000) * 32) / BIAS; (linuzappz) +#define SIO_INT() { \ + if (!Config.Sio) { \ + psxRegs.interrupt |= 0x80; \ + psxRegs.intCycle[7+1] = 200; /*270;*/ \ + psxRegs.intCycle[7] = psxRegs.cycle; \ + } \ +} + +unsigned char sioRead8() { + unsigned char ret = 0; + + if ((StatReg & RX_RDY)/* && (CtrlReg & RX_PERM)*/) { +// StatReg &= ~RX_OVERRUN; + ret = buf[parp]; + if (parp == bufcount) { + StatReg &= ~RX_RDY; // Receive is not Ready now? + StatReg |= TX_EMPTY; // Buffer is Empty + if (mcdst == 5) { + mcdst = 0; + if (rdwr == 2) { + switch (CtrlReg&0x2002) { + case 0x0002: + memcpy(Mcd1Data + (adrL | (adrH << 8)) * 128, &buf[1], 128); + SaveMcd(Config.Mcd1, Mcd1Data, (adrL | (adrH << 8)) * 128, 128); + break; + case 0x2002: + memcpy(Mcd2Data + (adrL | (adrH << 8)) * 128, &buf[1], 128); + SaveMcd(Config.Mcd2, Mcd2Data, (adrL | (adrH << 8)) * 128, 128); + break; + } + } + } + if (padst == 2) padst = 0; + if (mcdst == 1) { + mcdst = 2; + StatReg&= ~TX_EMPTY; + StatReg|= RX_RDY; + } + } + } + +#ifdef PAD_LOG + PAD_LOG("sio read8 ;ret = %x\n", ret); +#endif + return ret; +} + +void sioWrite8(unsigned char value) { +#ifdef PAD_LOG + PAD_LOG("sio write8 %x\n", value); +#endif + switch (padst) { + case 1: SIO_INT(); + if ((value&0x40) == 0x40) { + padst = 2; parp = 1; + switch (CtrlReg&0x2002) { + case 0x0002: + buf[parp] = PAD1_poll(value); + break; + case 0x2002: + buf[parp] = PAD2_poll(value); + break; + } + if (!(buf[parp] & 0x0f)) { + bufcount = 2 + 32; + } else { + bufcount = 2 + (buf[parp] & 0x0f) * 2; + } + if (buf[parp] == 0x41) { + switch (value) { + case 0x43: + buf[1] = 0x43; + break; + case 0x45: + buf[1] = 0xf3; + break; + } + } + } + else padst = 0; + return; + case 2: + parp++; +/* if (buf[1] == 0x45) { + buf[parp] = 0; + SIO_INT(); + return; + }*/ + switch (CtrlReg&0x2002) { + case 0x0002: buf[parp] = PAD1_poll(value); break; + case 0x2002: buf[parp] = PAD2_poll(value); break; + } + if (parp == bufcount) { padst = 0; return; } + SIO_INT(); + return; + } + + switch (mcdst) { + case 1: + SIO_INT(); + if (rdwr) { parp++; return; } + parp = 1; + switch (value) { + case 0x52: rdwr = 1; break; + case 0x57: rdwr = 2; break; + default: mcdst = 0; + } + return; + case 2: // address H + SIO_INT(); + adrH = value; + *buf = 0; + parp = 0; + bufcount = 1; + mcdst = 3; + return; + case 3: // address L + SIO_INT(); + adrL = value; + *buf = adrH; + parp = 0; + bufcount = 1; + mcdst = 4; + return; + case 4: + SIO_INT(); + parp = 0; + switch (rdwr) { + case 1: // read + buf[0] = 0x5c; + buf[1] = 0x5d; + buf[2] = adrH; + buf[3] = adrL; + switch (CtrlReg&0x2002) { + case 0x0002: + memcpy(&buf[4], Mcd1Data + (adrL | (adrH << 8)) * 128, 128); + break; + case 0x2002: + memcpy(&buf[4], Mcd2Data + (adrL | (adrH << 8)) * 128, 128); + break; + } + { + char xor = 0; + int i; + for (i=2;i<128+4;i++) + xor^=buf[i]; + buf[132] = xor; + } + buf[133] = 0x47; + bufcount = 133; + break; + case 2: // write + buf[0] = adrL; + buf[1] = value; + buf[129] = 0x5c; + buf[130] = 0x5d; + buf[131] = 0x47; + bufcount = 131; + break; + } + mcdst = 5; + return; + case 5: + parp++; + if (rdwr == 2) { + if (parp < 128) buf[parp+1] = value; + } + SIO_INT(); + return; + } + + switch (value) { + case 0x01: // start pad + StatReg &= ~TX_EMPTY; // Now the Buffer is not empty + StatReg |= RX_RDY; // Transfer is Ready + + switch (CtrlReg&0x2002) { + case 0x0002: buf[0] = PAD1_startPoll(1); break; + case 0x2002: buf[0] = PAD2_startPoll(2); break; + } + + bufcount = 2; + parp = 0; + padst = 1; + SIO_INT(); + return; + case 0x81: // start memcard + StatReg &= ~TX_EMPTY; + StatReg |= RX_RDY; + memcpy(buf, cardh, 4); + parp = 0; + bufcount = 3; + mcdst = 1; + rdwr = 0; + SIO_INT(); + return; + } +} + +void sioWriteCtrl16(unsigned short value) { + CtrlReg = value & ~RESET_ERR; + if (value & RESET_ERR) StatReg &= ~IRQ; + if ((CtrlReg & SIO_RESET) || (!CtrlReg)) { + padst = 0; mcdst = 0; parp = 0; + StatReg = TX_RDY | TX_EMPTY; + psxRegs.interrupt&=~0x80; + } +} + +void sioInterrupt() { +#ifdef PAD_LOG + PAD_LOG("Sio Interrupt\n"); +#endif + StatReg|= IRQ; + psxHu32(0x1070)|=0x80; +} + +void LoadMcd(int mcd, char *str) { + FILE *f; + char *data = NULL; + + if (mcd == 1) data = Mcd1Data; + if (mcd == 2) data = Mcd2Data; + + if (*str == 0) sprintf(str, "memcards/Mcd00%d.mcr", mcd); + f = fopen(str, "rb"); + if (f == NULL) { + CreateMcd(str); + f = fopen(str, "rb"); + if (f != NULL) { + struct stat buf; + + if (stat(str, &buf) != -1) { + if (buf.st_size == MCD_SIZE + 64) + fseek(f, 64, SEEK_SET); + else if(buf.st_size == MCD_SIZE + 3904) + fseek(f, 3904, SEEK_SET); + } + fread(data, 1, MCD_SIZE, f); + fclose(f); + } + else SysMessage ("Failed loading MemCard %s\n", str); + } + else { + struct stat buf; + + if (stat(str, &buf) != -1) { + if (buf.st_size == MCD_SIZE + 64) + fseek(f, 64, SEEK_SET); + else if(buf.st_size == MCD_SIZE + 3904) + fseek(f, 3904, SEEK_SET); + } + fread(data, 1, MCD_SIZE, f); + fclose(f); + } +} + +void LoadMcds(char *mcd1, char *mcd2) { + LoadMcd(1, mcd1); + LoadMcd(2, mcd2); +} + +void SaveMcd(char *mcd, char *data, unsigned long adr, int size) { + FILE *f; + + f = fopen(mcd, "r+b"); + if (f != NULL) { + struct stat buf; + + if (stat(mcd, &buf) != -1) { + if (buf.st_size == MCD_SIZE + 64) + fseek(f, adr + 64, SEEK_SET); + else if (buf.st_size == MCD_SIZE + 3904) + fseek(f, adr + 3904, SEEK_SET); + else + fseek(f, adr, SEEK_SET); + } else fseek(f, adr, SEEK_SET); + + fwrite(data + adr, 1, size, f); + fclose(f); + return; + } + + // try to create it again if we can't open it + /*f = fopen(mcd, "wb"); + if (f != NULL) { + fwrite(data, 1, MCD_SIZE, f); + fclose(f); + }*/ + ConvertMcd(mcd, data); +} + +void CreateMcd(char *mcd) { + FILE *f; + struct stat buf; + int s = MCD_SIZE; + int i=0; + strlwr(mcd); + + f = fopen(mcd, "wb"); + if (f == NULL) return; + + if(stat(mcd, &buf)!=-1) { + if ((buf.st_size == MCD_SIZE + 3904) || strstr(mcd, ".gme")) { + s = s + 3904; + fputc('1', f); s--; + fputc('2', f); s--; + fputc('3', f); s--; + fputc('-', f); s--; + fputc('4', f); s--; + fputc('5', f); s--; + fputc('6', f); s--; + fputc('-', f); s--; + fputc('S', f); s--; + fputc('T', f); s--; + fputc('D', f); s--; + for(i=0;i<7;i++) { + fputc(0, f); s--; + } + fputc(1, f); s--; + fputc(0, f); s--; + fputc(1, f); s--; + fputc('M', f); s--; + fputc('Q', f); s--; + for(i=0;i<14;i++) { + fputc(0xa0, f); s--; + } + fputc(0, f); s--; + fputc(0xff, f); + while (s-- > (MCD_SIZE+1)) fputc(0, f); + } else if ((buf.st_size == MCD_SIZE + 64) || strstr(mcd, ".mem") || strstr(mcd, ".vgs")) { + s = s + 64; + fputc('V', f); s--; + fputc('g', f); s--; + fputc('s', f); s--; + fputc('M', f); s--; + for(i=0;i<3;i++) { + fputc(1, f); s--; + fputc(0, f); s--; + fputc(0, f); s--; + fputc(0, f); s--; + } + fputc(0, f); s--; + fputc(2, f); + while (s-- > (MCD_SIZE+1)) fputc(0, f); + } + } + fputc('M', f); s--; + fputc('C', f); s--; + while (s-- > (MCD_SIZE-127)) fputc(0, f); + fputc(0xe, f); s--; + while ((s--)>=0) + fputc(0, f); + fclose(f); +} + +void ConvertMcd(char *mcd, char *data) { + FILE *f; + int i=0; + int s = MCD_SIZE; + strlwr(mcd); + + if (strstr(mcd, ".gme")) { + f = fopen(mcd, "wb"); + if (f != NULL) { + fwrite(data-3904, 1, MCD_SIZE+3904, f); + fclose(f); + } + f = fopen(mcd, "r+"); + s = s + 3904; + fputc('1', f); s--; + fputc('2', f); s--; + fputc('3', f); s--; + fputc('-', f); s--; + fputc('4', f); s--; + fputc('5', f); s--; + fputc('6', f); s--; + fputc('-', f); s--; + fputc('S', f); s--; + fputc('T', f); s--; + fputc('D', f); s--; + for(i=0;i<7;i++) { + fputc(0, f); s--; + } + fputc(1, f); s--; + fputc(0, f); s--; + fputc(1, f); s--; + fputc('M', f); s--; + fputc('Q', f); s--; + for(i=0;i<14;i++) { + fputc(0xa0, f); s--; + } + fputc(0, f); s--; + fputc(0xff, f); + while (s-- > (MCD_SIZE+1)) fputc(0, f); + fclose(f); + } else if(strstr(mcd, ".mem") || strstr(mcd,".vgs")) { + f = fopen(mcd, "wb"); + if (f != NULL) { + fwrite(data-64, 1, MCD_SIZE+64, f); + fclose(f); + } + f = fopen(mcd, "r+"); + s = s + 64; + fputc('V', f); s--; + fputc('g', f); s--; + fputc('s', f); s--; + fputc('M', f); s--; + for(i=0;i<3;i++) { + fputc(1, f); s--; + fputc(0, f); s--; + fputc(0, f); s--; + fputc(0, f); s--; + } + fputc(0, f); s--; + fputc(2, f); + while (s-- > (MCD_SIZE+1)) fputc(0, f); + fclose(f); + } else { + f = fopen(mcd, "wb"); + if (f != NULL) { + fwrite(data, 1, MCD_SIZE, f); + fclose(f); + } + } +} + +void GetMcdBlockInfo(int mcd, int block, McdBlock *Info) { + unsigned char *data = NULL, *ptr, *str; + unsigned short clut[16]; + unsigned short c; + int i, x; + + memset(Info, 0, sizeof(McdBlock)); + + str = Info->Title; + + if (mcd == 1) data = Mcd1Data; + if (mcd == 2) data = Mcd2Data; + + ptr = data + block * 8192 + 2; + + Info->IconCount = *ptr & 0x3; + + ptr+= 2; + + i=0; + + for (i=0; i < 48; i++) { + c = *(ptr) << 8; + c|= *(ptr+1); + if (!c) break; + + + if (c >= 0x8281 && c <= 0x8298) + c = (c - 0x8281) + 'a'; + else if (c >= 0x824F && c <= 0x827A) + c = (c - 0x824F) + '0'; + else if (c == 0x8144) c = '.'; + else if (c == 0x8146) c = ':'; + else if (c == 0x8168) c = '"'; + else if (c == 0x8169) c = '('; + else if (c == 0x816A) c = ')'; + else if (c == 0x816D) c = '['; + else if (c == 0x816E) c = ']'; + else if (c == 0x817C) c = '-'; + else { + c = ' '; + } + + str[i] = c; + ptr+=2; + } + str[i] = 0; + + ptr = data + block * 8192 + 0x60; // icon palete data + + for (i=0; i<16; i++) { + clut[i] = *((unsigned short*)ptr); + ptr+=2; + } + + for (i=0; iIconCount; i++) { + short *icon = &Info->Icon[i*16*16]; + + ptr = data + block * 8192 + 128 + 128 * i; // icon data + + for (x=0; x<16*16; x++) { + icon[x++] = clut[*ptr & 0xf]; + icon[x] = clut[*ptr >> 4]; + ptr++; + } + } + + ptr = data + block * 128; + + Info->Flags = *ptr; + + ptr+= 0xa; + strncpy(Info->ID, ptr, 12); + Info->ID[12] = 0; + ptr+= 12; + strcpy(Info->Name, ptr); +} + +int sioFreeze(gzFile f, int Mode) { + char Unused[4096]; + + gzfreezel(buf); + gzfreezel(&StatReg); + gzfreezel(&ModeReg); + gzfreezel(&CtrlReg); + gzfreezel(&BaudReg); + gzfreezel(&bufcount); + gzfreezel(&parp); + gzfreezel(&mcdst); + gzfreezel(&rdwr); + gzfreezel(&adrH); + gzfreezel(&adrL); + gzfreezel(&padst); + gzfreezel(Unused); + + return 0; +} diff --git a/PcsxSrc/Sio.h b/PcsxSrc/Sio.h new file mode 100644 index 0000000..d458609 --- /dev/null +++ b/PcsxSrc/Sio.h @@ -0,0 +1,76 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _SIO_H_ +#define _SIO_H_ + +#define MCD_SIZE (1024 * 8 * 16) + +// Status Flags +#define TX_RDY 0x0001 +#define RX_RDY 0x0002 +#define TX_EMPTY 0x0004 +#define PARITY_ERR 0x0008 +#define RX_OVERRUN 0x0010 +#define FRAMING_ERR 0x0020 +#define SYNC_DETECT 0x0040 +#define DSR 0x0080 +#define CTS 0x0100 +#define IRQ 0x0200 + +// Control Flags +#define TX_PERM 0x0001 +#define DTR 0x0002 +#define RX_PERM 0x0004 +#define BREAK 0x0008 +#define RESET_ERR 0x0010 +#define RTS 0x0020 +#define SIO_RESET 0x0040 + +extern unsigned short StatReg; +extern unsigned short ModeReg; +extern unsigned short CtrlReg; +extern unsigned short BaudReg; + +extern char Mcd1Data[MCD_SIZE], Mcd2Data[MCD_SIZE]; + +unsigned char sioRead8(); +void sioWrite8(unsigned char value); +void sioWriteCtrl16(unsigned short value); +void sioInterrupt(); +int sioFreeze(gzFile f, int Mode); + +void LoadMcd(int mcd, char *str); +void LoadMcds(char *mcd1, char *mcd2); +void SaveMcd(char *mcd, char *data, unsigned long adr, int size); +void CreateMcd(char *mcd); +void ConvertMcd(char *mcd, char *data); + +typedef struct { + char Title[48]; + char ID[14]; + char Name[16]; + int IconCount; + short Icon[16*16*3]; + unsigned char Flags; +} McdBlock; + +void GetMcdBlockInfo(int mcd, int block, McdBlock *info); + +#endif diff --git a/PcsxSrc/Spu.c b/PcsxSrc/Spu.c new file mode 100644 index 0000000..1ecae13 --- /dev/null +++ b/PcsxSrc/Spu.c @@ -0,0 +1,23 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "PsxCommon.h" + +void CALLBACK SPUirq(void) { + psxHu32(0x1070)|=0x200; +} diff --git a/PcsxSrc/Spu.h b/PcsxSrc/Spu.h new file mode 100644 index 0000000..ea620ca --- /dev/null +++ b/PcsxSrc/Spu.h @@ -0,0 +1,36 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __SPU_H__ +#define __SPU_H__ + +#include "plugins.h" + +#define H_SPUirqAddr 0x0da4 +#define H_SPUaddr 0x0da6 +#define H_SPUdata 0x0da8 +#define H_SPUctrl 0x0daa +#define H_SPUstat 0x0dae +#define H_SPUon1 0x0d88 +#define H_SPUon2 0x0d8a +#define H_SPUoff1 0x0d8c +#define H_SPUoff2 0x0d8e + +void CALLBACK SPUirq(void); + +#endif /* __SPU_H__ */ diff --git a/PcsxSrc/System.h b/PcsxSrc/System.h new file mode 100644 index 0000000..383ca58 --- /dev/null +++ b/PcsxSrc/System.h @@ -0,0 +1,34 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __SYSTEM_H__ +#define __SYSTEM_H__ + +int SysInit(); // Init mem and plugins +void SysReset(); // Resets mem +void SysPrintf(char *fmt, ...); // Printf used by bios syscalls +void SysMessage(char *fmt, ...); // Message used to print msg to users +void *SysLoadLibrary(char *lib); // Loads Library +void *SysLoadSym(void *lib, char *sym); // Loads Symbol from Library +char *SysLibError(); // Gets previous error loading sysbols +void SysCloseLibrary(void *lib); // Closes Library +void SysUpdate(); // Called on VBlank (to update i.e. pads) +void SysRunGui(); // Returns to the Gui +void SysClose(); // Close mem and plugins + +#endif /* __SYSTEM_H__ */ diff --git a/PcsxSrc/Win32/AboutDlg.c b/PcsxSrc/Win32/AboutDlg.c new file mode 100644 index 0000000..0a93fae --- /dev/null +++ b/PcsxSrc/Win32/AboutDlg.c @@ -0,0 +1,44 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include "resource.h" +#include "AboutDlg.h" + +LRESULT WINAPI AboutDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch(uMsg) + { + case WM_INITDIALOG: + { + Static_SetText(GetDlgItem(hDlg, IDC_PCSX_ABOUT_TEXT), "P©SX EMU\nVersion " PCSX_VERSION); + return TRUE; + } + + case WM_COMMAND: + switch(wParam) + { + case IDOK: + EndDialog(hDlg, TRUE ); + return TRUE; + } + break; + } + return FALSE; +} diff --git a/PcsxSrc/Win32/AboutDlg.h b/PcsxSrc/Win32/AboutDlg.h new file mode 100644 index 0000000..4c71245 --- /dev/null +++ b/PcsxSrc/Win32/AboutDlg.h @@ -0,0 +1,24 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _PCSX_ABOUTDLG_H_ +#define _PCSX_ABOUTDLG_H_ + +LRESULT WINAPI AboutDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + +#endif \ No newline at end of file diff --git a/PcsxSrc/Win32/Cdrom02.ico b/PcsxSrc/Win32/Cdrom02.ico new file mode 100644 index 0000000..7a7038b Binary files /dev/null and b/PcsxSrc/Win32/Cdrom02.ico differ diff --git a/PcsxSrc/Win32/ConfigurePlugins.c b/PcsxSrc/Win32/ConfigurePlugins.c new file mode 100644 index 0000000..5399dc1 --- /dev/null +++ b/PcsxSrc/Win32/ConfigurePlugins.c @@ -0,0 +1,471 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include "PsxCommon.h" +#include "plugin.h" +#include "resource.h" +#include "Win32.h" + +#define QueryKeyV(s, name, var) \ + size = s; \ + if (RegQueryValueEx(myKey, name, 0, &type, (LPBYTE) var, &size) != 0) { if (err) { RegCloseKey(myKey); return -1; } } + +#define SetKeyV(name, var, s, t) \ + RegSetValueEx(myKey, name, 0, t, (LPBYTE) var, s); + +int LoadConfig() { + HKEY myKey; + DWORD type,size; + PcsxConfig *Conf = &Config; + int err; + + if (RegOpenKeyEx(HKEY_CURRENT_USER,"Software\\Pcsx",0,KEY_ALL_ACCESS,&myKey)!=ERROR_SUCCESS) return -1; + + err = 1; + QueryKeyV(256, "Bios", Conf->Bios); + QueryKeyV(256, "Gpu", Conf->Gpu); + QueryKeyV(256, "Spu", Conf->Spu); + QueryKeyV(256, "Cdr", Conf->Cdr); + QueryKeyV(256, "Pad1", Conf->Pad1); + QueryKeyV(256, "Pad2", Conf->Pad2); + QueryKeyV(256, "Mcd1", Conf->Mcd1); + QueryKeyV(256, "Mcd2", Conf->Mcd2); + QueryKeyV(256, "PluginsDir", Conf->PluginsDir); + QueryKeyV(256, "BiosDir", Conf->BiosDir); + err = 0; + QueryKeyV(sizeof(Conf->Xa), "Xa", &Conf->Xa); + QueryKeyV(sizeof(Conf->Sio), "Sio", &Conf->Sio); + QueryKeyV(sizeof(Conf->Mdec), "Mdec", &Conf->Mdec); + QueryKeyV(sizeof(Conf->PsxAuto), "PsxAuto", &Conf->PsxAuto); + QueryKeyV(sizeof(Conf->PsxType), "PsxType", &Conf->PsxType); + QueryKeyV(sizeof(Conf->QKeys), "QKeys", &Conf->QKeys); + QueryKeyV(sizeof(Conf->Cdda), "Cdda", &Conf->Cdda); + QueryKeyV(sizeof(Conf->Cpu), "Cpu", &Conf->Cpu); + QueryKeyV(sizeof(Conf->PsxOut), "PsxOut", &Conf->PsxOut); + QueryKeyV(sizeof(Conf->SpuIrq), "SpuIrq", &Conf->SpuIrq); + QueryKeyV(sizeof(Conf->CdTiming),"CdTiming",&Conf->CdTiming); + + RegCloseKey(myKey); + + return 0; +} + +///////////////////////////////////////////////////////// + +void SaveConfig() { + HKEY myKey; + DWORD myDisp; + PcsxConfig *Conf = &Config; + + RegCreateKeyEx(HKEY_CURRENT_USER,"Software\\Pcsx",0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&myKey,&myDisp); + + SetKeyV("Bios", Conf->Bios, strlen(Conf->Bios), REG_SZ); + SetKeyV("Gpu", Conf->Gpu, strlen(Conf->Gpu), REG_SZ); + SetKeyV("Spu", Conf->Spu, strlen(Conf->Spu), REG_SZ); + SetKeyV("Cdr", Conf->Cdr, strlen(Conf->Cdr), REG_SZ); + SetKeyV("Pad1", Conf->Pad1, strlen(Conf->Pad1), REG_SZ); + SetKeyV("Pad2", Conf->Pad2, strlen(Conf->Pad2), REG_SZ); + SetKeyV("Mcd1", Conf->Mcd1, strlen(Conf->Mcd1), REG_SZ); + SetKeyV("Mcd2", Conf->Mcd2, strlen(Conf->Mcd2), REG_SZ); + SetKeyV("PluginsDir", Conf->PluginsDir, strlen(Conf->PluginsDir), REG_SZ); + SetKeyV("BiosDir", Conf->BiosDir, strlen(Conf->BiosDir), REG_SZ); + SetKeyV("Xa", &Conf->Xa, sizeof(Conf->Xa), REG_DWORD); + SetKeyV("Sio", &Conf->Sio, sizeof(Conf->Sio), REG_DWORD); + SetKeyV("Mdec", &Conf->Mdec, sizeof(Conf->Mdec), REG_DWORD); + SetKeyV("PsxAuto", &Conf->PsxAuto, sizeof(Conf->PsxAuto), REG_DWORD); + SetKeyV("PsxType", &Conf->PsxType, sizeof(Conf->PsxType), REG_DWORD); + SetKeyV("QKeys", &Conf->QKeys, sizeof(Conf->QKeys), REG_DWORD); + SetKeyV("Cdda", &Conf->Cdda, sizeof(Conf->Cdda), REG_DWORD); + SetKeyV("Cpu", &Conf->Cpu, sizeof(Conf->Cpu), REG_DWORD); + SetKeyV("PsxOut", &Conf->PsxOut, sizeof(Conf->PsxOut), REG_DWORD); + SetKeyV("SpuIrq", &Conf->SpuIrq, sizeof(Conf->SpuIrq), REG_DWORD); + SetKeyV("CdTiming",&Conf->CdTiming,sizeof(Conf->SpuIrq), REG_DWORD); + + RegCloseKey(myKey); +} + +///////////////////////////////////////////////////////// + +#define ComboAddPlugin(hw, str) { \ + lp = (char *)malloc(strlen(FindData.cFileName)+8); \ + sprintf(lp, "%s", FindData.cFileName); \ + i = ComboBox_AddString(hw, tmpStr); \ + ComboBox_SetItemData(hw, i, lp); \ + if (stricmp(str, lp)==0) \ + ComboBox_SetCurSel(hw, i); \ +} + +BOOL OnConfigurePluginsDialog(HWND hW) { + WIN32_FIND_DATA FindData; + HANDLE Find; + HANDLE Lib; + PSEgetLibType PSE_GetLibType; + PSEgetLibName PSE_GetLibName; + PSEgetLibVersion PSE_GetLibVersion; + HWND hWC_GPU=GetDlgItem(hW,IDC_LISTGPU); + HWND hWC_SPU=GetDlgItem(hW,IDC_LISTSPU); + HWND hWC_CDR=GetDlgItem(hW,IDC_LISTCDR); + HWND hWC_PAD1=GetDlgItem(hW,IDC_LISTPAD1); + HWND hWC_PAD2=GetDlgItem(hW,IDC_LISTPAD2); + HWND hWC_BIOS=GetDlgItem(hW,IDC_LISTBIOS); + char tmpStr[256]; + char *lp; + int i; + + strcpy(tmpStr, Config.PluginsDir); + strcat(tmpStr, "*.dll"); + Find = FindFirstFile(tmpStr, &FindData); + + do { + if (Find==INVALID_HANDLE_VALUE) break; + sprintf(tmpStr,"%s%s", Config.PluginsDir, FindData.cFileName); + Lib = LoadLibrary(tmpStr); + if (Lib!=NULL) { + PSE_GetLibType = (PSEgetLibType) GetProcAddress((HMODULE)Lib,"PSEgetLibType"); + PSE_GetLibName = (PSEgetLibName) GetProcAddress((HMODULE)Lib,"PSEgetLibName"); + PSE_GetLibVersion = (PSEgetLibVersion) GetProcAddress((HMODULE)Lib,"PSEgetLibVersion"); + + if (PSE_GetLibType != NULL && PSE_GetLibName != NULL && PSE_GetLibVersion != NULL) { + unsigned long version = PSE_GetLibVersion(); + long type; + + sprintf(tmpStr, "%s %d.%d", PSE_GetLibName(), (version>>8)&0xff, version&0xff); + type = PSE_GetLibType(); + if (type & PSE_LT_CDR) { + ComboAddPlugin(hWC_CDR, Config.Cdr); + } + + if (type & PSE_LT_SPU) { + ComboAddPlugin(hWC_SPU, Config.Spu); + } + + if (type & PSE_LT_GPU) { + ComboAddPlugin(hWC_GPU, Config.Gpu); + } + + if (type & PSE_LT_PAD) { + PADquery query; + + query = (PADquery)GetProcAddress((HMODULE)Lib, "PADquery"); + if (query() & 0x1) + ComboAddPlugin(hWC_PAD1, Config.Pad1); + if (query() & 0x2) + ComboAddPlugin(hWC_PAD2, Config.Pad2); + } + } + } + } while (FindNextFile(Find,&FindData)); + + if (Find!=INVALID_HANDLE_VALUE) FindClose(Find); + +// BIOS + + lp=(char *)malloc(strlen("HLE") + 1); + sprintf(lp, "HLE"); + i=ComboBox_AddString(hWC_BIOS, "Internal HLE Bios"); + ComboBox_SetItemData(hWC_BIOS, i, lp); + if (stricmp(Config.Bios, lp)==0) + ComboBox_SetCurSel(hWC_BIOS, i); + + strcpy(tmpStr, Config.BiosDir); + strcat(tmpStr, "*"); + Find=FindFirstFile(tmpStr, &FindData); + + do { + if (Find==INVALID_HANDLE_VALUE) break; + if (!strcmp(FindData.cFileName, ".")) continue; + if (!strcmp(FindData.cFileName, "..")) continue; + if (FindData.nFileSizeLow != 1024 * 512) continue; + lp = (char *)malloc(strlen(FindData.cFileName)+8); + sprintf(lp, "%s", (char *)FindData.cFileName); + i = ComboBox_AddString(hWC_BIOS, FindData.cFileName); + ComboBox_SetItemData(hWC_BIOS, i, lp); + if (stricmp(Config.Bios, FindData.cFileName)==0) + ComboBox_SetCurSel(hWC_BIOS, i); + } while (FindNextFile(Find,&FindData)); + + if (Find!=INVALID_HANDLE_VALUE) FindClose(Find); + + if (ComboBox_GetCurSel(hWC_CDR ) == -1) + ComboBox_SetCurSel(hWC_CDR, 0); + if (ComboBox_GetCurSel(hWC_GPU ) == -1) + ComboBox_SetCurSel(hWC_GPU, 0); + if (ComboBox_GetCurSel(hWC_SPU ) == -1) + ComboBox_SetCurSel(hWC_SPU, 0); + if (ComboBox_GetCurSel(hWC_PAD1) == -1) + ComboBox_SetCurSel(hWC_PAD1, 0); + if (ComboBox_GetCurSel(hWC_PAD2) == -1) + ComboBox_SetCurSel(hWC_PAD2, 0); + if (ComboBox_GetCurSel(hWC_BIOS) == -1) + ComboBox_SetCurSel(hWC_BIOS, 0); + + return TRUE; +} + +#define CleanCombo(item) \ + hWC = GetDlgItem(hW, item); \ + iCnt = ComboBox_GetCount(hWC); \ + for (i=0; i + +int SelectPath(HWND hW, char *Title, char *Path) { + LPITEMIDLIST pidl; + BROWSEINFO bi; + char Buffer[256]; + + bi.hwndOwner = hW; + bi.pidlRoot = NULL; + bi.pszDisplayName = Buffer; + bi.lpszTitle = Title; + bi.ulFlags = BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS; + bi.lpfn = NULL; + bi.lParam = 0; + if ((pidl = SHBrowseForFolder(&bi)) != NULL) { + if (SHGetPathFromIDList(pidl, Path)) { + int len = strlen(Path); + + if (Path[len - 1] != '\\') { strcat(Path,"\\"); } + return 0; + } + } + return -1; +} + +void SetPluginsDir(HWND hW) { + char Path[256]; + + if (SelectPath(hW, "Select Plugins Directory", Path) == -1) return; + strcpy(Config.PluginsDir, Path); + CleanUpCombos(hW); + OnConfigurePluginsDialog(hW); +} + +void SetBiosDir(HWND hW) { + char Path[256]; + + if (SelectPath(hW, "Select Bios Directory", Path) == -1) return; + strcpy(Config.BiosDir, Path); + CleanUpCombos(hW); + OnConfigurePluginsDialog(hW); +} + +BOOL CALLBACK ConfigurePluginsDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) { + switch(uMsg) { + case WM_INITDIALOG: + return OnConfigurePluginsDialog(hW); + + case WM_COMMAND: + switch(LOWORD(wParam)) { + case IDC_CONFIGGPU: ConfigureGPU(hW); return TRUE; + case IDC_CONFIGSPU: ConfigureSPU(hW); return TRUE; + case IDC_CONFIGCDR: ConfigureCDR(hW); return TRUE; + case IDC_CONFIGPAD1: ConfigurePAD1(hW); return TRUE; + case IDC_CONFIGPAD2: ConfigurePAD2(hW); return TRUE; + + case IDC_TESTGPU: TestGPU(hW); return TRUE; + case IDC_TESTSPU: TestSPU(hW); return TRUE; + case IDC_TESTCDR: TestCDR(hW); return TRUE; + case IDC_TESTPAD1: TestPAD1(hW); return TRUE; + case IDC_TESTPAD2: TestPAD2(hW); return TRUE; + + case IDC_ABOUTGPU: AboutGPU(hW); return TRUE; + case IDC_ABOUTSPU: AboutSPU(hW); return TRUE; + case IDC_ABOUTCDR: AboutCDR(hW); return TRUE; + case IDC_ABOUTPAD1: AboutPAD1(hW); return TRUE; + case IDC_ABOUTPAD2: AboutPAD2(hW); return TRUE; + + case IDC_PLUGINSDIR: SetPluginsDir(hW); return TRUE; + case IDC_BIOSDIR: SetBiosDir(hW); return TRUE; + + case IDCANCEL: OnCancel(hW); return TRUE; + case IDOK: OnOK(hW); return TRUE; + } + } + return FALSE; +} + + +void ConfigurePlugins(HWND hWnd) { + DialogBox(gApp.hInstance, + MAKEINTRESOURCE(IDD_CONFIG), + hWnd, + (DLGPROC)ConfigurePluginsDlgProc); +} + diff --git a/PcsxSrc/Win32/Win32.h b/PcsxSrc/Win32/Win32.h new file mode 100644 index 0000000..77954ad --- /dev/null +++ b/PcsxSrc/Win32/Win32.h @@ -0,0 +1,48 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __WIN32_H__ +#define __WIN32_H__ + +AppData gApp; +HANDLE hConsole; + +long LoadCdBios; +extern int StatesC; +extern int AccBreak; +extern int NeedReset; +extern int ConfPlug; +int Running; +char PcsxDir[256]; + +LRESULT WINAPI MainWndProc(HWND, UINT, WPARAM, LPARAM); +BOOL CALLBACK ConfigureMcdsDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam); +BOOL CALLBACK ConfigureCpuDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam); + +void ConfigurePlugins(HWND hWnd); + +int Open_File_Proc(char *file); +void Open_Mcd_Proc(HWND hW, int MCDID); +void CreateMainWindow(int nCmdShow); +void RunGui(); +void PADhandleKey(int key); + +int LoadConfig(); +void SaveConfig(); + +#endif /* __WIN32_H__ */ \ No newline at end of file diff --git a/PcsxSrc/Win32/WndMain.c b/PcsxSrc/Win32/WndMain.c new file mode 100644 index 0000000..eaeab13 --- /dev/null +++ b/PcsxSrc/Win32/WndMain.c @@ -0,0 +1,1044 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "resource.h" +#include "AboutDlg.h" + +#include "PsxCommon.h" +#include "plugin.h" +#include "Debug.h" +#include "Win32.h" + +int AccBreak=0; +int ConfPlug=0; +int StatesC=0; +int NeedReset=1; +int cdOpenCase=0; + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { + gApp.hInstance = hInstance; + + Running=0; + + GetCurrentDirectory(256, PcsxDir); + + memset(&Config, 0, sizeof(PcsxConfig)); + if (LoadConfig() == -1) { + Config.PsxAuto = 1; + strcpy(Config.PluginsDir, "Plugin\\"); + strcpy(Config.BiosDir, "Bios\\"); + SysMessage("Pcsx needs to be configured"); + ConfPlug=1; + ConfigurePlugins(gApp.hWnd); + DialogBox(gApp.hInstance, MAKEINTRESOURCE(IDD_MCDCONF), gApp.hWnd, (DLGPROC)ConfigureMcdsDlgProc); + SysMessage("Pcsx now will quit, restart it"); + return 0; + } + + if (SysInit() == -1) return 1; + + CreateMainWindow(nCmdShow); + + RunGui(); + + return 0; +} + +void RunGui() { + MSG msg; + + PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE); + + for (;;) { + if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } +} + +void OpenConsole() { + if (hConsole) return; + AllocConsole(); + SetConsoleTitle("Psx Output"); + hConsole = GetStdHandle(STD_OUTPUT_HANDLE); +} + +void CloseConsole() { + FreeConsole(); hConsole = NULL; +} + +LRESULT WINAPI MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { + char File[256]; + + switch (msg) { + case WM_COMMAND: + switch (LOWORD(wParam)) { + case ID_FILE_EXIT: + SysClose(); + PostQuitMessage(0); + exit(0); + return TRUE; + + case ID_FILE_RUN_CD: + LoadCdBios = 0; + SetMenu(hWnd, NULL); + OpenPlugins(hWnd); + SysReset(); + NeedReset = 0; + CheckCdrom(); + if (LoadCdrom() == -1) { + ClosePlugins(); + AccBreak = 1; + DestroyWindow(gApp.hWnd); + CreateMainWindow(SW_SHOWNORMAL); + SetMenu(gApp.hWnd, gApp.hMenu); + SetCursor(LoadCursor(gApp.hInstance, IDC_ARROW)); + ShowCursor(TRUE); + SysMessage("Could not load Cdrom\n"); + return TRUE; + } + ShowCursor(FALSE); + Running = 1; + psxCpu->Execute(); + return TRUE; + + case ID_FILE_RUNCDBIOS: + LoadCdBios = 1; + SetMenu(hWnd, NULL); + OpenPlugins(hWnd); + ShowCursor(FALSE); + CheckCdrom(); + SysReset(); + NeedReset = 0; + Running = 1; + psxCpu->Execute(); + return TRUE; + + case ID_FILE_RUN_EXE: + if (!Open_File_Proc(File)) return TRUE; + SetMenu(hWnd, NULL); + OpenPlugins(hWnd); + SysReset(); + NeedReset = 0; + Load(File); + Running = 1; + psxCpu->Execute(); + return TRUE; + + case ID_EMULATOR_RUN: + SetMenu(hWnd, NULL); + OpenPlugins(hWnd); + ShowCursor(FALSE); + if (NeedReset) { SysReset(); NeedReset = 0; } + Running = 1; + psxCpu->Execute(); + return TRUE; + + case ID_EMULATOR_RESET: + NeedReset = 1; + return TRUE; + + case ID_CONFIGURATION_GRAPHICS: + GPU_configure(); + return TRUE; + + case ID_CONFIGURATION_SOUND: + SPU_configure(); + return TRUE; + + case ID_CONFIGURATION_CONTROLLERS: + PAD1_configure(); + if (strcmp(Config.Pad1, Config.Pad2)) PAD2_configure(); + return TRUE; + + case ID_CONFIGURATION_CDROM: + CDR_configure(); + return TRUE; + + case ID_CONFIGURATION_MEMORYCARDMANAGER: + DialogBox(gApp.hInstance, MAKEINTRESOURCE(IDD_MCDCONF), hWnd, (DLGPROC)ConfigureMcdsDlgProc); + return TRUE; + + case ID_CONFIGURATION_CPU: + DialogBox(gApp.hInstance, MAKEINTRESOURCE(IDD_CPUCONF), hWnd, (DLGPROC)ConfigureCpuDlgProc); + return TRUE; + + case ID_CONFIGURATION: + ConfigurePlugins(hWnd); + return TRUE; + + case ID_HELP_HELP: + ShellExecute(NULL, "open", "Readme.txt", NULL, NULL, SW_SHOWNORMAL); + return TRUE; + + case ID_HELP_ABOUT: + DialogBox(gApp.hInstance, MAKEINTRESOURCE(ABOUT_DIALOG), hWnd, (DLGPROC)AboutDlgProc); + return TRUE; + } + break; + + case WM_SYSKEYDOWN: + if (wParam != VK_F10) + return DefWindowProc(hWnd, msg, wParam, lParam); + case WM_KEYDOWN: + PADhandleKey(wParam); + return TRUE; + + case WM_DESTROY: + if (!AccBreak) { + if (Running) ClosePlugins(); + SysClose(); + PostQuitMessage(0); + exit(0); + } + else AccBreak = 0; + + return TRUE; + + case WM_CREATE: + gApp.hMenu = LoadMenu(gApp.hInstance, MAKEINTRESOURCE(IDR_MENU1)); + SetMenu(hWnd, gApp.hMenu); + break; + + case WM_QUIT: + exit(0); + break; + + default: + return DefWindowProc(hWnd, msg, wParam, lParam); + } + + return FALSE; +} + +HWND mcdDlg; +McdBlock Blocks[2][15]; +int IconC[2][15]; +HIMAGELIST Iiml[2]; +HICON eICON; + +void CreateListView(int idc) { + HWND List; + LV_COLUMN col; + + List = GetDlgItem(mcdDlg, idc); + + col.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + col.fmt = LVCFMT_LEFT; + + col.pszText = "Title"; + col.cx = 170; + col.iSubItem = 0; + + ListView_InsertColumn(List, 0, &col); + + col.pszText = "Status"; + col.cx = 50; + col.iSubItem = 1; + + ListView_InsertColumn(List, 1, &col); + + col.pszText = "Game ID"; + col.cx = 90; + col.iSubItem = 2; + + ListView_InsertColumn(List, 2, &col); + + col.pszText = "Game"; + col.cx = 80; + col.iSubItem = 3; + + ListView_InsertColumn(List, 3, &col); +} + +int GetRGB() { + HDC scrDC, memDC; + HBITMAP oldBmp = NULL; + HBITMAP curBmp = NULL; + COLORREF oldColor; + COLORREF curColor = RGB(255,255,255); + int i, R, G, B; + + R = G = B = 1; + + scrDC = CreateDC("DISPLAY", NULL, NULL, NULL); + memDC = CreateCompatibleDC(NULL); + curBmp = CreateCompatibleBitmap(scrDC, 1, 1); + oldBmp = (HBITMAP)SelectObject(memDC, curBmp); + + for (i = 255; i >= 0; --i) { + oldColor = curColor; + curColor = SetPixel(memDC, 0, 0, RGB(i, i, i)); + + if (GetRValue(curColor) < GetRValue(oldColor)) ++R; + if (GetGValue(curColor) < GetGValue(oldColor)) ++G; + if (GetBValue(curColor) < GetBValue(oldColor)) ++B; + } + + DeleteObject(oldBmp); + DeleteObject(curBmp); + DeleteDC(scrDC); + DeleteDC(memDC); + + return (R * G * B); +} + +HICON GetIcon(short *icon) { + ICONINFO iInfo; + HDC hDC; + char mask[16*16]; + int x, y, c, Depth; + + hDC = CreateIC("DISPLAY",NULL,NULL,NULL); + Depth=GetDeviceCaps(hDC, BITSPIXEL); + DeleteDC(hDC); + + if (Depth == 16) { + if (GetRGB() == (32 * 32 * 32)) + Depth = 15; + } + + for (y=0; y<16; y++) { + for (x=0; x<16; x++) { + c = icon[y*16+x]; + if (Depth == 15) + c = ((c&0x001f) << 10) | ((c&0x7c00) >> 10) | (c&0x03e0); + else + c = (c&0x001f) | ((c&0x7c00) << 1) | ((c&0x03e0) << 1); + + icon[y*16+x] = c; + } + } + + iInfo.fIcon = TRUE; + memset(mask, 0, 16*16); + iInfo.hbmMask = CreateBitmap(16, 16, 1, 1, mask); + iInfo.hbmColor = CreateBitmap(16, 16, 1, 16, icon); + + return CreateIconIndirect(&iInfo); +} + +HICON hICON[2][3][15]; +int aIover[2]; +int ani[2]; + +void LoadMcdItems(int mcd, int idc) { + HWND List = GetDlgItem(mcdDlg, idc); + LV_ITEM item; + HIMAGELIST iml = Iiml[mcd-1]; + int i, j; + HICON hIcon; + McdBlock *Info; + + aIover[mcd-1]=0; + ani[mcd-1]=0; + + ListView_DeleteAllItems(List); + + for (i=0; i<15; i++) { + + item.mask = LVIF_TEXT | LVIF_IMAGE; + item.iItem = i; + item.iImage = i; + item.pszText = LPSTR_TEXTCALLBACK; + item.iSubItem = 0; + + IconC[mcd-1][i] = 0; + Info = &Blocks[mcd-1][i]; + + if ((Info->Flags & 0xF) == 1 && Info->IconCount != 0) { + hIcon = GetIcon(Info->Icon); + + if (Info->IconCount > 1) { + for(j = 0; j < 3; j++) + hICON[mcd-1][j][i]=hIcon; + } + } else { + hIcon = eICON; + } + + ImageList_ReplaceIcon(iml, -1, hIcon); + ListView_InsertItem(List, &item); + } +} + +void UpdateMcdItems(int mcd, int idc) { + HWND List = GetDlgItem(mcdDlg, idc); + LV_ITEM item; + HIMAGELIST iml = Iiml[mcd-1]; + int i, j; + McdBlock *Info; + HICON hIcon; + + aIover[mcd-1]=0; + ani[mcd-1]=0; + + for (i=0; i<15; i++) { + + item.mask = LVIF_TEXT | LVIF_IMAGE; + item.iItem = i; + item.iImage = i; + item.pszText = LPSTR_TEXTCALLBACK; + item.iSubItem = 0; + + IconC[mcd-1][i] = 0; + Info = &Blocks[mcd-1][i]; + + if ((Info->Flags & 0xF) == 1 && Info->IconCount != 0) { + hIcon = GetIcon(Info->Icon); + + if (Info->IconCount > 1) { + for(j = 0; j < 3; j++) + hICON[mcd-1][j][i]=hIcon; + } + } else { + hIcon = eICON; + } + + ImageList_ReplaceIcon(iml, i, hIcon); + ListView_SetItem(List, &item); + } + ListView_Update(List, -1); +} + +void McdListGetDispInfo(int mcd, int idc, LPNMHDR pnmh) { + LV_DISPINFO *lpdi = (LV_DISPINFO *)pnmh; + McdBlock *Info; + + Info = &Blocks[mcd-1][lpdi->item.iItem]; + + switch (lpdi->item.iSubItem) { + case 0: + switch (Info->Flags & 0xF) { + case 1: + lpdi->item.pszText = Info->Title; + break; + case 2: + lpdi->item.pszText = "mid link block"; + break; + case 3: + lpdi->item.pszText = "terminiting link block"; + break; + } + break; + case 1: + if ((Info->Flags & 0xF0) == 0xA0) { + if ((Info->Flags & 0xF) >= 1 && + (Info->Flags & 0xF) <= 3) { + lpdi->item.pszText = "Deleted"; + } else lpdi->item.pszText = "Free"; + } else if ((Info->Flags & 0xF0) == 0x50) + lpdi->item.pszText = "Used"; + else { lpdi->item.pszText = "Free"; } + break; + case 2: + if((Info->Flags & 0xF)==1) + lpdi->item.pszText = Info->ID; + break; + case 3: + if((Info->Flags & 0xF)==1) + lpdi->item.pszText = Info->Name; + break; + } +} + +void McdListNotify(int mcd, int idc, LPNMHDR pnmh) { + switch (pnmh->code) { + case LVN_GETDISPINFO: McdListGetDispInfo(mcd, idc, pnmh); break; + } +} + +void UpdateMcdDlg() { + int i; + + for (i=1; i<16; i++) GetMcdBlockInfo(1, i, &Blocks[0][i-1]); + for (i=1; i<16; i++) GetMcdBlockInfo(2, i, &Blocks[1][i-1]); + UpdateMcdItems(1, IDC_LIST1); + UpdateMcdItems(2, IDC_LIST2); +} + +void LoadMcdDlg() { + int i; + + for (i=1; i<16; i++) GetMcdBlockInfo(1, i, &Blocks[0][i-1]); + for (i=1; i<16; i++) GetMcdBlockInfo(2, i, &Blocks[1][i-1]); + LoadMcdItems(1, IDC_LIST1); + LoadMcdItems(2, IDC_LIST2); +} + +void UpdateMcdIcon(int mcd, int idc) { + HWND List = GetDlgItem(mcdDlg, idc); + HIMAGELIST iml = Iiml[mcd-1]; + int i; + McdBlock *Info; + int *count; + + if(!aIover[mcd-1]) { + ani[mcd-1]++; + + for (i=0; i<15; i++) { + Info = &Blocks[mcd-1][i]; + count = &IconC[mcd-1][i]; + + if ((Info->Flags & 0xF) != 1) continue; + if (Info->IconCount <= 1) continue; + + if (*count < Info->IconCount) { + (*count)++; + aIover[mcd-1]=0; + + if(ani[mcd-1] <= (Info->IconCount-1)) // last frame and below... + hICON[mcd-1][ani[mcd-1]][i] = GetIcon(&Info->Icon[(*count)*16*16]); + } else { + aIover[mcd-1]=1; + } + } + + } else { + + if (ani[mcd-1] > 1) ani[mcd-1] = 0; // 1st frame + else ani[mcd-1]++; // 2nd, 3rd frame + + for(i=0;i<15;i++) { +// RECT rect, hrect; + + Info = &Blocks[mcd-1][i]; + + if (((Info->Flags & 0xF) == 1) && (Info->IconCount > 1)) + ImageList_ReplaceIcon(iml, i, hICON[mcd-1][ani[mcd-1]][i]); + +/* GetWindowRect(List, &hrect); + ListView_GetItemRect(List, i, &rect, LVIR_ICON); + rect.left+= hrect.left; rect.right+= hrect.left; + rect.top+= hrect.top; rect.bottom+= hrect.top; + +// rect.left-= 12; rect.right-= 12; // quick fix + + InvalidateRect(mcdDlg, &rect, FALSE);*/ + } + ListView_Update(List, 0); + } +} + +static int copy = 0, copymcd = 0; +static int listsel = 0; + +BOOL CALLBACK ConfigureMcdsDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) { + char str[256]; + LPBYTE lpAND, lpXOR; + LPBYTE lpA, lpX; + int i, j; + + switch(uMsg) { + case WM_INITDIALOG: + mcdDlg = hW; + + lpA=lpAND=(LPBYTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(16*16)); + lpX=lpXOR=(LPBYTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(16*16)); + + for(i=0;i<16;i++) + { + for(j=0;j<16;j++) + { + *lpA++=0xff; + *lpX++=0; + } + } + eICON=CreateIcon(gApp.hInstance,16,16,1,1,lpAND,lpXOR); + + HeapFree(GetProcessHeap(),0,lpAND); + HeapFree(GetProcessHeap(),0,lpXOR); + + if (!strlen(Config.Mcd1)) strcpy(Config.Mcd1, "memcards\\Mcd001.mcr"); + if (!strlen(Config.Mcd2)) strcpy(Config.Mcd2, "memcards\\Mcd002.mcr"); + Edit_SetText(GetDlgItem(hW,IDC_MCD1), Config.Mcd1); + Edit_SetText(GetDlgItem(hW,IDC_MCD2), Config.Mcd2); + + CreateListView(IDC_LIST1); + CreateListView(IDC_LIST2); + + Iiml[0] = ImageList_Create(16, 16, ILC_COLOR16, 0, 0); + Iiml[1] = ImageList_Create(16, 16, ILC_COLOR16, 0, 0); + + ListView_SetImageList(GetDlgItem(mcdDlg, IDC_LIST1), Iiml[0], LVSIL_SMALL); + ListView_SetImageList(GetDlgItem(mcdDlg, IDC_LIST2), Iiml[1], LVSIL_SMALL); + + Button_Enable(GetDlgItem(hW, IDC_PASTE), FALSE); + + LoadMcdDlg(); + + SetTimer(hW, 1, 250, NULL); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDC_COPYTO1: + copy = ListView_GetSelectionMark(GetDlgItem(mcdDlg, IDC_LIST2)); + copymcd = 1; + + Button_Enable(GetDlgItem(hW, IDC_PASTE), TRUE); + return TRUE; + case IDC_COPYTO2: + copy = ListView_GetSelectionMark(GetDlgItem(mcdDlg, IDC_LIST1)); + copymcd = 2; + + Button_Enable(GetDlgItem(hW, IDC_PASTE), TRUE); + return TRUE; + case IDC_PASTE: + if (MessageBox(hW, "Are you sure you want to paste this selection?", "Confirmation", MB_YESNO) == IDNO) return TRUE; + + if (copymcd == 1) { + Edit_GetText(GetDlgItem(hW,IDC_MCD1), str, 256); + i = ListView_GetSelectionMark(GetDlgItem(mcdDlg, IDC_LIST1)); + + // save dir data + save data + memcpy(Mcd1Data + (i+1) * 128, Mcd2Data + (copy+1) * 128, 128); + SaveMcd(str, Mcd1Data, (i+1) * 128, 128); + memcpy(Mcd1Data + (i+1) * 1024 * 8, Mcd2Data + (copy+1) * 1024 * 8, 1024 * 8); + SaveMcd(str, Mcd1Data, (i+1) * 1024 * 8, 1024 * 8); + } else { // 2 + Edit_GetText(GetDlgItem(hW,IDC_MCD2), str, 256); + i = ListView_GetSelectionMark(GetDlgItem(mcdDlg, IDC_LIST2)); + + // save dir data + save data + memcpy(Mcd2Data + (i+1) * 128, Mcd1Data + (copy+1) * 128, 128); + SaveMcd(str, Mcd2Data, (i+1) * 128, 128); + memcpy(Mcd2Data + (i+1) * 1024 * 8, Mcd1Data + (copy+1) * 1024 * 8, 1024 * 8); + SaveMcd(str, Mcd2Data, (i+1) * 1024 * 8, 1024 * 8); + } + + UpdateMcdDlg(); + + return TRUE; + case IDC_DELETE1: + { + McdBlock *Info; + int mcd = 1; + int i, xor = 0, j; + unsigned char *data, *ptr; + + Edit_GetText(GetDlgItem(hW,IDC_MCD1), str, 256); + i = ListView_GetSelectionMark(GetDlgItem(mcdDlg, IDC_LIST1)); + data = Mcd1Data; + + i++; + + ptr = data + i * 128; + + Info = &Blocks[mcd-1][i-1]; + + if ((Info->Flags & 0xF0) == 0xA0) { + if ((Info->Flags & 0xF) >= 1 && + (Info->Flags & 0xF) <= 3) { // deleted + *ptr = 0x50 | (Info->Flags & 0xF); + } else return TRUE; + } else if ((Info->Flags & 0xF0) == 0x50) { // used + *ptr = 0xA0 | (Info->Flags & 0xF); + } else { return TRUE; } + + for (j=0; j<127; j++) xor^=*ptr++; + *ptr = xor; + + SaveMcd(str, data, i * 128, 128); + UpdateMcdDlg(); + } + + return TRUE; + case IDC_DELETE2: + { + McdBlock *Info; + int mcd = 2; + int i, xor = 0, j; + unsigned char *data, *ptr; + + Edit_GetText(GetDlgItem(hW,IDC_MCD2), str, 256); + i = ListView_GetSelectionMark(GetDlgItem(mcdDlg, IDC_LIST2)); + data = Mcd2Data; + + i++; + + ptr = data + i * 128; + + Info = &Blocks[mcd-1][i-1]; + + if ((Info->Flags & 0xF0) == 0xA0) { + if ((Info->Flags & 0xF) >= 1 && + (Info->Flags & 0xF) <= 3) { // deleted + *ptr = 0x50 | (Info->Flags & 0xF); + } else return TRUE; + } else if ((Info->Flags & 0xF0) == 0x50) { // used + *ptr = 0xA0 | (Info->Flags & 0xF); + } else { return TRUE; } + + for (j=0; j<127; j++) xor^=*ptr++; + *ptr = xor; + + SaveMcd(str, data, i * 128, 128); + UpdateMcdDlg(); + } + + return TRUE; + + case IDC_MCDSEL1: + Open_Mcd_Proc(hW, 1); + return TRUE; + case IDC_MCDSEL2: + Open_Mcd_Proc(hW, 2); + return TRUE; + case IDC_RELOAD1: + Edit_GetText(GetDlgItem(hW,IDC_MCD1), str, 256); + LoadMcd(1, str); + UpdateMcdDlg(); + return TRUE; + case IDC_RELOAD2: + Edit_GetText(GetDlgItem(hW,IDC_MCD2), str, 256); + LoadMcd(2, str); + UpdateMcdDlg(); + return TRUE; + case IDC_FORMAT1: + if (MessageBox(hW, "Are you sure you want to format this Memory Card?", "Confirmation", MB_YESNO) == IDNO) return TRUE; + Edit_GetText(GetDlgItem(hW,IDC_MCD1), str, 256); + CreateMcd(str); + LoadMcd(1, str); + UpdateMcdDlg(); + return TRUE; + case IDC_FORMAT2: + if (MessageBox(hW, "Are you sure you want to format this Memory Card?", "Confirmation", MB_YESNO) == IDNO) return TRUE; + Edit_GetText(GetDlgItem(hW,IDC_MCD2), str, 256); + CreateMcd(str); + LoadMcd(2, str); + UpdateMcdDlg(); + return TRUE; + case IDCANCEL: + LoadMcds(Config.Mcd1, Config.Mcd2); + + EndDialog(hW,FALSE); + + return TRUE; + case IDOK: + Edit_GetText(GetDlgItem(hW,IDC_MCD1), Config.Mcd1, 256); + Edit_GetText(GetDlgItem(hW,IDC_MCD2), Config.Mcd2, 256); + + LoadMcds(Config.Mcd1, Config.Mcd2); + SaveConfig(); + + EndDialog(hW,TRUE); + + return TRUE; + } + case WM_NOTIFY: + switch (wParam) { + case IDC_LIST1: McdListNotify(1, IDC_LIST1, (LPNMHDR)lParam); break; + case IDC_LIST2: McdListNotify(2, IDC_LIST2, (LPNMHDR)lParam); break; + } + return TRUE; + case WM_TIMER: + UpdateMcdIcon(1, IDC_LIST1); + UpdateMcdIcon(2, IDC_LIST2); + return TRUE; + case WM_DESTROY: + DestroyIcon(eICON); + //KillTimer(hW, 1); + return TRUE; + } + return FALSE; +} + +BOOL CALLBACK ConfigureCpuDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) { + long tmp; + + switch(uMsg) { + case WM_INITDIALOG: + Button_SetCheck(GetDlgItem(hW,IDC_XA), Config.Xa); + Button_SetCheck(GetDlgItem(hW,IDC_SIO), Config.Sio); + Button_SetCheck(GetDlgItem(hW,IDC_MDEC), Config.Mdec); + Button_SetCheck(GetDlgItem(hW,IDC_QKEYS), Config.QKeys); + Button_SetCheck(GetDlgItem(hW,IDC_CDDA), Config.Cdda); + Button_SetCheck(GetDlgItem(hW,IDC_PSXAUTO), Config.PsxAuto); + Button_SetCheck(GetDlgItem(hW,IDC_CPU), Config.Cpu); + Button_SetCheck(GetDlgItem(hW,IDC_PSXOUT), Config.PsxOut); + Button_SetCheck(GetDlgItem(hW,IDC_SPUIRQ), Config.SpuIrq); + Button_SetCheck(GetDlgItem(hW,IDC_CDTIMING),Config.CdTiming); + ComboBox_AddString(GetDlgItem(hW,IDC_PSXTYPES),"NTSC"); + ComboBox_AddString(GetDlgItem(hW,IDC_PSXTYPES),"PAL"); + ComboBox_SetCurSel(GetDlgItem(hW,IDC_PSXTYPES),Config.PsxType); + + case WM_COMMAND: { + switch (LOWORD(wParam)) { + case IDCANCEL: EndDialog(hW,FALSE); return TRUE; + case IDOK: + tmp = ComboBox_GetCurSel(GetDlgItem(hW,IDC_PSXTYPES)); + if (tmp == 0) Config.PsxType = 0; + else Config.PsxType = 1; + + Config.Xa = Button_GetCheck(GetDlgItem(hW,IDC_XA)); + Config.Sio = Button_GetCheck(GetDlgItem(hW,IDC_SIO)); + Config.Mdec = Button_GetCheck(GetDlgItem(hW,IDC_MDEC)); + Config.QKeys = Button_GetCheck(GetDlgItem(hW,IDC_QKEYS)); + Config.Cdda = Button_GetCheck(GetDlgItem(hW,IDC_CDDA)); + Config.PsxAuto = Button_GetCheck(GetDlgItem(hW,IDC_PSXAUTO)); + tmp = Config.Cpu; + Config.Cpu = Button_GetCheck(GetDlgItem(hW,IDC_CPU)); + if (tmp != Config.Cpu) { + psxCpu->Shutdown(); + if (Config.Cpu) + psxCpu = &psxInt; + else psxCpu = &psxRec; + if (psxCpu->Init() == -1) { + SysClose(); + exit(1); + } + psxCpu->Reset(); + } + Config.PsxOut = Button_GetCheck(GetDlgItem(hW,IDC_PSXOUT)); + Config.SpuIrq = Button_GetCheck(GetDlgItem(hW,IDC_SPUIRQ)); + Config.CdTiming= Button_GetCheck(GetDlgItem(hW,IDC_CDTIMING)); + + SaveConfig(); + + EndDialog(hW,TRUE); + + if (Config.PsxOut) OpenConsole(); + else CloseConsole(); + + return TRUE; + } + } + } + return FALSE; +} + +#define MAXFILENAME 256 + +void Open_Mcd_Proc(HWND hW, int mcd) { + OPENFILENAME ofn; + char szFileName[MAXFILENAME]; + char szFileTitle[MAXFILENAME]; + + memset(&szFileName, 0, sizeof(szFileName)); + memset(&szFileTitle, 0, sizeof(szFileTitle)); + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hW; + ofn.lpstrFilter = "Psx Mcd Format (*.mcr;*.mc;*.mem;*.vgs;*.mcd;*.gme;*.ddf)\0*.mcr;*.mcd;*.mem;*.gme;*.mc;*.ddf\0Psx Memory Card (*.mcr;*.mc)\0*.mcr;0*.mc\0CVGS Memory Card (*.mem;*.vgs)\0*.mem;*.vgs\0Bleem Memory Card (*.mcd)\0*.mcd\0DexDrive Memory Card (*.gme)\0*.gme\0DataDeck Memory Card (*.ddf)\0*.ddf\0";; + ofn.lpstrCustomFilter = NULL; + ofn.nMaxCustFilter = 0; + ofn.nFilterIndex = 1; + ofn.lpstrFile = szFileName; + ofn.nMaxFile = MAXFILENAME; + ofn.lpstrInitialDir = "memcards"; + ofn.lpstrFileTitle = szFileTitle; + ofn.nMaxFileTitle = MAXFILENAME; + ofn.lpstrTitle = NULL; + ofn.lpstrDefExt = "MCR"; + ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR; + + if (GetOpenFileName ((LPOPENFILENAME)&ofn)) { + Edit_SetText(GetDlgItem(hW,mcd == 1 ? IDC_MCD1 : IDC_MCD2), szFileName); + LoadMcd(mcd, szFileName); + UpdateMcdDlg(); + } +} + +int Open_File_Proc(char *file) { + OPENFILENAME ofn; + char szFileName[MAXFILENAME]; + char szFileTitle[MAXFILENAME]; + + memset(&szFileName, 0, sizeof(szFileName)); + memset(&szFileTitle, 0, sizeof(szFileTitle)); + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = gApp.hWnd; + ofn.lpstrFilter = "Psx Exe Format\0*.*;*.*\0"; + ofn.lpstrCustomFilter = NULL; + ofn.nMaxCustFilter = 0; + ofn.nFilterIndex = 1; + ofn.lpstrFile = szFileName; + ofn.nMaxFile = MAXFILENAME; + ofn.lpstrInitialDir = NULL; + ofn.lpstrFileTitle = szFileTitle; + ofn.nMaxFileTitle = MAXFILENAME; + ofn.lpstrTitle = NULL; + ofn.lpstrDefExt = "EXE"; + ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR; + + if (GetOpenFileName ((LPOPENFILENAME)&ofn)) { + strcpy(file, szFileName); + return 1; + } else + return 0; +} + +void CreateMainWindow(int nCmdShow) { + char strTitle[20]; + WNDCLASS wc; + HWND hWnd; + HDC hdc; + HPEN hpen; + + LoadString(gApp.hInstance, IDS_TITLE, strTitle, 20); + + wc.lpszClassName = "P©SX Main"; + wc.lpfnWndProc = MainWndProc; + wc.style = 0; + wc.hInstance = gApp.hInstance; + wc.hIcon = LoadIcon(gApp.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); + wc.hCursor = NULL; + wc.hbrBackground = (HBRUSH)(COLOR_MENUTEXT); + wc.lpszMenuName = 0; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + + RegisterClass(&wc); + + hWnd = CreateWindow("P©SX Main", + strTitle, + WS_OVERLAPPED | WS_SYSMENU, + 20, + 20, + 320, + 240, + NULL, + NULL, + gApp.hInstance, + NULL); + + gApp.hWnd = hWnd; + + hdc = GetDC(hWnd); + hpen = CreatePen(PS_SOLID, 0, 0xffffff); + + SelectObject(hdc, hpen); + + ShowWindow(hWnd, nCmdShow); +} + +int SysInit() { + if (Config.PsxOut) OpenConsole(); + + if (psxInit() == -1) return -1; + + #ifdef GTE_DUMP + gteLog = fopen("gteLog.txt","w"); + #endif + +#ifdef EMU_LOG + emuLog = fopen("emuLog.txt","w"); + setvbuf(emuLog, NULL, _IONBF, 0); +#endif + + LoadPlugins(); + LoadMcds(Config.Mcd1, Config.Mcd2); + + return 0; +} + +void SysReset() { + psxReset(); +} + + +void SysClose() { + psxShutdown(); + ReleasePlugins(); + + if (Config.PsxOut) CloseConsole(); + + if (emuLog != NULL) fclose(emuLog); + #ifdef GTE_DUMP + if (gteLog != NULL) fclose(gteLog); + #endif +} + +void SysPrintf(char *fmt, ...) { + va_list list; + char msg[512]; + DWORD tmp; + + if (!hConsole) return; + + va_start(list,fmt); + vsprintf(msg,fmt,list); + va_end(list); + + WriteConsole(hConsole, msg, (DWORD)strlen(msg), &tmp, 0); +#ifdef EMU_LOG +#ifndef LOG_STDOUT + fprintf(emuLog, "%s", msg); +#endif +#endif +} + +void SysMessage(char *fmt, ...) { + va_list list; + char tmp[512]; + + va_start(list,fmt); + vsprintf(tmp,fmt,list); + va_end(list); + MessageBox(0, tmp, "Pcsx Msg", 0); +} + +static char *err = "Error Loading Symbol"; +static int errval; + +void *SysLoadLibrary(char *lib) { + return LoadLibrary(lib); +} + +void *SysLoadSym(void *lib, char *sym) { + void *tmp = GetProcAddress((HINSTANCE)lib, sym); + if (tmp == NULL) errval = 1; + else errval = 0; + return tmp; +} + +char *SysLibError() { + if (errval) { errval = 0; return err; } + return NULL; +} + +void SysCloseLibrary(void *lib) { + FreeLibrary((HINSTANCE)lib); +} + +void SysUpdate() { + MSG msg; + + PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE); + + while (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } +} + +void SysRunGui() { + RunGui(); +} \ No newline at end of file diff --git a/PcsxSrc/Win32/pcsx.dsp b/PcsxSrc/Win32/pcsx.dsp new file mode 100644 index 0000000..0cd948b --- /dev/null +++ b/PcsxSrc/Win32/pcsx.dsp @@ -0,0 +1,350 @@ +# Microsoft Developer Studio Project File - Name="pcsx" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=PCSX - WIN32 RELEASE +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "pcsx.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "pcsx.mak" CFG="PCSX - WIN32 RELEASE" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "pcsx - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "__WIN32__" /D PCSX_VERSION=\"1.3\" /D "__i386__" /FD /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x408 /d "NDEBUG" +# ADD RSC /l 0x408 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib zlib.lib winmm.lib /nologo /subsystem:windows /machine:I386 +# Begin Target + +# Name "pcsx - Win32 Release" +# Begin Group "GUI" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\AboutDlg.c +# End Source File +# Begin Source File + +SOURCE=.\AboutDlg.h +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\Win32.h +# End Source File +# Begin Source File + +SOURCE=.\WndMain.c +# End Source File +# End Group +# Begin Group "Bios" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\PsxBios.c +# End Source File +# Begin Source File + +SOURCE=..\PsxBios.h +# End Source File +# End Group +# Begin Group "CdRom" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\CdRom.c +# End Source File +# Begin Source File + +SOURCE=..\CdRom.h +# End Source File +# Begin Source File + +SOURCE=..\Decode_XA.c +# End Source File +# Begin Source File + +SOURCE=..\Decode_XA.h +# End Source File +# End Group +# Begin Group "GPU-SPU-SIO" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Sio.c +# End Source File +# Begin Source File + +SOURCE=..\Sio.h +# End Source File +# Begin Source File + +SOURCE=..\Spu.c +# End Source File +# Begin Source File + +SOURCE=..\Spu.h +# End Source File +# End Group +# Begin Group "Debugger" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Debug.h +# End Source File +# Begin Source File + +SOURCE=..\DisR3000A.c +# End Source File +# End Group +# Begin Group "GTE" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Gte.c +# End Source File +# Begin Source File + +SOURCE=..\Gte.h +# End Source File +# End Group +# Begin Group "Memory" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\PsxMem.c +# End Source File +# Begin Source File + +SOURCE=..\PsxMem.h +# End Source File +# End Group +# Begin Group "Plugins system" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\ConfigurePlugins.c +# End Source File +# Begin Source File + +SOURCE=.\plugin.c +# End Source File +# Begin Source File + +SOURCE=.\plugin.h +# End Source File +# Begin Source File + +SOURCE=..\plugins.c +# End Source File +# Begin Source File + +SOURCE=..\plugins.h +# End Source File +# End Group +# Begin Group "CPU" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\PsxInterpreter.c +# End Source File +# Begin Source File + +SOURCE=..\R3000A.c +# End Source File +# Begin Source File + +SOURCE=..\R3000A.h +# End Source File +# End Group +# Begin Group "Hardware registers" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\PsxHw.c +# End Source File +# Begin Source File + +SOURCE=..\PsxHw.h +# End Source File +# End Group +# Begin Group "DMA" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\PsxDma.c +# End Source File +# Begin Source File + +SOURCE=..\PsxDma.h +# End Source File +# End Group +# Begin Group "Mdec" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Mdec.c +# End Source File +# Begin Source File + +SOURCE=..\Mdec.h +# End Source File +# End Group +# Begin Group "Misc" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Coff.h +# End Source File +# Begin Source File + +SOURCE=..\Misc.c +# End Source File +# Begin Source File + +SOURCE=..\Misc.h +# End Source File +# Begin Source File + +SOURCE=..\System.h +# End Source File +# End Group +# Begin Group "Counters" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\PsxCounters.c +# End Source File +# Begin Source File + +SOURCE=..\PsxCounters.h +# End Source File +# End Group +# Begin Group "ix86" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\ix86\iR3000A.c +# End Source File +# Begin Source File + +SOURCE=..\ix86\ix86.c +# End Source File +# Begin Source File + +SOURCE=..\ix86\ix86.h +# End Source File +# End Group +# Begin Group "HLE" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\PsxHLE.c +# End Source File +# Begin Source File + +SOURCE=..\PsxHLE.h +# End Source File +# End Group +# Begin Group "Docs" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=..\Docs\ChangeLog.txt +# End Source File +# Begin Source File + +SOURCE=..\Docs\CodingStyle.txt +# End Source File +# Begin Source File + +SOURCE=..\Docs\License.txt +# End Source File +# Begin Source File + +SOURCE=..\Docs\Readme.txt +# End Source File +# Begin Source File + +SOURCE=..\Docs\ToDo.txt +# End Source File +# End Group +# Begin Source File + +SOURCE=.\Cdrom02.ico +# End Source File +# Begin Source File + +SOURCE=.\pcsx.rc +# End Source File +# Begin Source File + +SOURCE=..\pcsxAbout.bmp +# End Source File +# Begin Source File + +SOURCE=..\PSEmu_Plugin_Defs.h +# End Source File +# Begin Source File + +SOURCE=..\PsxCommon.h +# End Source File +# End Target +# End Project diff --git a/PcsxSrc/Win32/pcsx.dsw b/PcsxSrc/Win32/pcsx.dsw new file mode 100644 index 0000000..038983b --- /dev/null +++ b/PcsxSrc/Win32/pcsx.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "pcsx"=.\pcsx.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/PcsxSrc/Win32/pcsx.rc b/PcsxSrc/Win32/pcsx.rc new file mode 100644 index 0000000..40723e0 --- /dev/null +++ b/PcsxSrc/Win32/pcsx.rc @@ -0,0 +1,402 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_MCDCONF DIALOG DISCARDABLE 0, 0, 407, 197 +STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "P©SX Memcard Manager" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,285,175,50,14 + PUSHBUTTON "Cancel",IDCANCEL,345,175,50,14 + EDITTEXT IDC_MCD1,10,155,160,14,ES_AUTOHSCROLL + EDITTEXT IDC_MCD2,235,155,160,14,ES_AUTOHSCROLL + PUSHBUTTON "Select Mcd",IDC_MCDSEL1,10,135,50,14 + PUSHBUTTON "Select Mcd",IDC_MCDSEL2,235,135,50,14 + GROUPBOX "Memory Card 2",IDC_STATIC,230,5,170,125 + PUSHBUTTON "Format Mcd",IDC_FORMAT1,65,135,50,14 + GROUPBOX "Memory Card 1",IDC_STATIC,5,5,170,125 + PUSHBUTTON "Format Mcd",IDC_FORMAT2,290,135,50,14 + CONTROL "List3",IDC_LIST1,"SysListView32",LVS_REPORT | + LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,10,15,160,110 + CONTROL "List3",IDC_LIST2,"SysListView32",LVS_REPORT | + LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,235,15,160,110 + PUSHBUTTON "Reload Mcd",IDC_RELOAD1,120,135,50,14 + PUSHBUTTON "Reload Mcd",IDC_RELOAD2,345,135,50,14 + PUSHBUTTON "-> Copy ->",IDC_COPYTO2,180,30,45,14 + PUSHBUTTON "<- Copy <-",IDC_COPYTO1,180,50,45,14 + PUSHBUTTON "Paste",IDC_PASTE,180,70,45,14 + PUSHBUTTON "<- Un/Delete",IDC_DELETE1,180,90,45,14 + PUSHBUTTON "Un/Delete ->",IDC_DELETE2,180,110,45,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_MCDCONF, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 400 + TOPMARGIN, 7 + BOTTOMMARGIN, 190 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDS_TITLE "P©SX" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.K.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +ABOUT_DIALOG DIALOGEX 0, 0, 332, 166 +STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,135,145,50,14 + CTEXT "PCSX EMU\nVersion x.x",IDC_PCSX_ABOUT_TEXT,55,10,40,15, + 0,WS_EX_TRANSPARENT + CTEXT "PCSX a psx emulator\n\nwritten by:\nmain coder: linuzappz\nco-coders: shadow\nex-coders: Nocomp, Pete Bernett, nik3d\nWebmaster: AkumaX", + IDC_STATIC,10,35,135,55,0,WS_EX_TRANSPARENT + CTEXT "Greets to: Duddie, Tratax, Kazzuya, JNS, Bobbi\nSpecial thanks to : Twin (we Love you twin0r), Roor (love for you too), calb (Thanks for help :) ), now3d (for great help to my psxdev stuff :) )", + IDC_STATIC,45,110,232,25 + CONTROL 113,IDC_STATIC,"Static",SS_BITMAP | WS_BORDER,155,10,171, + 86 + GROUPBOX "",IDC_STATIC,5,25,145,70 + GROUPBOX "",IDC_STATIC,43,100,235,40 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + ABOUT_DIALOG, DIALOG + BEGIN + RIGHTMARGIN, 310 + BOTTOMMARGIN, 158 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU1 MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "Run &CD", ID_FILE_RUN_CD + MENUITEM "Run CD Though &Bios", ID_FILE_RUNCDBIOS + MENUITEM "Run &EXE", ID_FILE_RUN_EXE + MENUITEM SEPARATOR + MENUITEM "E&xit", ID_FILE_EXIT + END + POPUP "&Emulator" + BEGIN + MENUITEM "&Run", ID_EMULATOR_RUN + MENUITEM "Re&set", ID_EMULATOR_RESET + END + POPUP "&Configuration" + BEGIN + MENUITEM "&Plugins && Bios", ID_CONFIGURATION + MENUITEM SEPARATOR + MENUITEM "&Graphics", ID_CONFIGURATION_GRAPHICS + MENUITEM "&Sound", ID_CONFIGURATION_SOUND + MENUITEM "CD-&ROM", ID_CONFIGURATION_CDROM + MENUITEM "&Controllers", ID_CONFIGURATION_CONTROLLERS + MENUITEM SEPARATOR + MENUITEM "C&PU", ID_CONFIGURATION_CPU + MENUITEM "&Memory cards", ID_CONFIGURATION_MEMORYCARDMANAGER + + END + POPUP "Help" + BEGIN + MENUITEM "&Help", ID_HELP_HELP + MENUITEM SEPARATOR + MENUITEM "&About P©SX", ID_HELP_ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_APP_ICON ICON DISCARDABLE ".\\Cdrom02.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +SPLASH_LOGO BITMAP DISCARDABLE "..\\pcsxAbout.bmp" +#endif // English (U.K.) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// Spanish (Castilian) (unknown sub-lang: 0xB) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ESS) +#ifdef _WIN32 +LANGUAGE LANG_SPANISH, 0xB +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_CPUCONF DIALOG DISCARDABLE 0, 0, 227, 161 +STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Cpu Config" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,50,140,50,14 + PUSHBUTTON "Cancel",IDCANCEL,120,140,50,14 + CONTROL "Disable Xa Decoding",IDC_XA,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,10,15,83,10 + CONTROL "Sio Irq Always Enabled",IDC_SIO,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,10,30,88,10 + CONTROL "Black && White Movies",IDC_MDEC,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,10,60,85,10 + CONTROL "Autodetect",IDC_PSXAUTO,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,10,110,51,10 + GROUPBOX "Misc Options",IDC_STATIC,5,5,220,85 + COMBOBOX IDC_PSXTYPES,105,111,53,50,CBS_DROPDOWNLIST | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + GROUPBOX "Select Psx System Type",IDC_STATIC,5,95,220,35 + CONTROL "Disable Misc Quick Keys (F5-F8)",IDC_QKEYS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,105,60,118,10 + CONTROL "Disable Cd Audio",IDC_CDDA,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,105,15,70,10 + CONTROL "Enable Console Output",IDC_PSXOUT,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,105,30,89,10 + CONTROL "Enable Interpreter Cpu",IDC_CPU,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,105,45,87,10 + CONTROL "Spu Irq Always Enabled",IDC_SPUIRQ,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,10,45,91,10 + CONTROL "Old Cdrom Timing (Gran Turismo...)",IDC_CDTIMING,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,10,75,125,10 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_CPUCONF, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 220 + TOPMARGIN, 7 + BOTTOMMARGIN, 154 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog Info +// + +IDD_CPUCONF DLGINIT +BEGIN + IDC_PSXTYPES, 0x403, 5, 0 +0x544e, 0x4353, "\000" + IDC_PSXTYPES, 0x403, 4, 0 +0x4150, 0x004c, + 0 +END + +#endif // Spanish (Castilian) (unknown sub-lang: 0xB) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// Greek resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ELL) +#ifdef _WIN32 +LANGUAGE LANG_GREEK, SUBLANG_DEFAULT +#pragma code_page(1253) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_CONFIG DIALOG DISCARDABLE 0, 0, 322, 161 +STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Configuration" +FONT 8, "MS Sans Serif" +BEGIN + COMBOBOX IDC_LISTGPU,10,10,145,74,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + PUSHBUTTON "Configure...",IDC_CONFIGGPU,10,30,45,12 + PUSHBUTTON "Test...",IDC_TESTGPU,60,30,45,12 + PUSHBUTTON "About...",IDC_ABOUTGPU,110,30,45,12 + COMBOBOX IDC_LISTSPU,165,10,145,74,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + PUSHBUTTON "Configure...",IDC_CONFIGSPU,165,30,45,12 + PUSHBUTTON "Test...",IDC_TESTSPU,215,30,45,12 + PUSHBUTTON "About...",IDC_ABOUTSPU,265,30,43,12 + COMBOBOX IDC_LISTCDR,10,100,145,74,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + PUSHBUTTON "Configure...",IDC_CONFIGCDR,10,120,43,12 + PUSHBUTTON "Test...",IDC_TESTCDR,60,120,45,12 + PUSHBUTTON "About...",IDC_ABOUTCDR,110,120,45,12 + COMBOBOX IDC_LISTBIOS,165,100,145,74,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "OK",IDOK,205,140,50,14 + PUSHBUTTON "Cancel",IDCANCEL,260,140,50,14 + RTEXT "Graphics",IDC_STATIC,50,0,41,10,SS_CENTERIMAGE + RTEXT "Sound",IDC_STATIC,200,0,43,10,SS_CENTERIMAGE + RTEXT "Cdrom",IDC_STATIC,70,90,20,10,SS_CENTERIMAGE + RTEXT "Bios",IDC_STATIC,225,90,15,10,SS_CENTERIMAGE + COMBOBOX IDC_LISTPAD1,10,55,145,74,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + PUSHBUTTON "Configure...",IDC_CONFIGPAD1,10,75,45,12 + PUSHBUTTON "Test...",IDC_TESTPAD1,60,75,45,12 + PUSHBUTTON "About...",IDC_ABOUTPAD1,110,75,45,12 + RTEXT "Second Controller",IDC_STATIC,205,45,58,10, + SS_CENTERIMAGE + COMBOBOX IDC_LISTPAD2,165,55,145,74,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + PUSHBUTTON "Configure...",IDC_CONFIGPAD2,165,75,45,12 + PUSHBUTTON "Test...",IDC_TESTPAD2,215,75,45,12 + PUSHBUTTON "About...",IDC_ABOUTPAD2,265,75,45,12 + CTEXT "First Controller",IDC_STATIC,55,45,48,10,SS_CENTERIMAGE + PUSHBUTTON "Set Bios Directory",IDC_BIOSDIR,90,140,65,14 + PUSHBUTTON "Set Plugins Directory",IDC_PLUGINSDIR,10,140,75,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_CONFIG, DIALOG + BEGIN + BOTTOMMARGIN, 147 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // Greek resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/PcsxSrc/Win32/plugin.c b/PcsxSrc/Win32/plugin.c new file mode 100644 index 0000000..a705fb2 --- /dev/null +++ b/PcsxSrc/Win32/plugin.c @@ -0,0 +1,191 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include "plugins.h" +#include "resource.h" +#include +#include +#include "R3000A.h" +#include "Win32.h" + +void PADhandleKey(int key) { + char Text[255]; + int ret; + + if (Running == 0) return; + switch (key) { + case 0: break; + case VK_F1: + sprintf (Text, "sstates/%s.%3.3d", CdromId, StatesC); + GPU_freeze(2, (GPUFreeze_t *)&StatesC); + ret = SaveState(Text); + sprintf (Text, "*PCSX*: %s State %d", !ret ? "Saved" : "Error Saving", StatesC+1); + GPU_displayText(Text); + return; + + case VK_F2: + if (StatesC < 4) StatesC++; + else StatesC = 0; + GPU_freeze(2, (GPUFreeze_t *)&StatesC); + return; + + case VK_F3: + sprintf (Text, "sstates/%s.%3.3d", CdromId, StatesC); + ret = LoadState(Text); + sprintf (Text, "*PCSX*: %s State %d", !ret ? "Loaded" : "Error Loading", StatesC+1); + GPU_displayText(Text); + return; + + case VK_F4: + { + gzFile f; + static int ShowPic; + static unsigned char *pMem; + + if (!ShowPic) { + sprintf (Text, "sstates/%s.%3.3d", CdromId, StatesC); + f = gzopen(Text, "rb"); + if (f == NULL) return; + + gzseek(f, 32, SEEK_SET); // skip header + + pMem = (unsigned char *) malloc(128*96*3); + gzread(f, pMem, 128*96*3); + gzclose(f); + GPU_freeze(2, (GPUFreeze_t *)&StatesC); + GPU_showScreenPic(pMem); + free(pMem); + ShowPic = 1; + } + else { + GPU_showScreenPic(NULL); + ShowPic = 0; + } + + } + return; + + case VK_F5: + if (Config.QKeys) break; + Config.Sio ^= 0x1; + sprintf (Text, "*PCSX*: Sio Irq %sAlways Enabled", Config.Sio ? "" : "Not "); + GPU_displayText(Text); + return; + + case VK_F6: + if (Config.QKeys) break; + Config.Mdec ^= 0x1; + sprintf (Text, "*PCSX*: Black&White Only Mdecs %sabled", Config.Mdec ? "En" : "Dis"); + GPU_displayText(Text); + return; + + case VK_F7: + if (Config.QKeys) break; + Config.Xa ^= 0x1; + sprintf (Text, "*PCSX*: Xa %sabled", !Config.Xa ? "En" : "Dis"); + GPU_displayText(Text); + return; + + case VK_F8: + if (Config.QKeys) break; + GPU_makeSnapshot(); + return; + + case VK_F9: + GPU_displayText("*PCSX*: CdRom Case Opened"); + cdOpenCase = 1; + return; + + case VK_F10: + GPU_displayText("*PCSX*: CdRom Case Closed"); + cdOpenCase = 0; + return; + + case VK_ESCAPE: + Running = 0; + ClosePlugins(); + AccBreak = 1; + DestroyWindow(gApp.hWnd); + CreateMainWindow(SW_SHOWNORMAL); + SetMenu(gApp.hWnd, gApp.hMenu); + SetCursor(LoadCursor(gApp.hInstance, IDC_ARROW)); + ShowCursor(TRUE); + RunGui(); + return; + } +} + +void CALLBACK SPUirq(void); + +void OpenPlugins(HWND hWnd) { + int ret; + + ret = CDR_open(); + if (ret != 0) { SysMessage ("Error Opening CDR Plugin\n"); exit(1); } + ShowCursor(FALSE); + ret = GPU_open(hWnd); + if (ret != 0) { SysMessage ("Error Opening GPU Plugin\n"); exit(1); } + ret = SPU_open(hWnd); + if (ret != 0) { SysMessage ("Error Opening SPU Plugin\n"); exit(1); } + SPU_registerCallback(SPUirq); + ret = PAD1_open(hWnd); + if (ret != 0) { SysMessage ("Error Opening PAD1 Plugin\n"); exit(1); } + ret = PAD2_open(hWnd); + if (ret != 0) { SysMessage ("Error Opening PAD2 Plugin\n"); exit(1); } + SetCurrentDirectory(PcsxDir); +} + +void ClosePlugins() { + int ret; + + ret = CDR_close(); + if (ret != 0) { SysMessage ("Error Closing CDR Plugin\n"); exit(1); } + ret = GPU_close(); + if (ret != 0) { SysMessage ("Error Closing GPU Plugin\n"); exit(1); } + ret = SPU_close(); + if (ret != 0) { SysMessage ("Error Closing SPU Plugin\n"); exit(1); } + ret = PAD1_close(); + if (ret != 0) { SysMessage ("Error Closing PAD1 Plugin\n"); exit(1); } + ret = PAD2_close(); + if (ret != 0) { SysMessage ("Error Closing PAD2 Plugin\n"); exit(1); } + ShowCursor(TRUE); +} + +void ResetPlugins() { + int ret; + + CDR_shutdown(); + GPU_shutdown(); + SPU_shutdown(); + PAD1_shutdown(); + PAD2_shutdown(); + ret = CDR_init(); + if (ret != 0) { SysMessage ("CDRinit error : %d\n",ret); exit(1); } + ret = GPU_init(); + if (ret != 0) { SysMessage ("GPUinit error : %d\n",ret); exit(1); } + ret = SPU_init(); + if (ret != 0) { SysMessage ("SPUinit error : %d\n",ret); exit(1); } + ret = PAD1_init(1); + if (ret != 0) { SysMessage ("PAD1init error : %d\n",ret); exit(1); } + ret = PAD2_init(2); + if (ret != 0) { SysMessage ("PAD2init error : %d\n",ret); exit(1); } +} + + diff --git a/PcsxSrc/Win32/plugin.h b/PcsxSrc/Win32/plugin.h new file mode 100644 index 0000000..bec7f7f --- /dev/null +++ b/PcsxSrc/Win32/plugin.h @@ -0,0 +1,29 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +// Windows Specifyc Plugin Functions +#ifndef __PLUGIN_H__ +#define __PLUGIN_H__ + +typedef long (CALLBACK* GPUopen)(HWND); + +typedef long (CALLBACK* SPUopen)(HWND); + +typedef long (CALLBACK* PADopen)(HWND); + +#endif /* __PLUGIN_H__ */ \ No newline at end of file diff --git a/PcsxSrc/Win32/resource.h b/PcsxSrc/Win32/resource.h new file mode 100644 index 0000000..464846e --- /dev/null +++ b/PcsxSrc/Win32/resource.h @@ -0,0 +1,266 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by pcsx.rc +// +#define IDS_TITLE 1 +#define IDR_MENU1 101 +#define IDI_APP_ICON 102 +#define IDD_MCDCONF 102 +#define DEBUG_DIALOG 103 +#define ABOUT_DIALOG 104 +#define IDD_CPUCONF 105 +#define SPLASH_LOGO 113 +#define IDD_GPREGS 114 +#define IDD_CP0REGS 115 +#define IDD_COP2D 116 +#define IDD_COP2C 117 +#define IDD_CONFIG 120 +#define IDD_MEMVIEW 136 +#define IDC_EDIT2 1001 +#define IDC_MCD2 1004 +#define IDC_ASMCHECK1 1005 +#define IDC_MCD1 1005 +#define IDC_MCDSEL1 1006 +#define IDC_STEP 1007 +#define IDC_MCDSEL2 1007 +#define IDC_XA 1007 +#define IDC_SIO 1008 +#define IDC_SKIP 1009 +#define IDC_MDEC 1009 +#define IDC_RESET 1010 +#define IDC_PSXAUTO 1010 +#define IDC_GO 1011 +#define IDC_PSXTYPES 1011 +#define IDC_BREAK 1012 +#define IDC_DISCPUQKEYS 1012 +#define IDC_QKEYS 1012 +#define IDC_EDIT1 1013 +#define IDC_CDDA 1013 +#define IDC_CLOSE 1014 +#define IDC_PCSX_ABOUT_TEXT 1014 +#define IDC_PSXOUT 1014 +#define IDC_ASM_SCROLL 1015 +#define IDC_CPU 1015 +#define IDC_ASMCHECK2 1016 +#define IDC_SPUIRQ 1016 +#define IDC_ASMCHECK3 1017 +#define IDC_MDEC2 1017 +#define IDC_CDTIMING 1017 +#define IDC_ASMCHECK4 1018 +#define IDC_ASMCHECK5 1019 +#define IDC_RELOAD1 1019 +#define IDC_CP07 1020 +#define IDC_ASMCHECK6 1020 +#define IDC_RELOAD2 1020 +#define IDC_ASMCHECK7 1021 +#define IDC_COPYTO2 1021 +#define IDC_ASMCHECK8 1022 +#define IDC_COPYTO1 1022 +#define IDC_ASMCHECK9 1023 +#define IDC_PASTE 1023 +#define IDC_ASMCHECK10 1024 +#define IDC_DELETE1 1024 +#define IDC_ASMCHECK11 1025 +#define IDC_DELETE2 1025 +#define IDC_ASMCHECK12 1026 +#define IDC_LIST1 1027 +#define IDC_ASMCHECK13 1027 +#define IDC_ASMCHECK14 1028 +#define IDC_LIST2 1028 +#define IDC_ASMCHECK15 1029 +#define IDC_ASMCHECK16 1030 +#define IDC_ASMCHECK17 1031 +#define IDC_ASMCHECK18 1032 +#define IDC_ASMCHECK19 1033 +#define IDC_CP021 1034 +#define IDC_ASMCHECK20 1034 +#define IDC_CP022 1035 +#define IDC_ASMCHECK21 1035 +#define IDC_CP023 1036 +#define IDC_ASMCHECK22 1036 +#define IDC_CP024 1037 +#define IDC_ASMCHECK23 1037 +#define IDC_CP025 1038 +#define IDC_ASMCHECK24 1038 +#define IDC_CP031 1044 +#define IDC_GPR0 1047 +#define IDC_GPR1 1048 +#define IDC_GPR2 1049 +#define IDC_GPR3 1050 +#define IDC_GPR4 1051 +#define IDC_GPR5 1052 +#define IDC_LISTGPU 1052 +#define IDC_GPR6 1053 +#define IDC_LISTSPU 1053 +#define IDC_GPR7 1054 +#define IDC_LISTCDR 1054 +#define IDC_GPR8 1055 +#define IDC_LISTBIOS 1055 +#define IDC_GPR9 1056 +#define IDC_CONFIGGPU 1056 +#define IDC_GPR10 1057 +#define IDC_TESTGPU 1057 +#define IDC_ABOUTGPU 1058 +#define IDC_CONFIGSPU 1059 +#define IDC_TESTSPU 1060 +#define IDC_ABOUTSPU 1061 +#define IDC_CONFIGCDR 1062 +#define IDC_GPR11 1063 +#define IDC_TESTCDR 1063 +#define IDC_ABOUTCDR 1064 +#define IDC_COMBODRIVE 1065 +#define IDC_LISTPAD1 1066 +#define IDC_CONFIGPAD1 1067 +#define IDC_GPR12 1068 +#define IDC_TESTPAD1 1068 +#define IDC_GPR13 1069 +#define IDC_ABOUTPAD1 1069 +#define IDC_GPR14 1070 +#define IDC_LISTPAD2 1070 +#define IDC_GPR15 1071 +#define IDC_CONFIGPAD2 1071 +#define IDC_GPR16 1072 +#define IDC_TESTPAD2 1072 +#define IDC_GPR17 1073 +#define IDC_ABOUTPAD2 1073 +#define IDC_GPR18 1074 +#define IDC_GPR19 1075 +#define IDC_GPR20 1076 +#define IDC_GPR21 1077 +#define IDC_GPR22 1078 +#define IDC_GPR23 1079 +#define IDC_GPR24 1080 +#define IDC_GPR25 1081 +#define IDC_GPR26 1082 +#define IDC_GPR27 1083 +#define IDC_GPR28 1084 +#define IDC_GPR29 1085 +#define IDC_GPR30 1086 +#define IDC_GPR31 1087 +#define IDC_GPR_PC 1089 +#define IDC_GPR_HI 1091 +#define IDC_GPR_LO 1092 +#define IDC_CP00 1093 +#define IDC_CP01 1094 +#define IDC_CP02 1095 +#define IDC_CP03 1096 +#define IDC_CP04 1097 +#define IDC_CP05 1098 +#define IDC_CP06 1099 +#define IDC_CP08 1100 +#define IDC_CP09 1101 +#define IDC_CP010 1102 +#define IDC_CP011 1103 +#define IDC_CP012 1104 +#define IDC_CP013 1105 +#define IDC_CP014 1106 +#define IDC_CP015 1107 +#define IDC_CP016 1108 +#define IDC_CP017 1109 +#define IDC_CP018 1110 +#define IDC_CP019 1111 +#define IDC_CP020 1112 +#define IDC_CP026 1113 +#define IDC_CP027 1114 +#define IDC_CP028 1115 +#define IDC_CP029 1116 +#define IDC_CP030 1117 +#define IDC_COP2D0 1118 +#define IDC_COP2D1 1119 +#define IDC_COP2D2 1120 +#define IDC_COP2D3 1121 +#define IDC_COP2D4 1122 +#define IDC_COP2D5 1123 +#define IDC_COP2D6 1124 +#define IDC_COP2D7 1125 +#define IDC_COP2D8 1126 +#define IDC_COP2D9 1127 +#define IDC_COP2D10 1128 +#define IDC_COP2D11 1129 +#define IDC_COP2D12 1130 +#define IDC_COP2D13 1131 +#define IDC_COP2D14 1132 +#define IDC_COP2D15 1133 +#define IDC_COP2D16 1134 +#define IDC_COP2D17 1135 +#define IDC_COP2D18 1136 +#define IDC_COP2D19 1137 +#define IDC_COP2D20 1138 +#define IDC_COP2D21 1139 +#define IDC_COP2D22 1140 +#define IDC_COP2D23 1141 +#define IDC_COP2D24 1142 +#define IDC_COP2D25 1143 +#define IDC_COP2D26 1144 +#define IDC_COP2D27 1145 +#define IDC_COP2D28 1146 +#define IDC_COP2D29 1147 +#define IDC_COP2D30 1148 +#define IDC_COP2D31 1149 +#define IDC_COP2C0 1152 +#define IDC_COP2C1 1153 +#define IDC_COP2C2 1154 +#define IDC_COP2C3 1155 +#define IDC_COP2C4 1156 +#define IDC_COP2C5 1157 +#define IDC_COP2C6 1158 +#define IDC_COP2C7 1159 +#define IDC_COP2C8 1160 +#define IDC_COP2C9 1161 +#define IDC_COP2C10 1162 +#define IDC_COP2C11 1163 +#define IDC_COP2C12 1164 +#define IDC_COP2C13 1165 +#define IDC_COP2C14 1166 +#define IDC_COP2C15 1167 +#define IDC_COP2C16 1168 +#define IDC_COP2C17 1169 +#define IDC_COP2C18 1170 +#define IDC_COP2C19 1171 +#define IDC_COP2C20 1172 +#define IDC_COP2C21 1173 +#define IDC_COP2C22 1174 +#define IDC_COP2C23 1175 +#define IDC_COP2C24 1176 +#define IDC_COP2C25 1177 +#define IDC_COP2C26 1178 +#define IDC_COP2C27 1179 +#define IDC_COP2C28 1180 +#define IDC_COP2C29 1181 +#define IDC_COP2C30 1182 +#define IDC_COP2C31 1183 +#define IDC_BUTTON1 1254 +#define IDC_BIOSDIR 1254 +#define IDC_FORMAT1 1254 +#define IDC_PLUGINSDIR 1255 +#define IDC_FORMAT2 1255 +#define ID_FILE_EXIT 40001 +#define ID_HELP_ABOUT 40002 +#define ID_FILE_RUN_CD 40003 +#define ID_FILE_RUN_EXE 40004 +#define ID_EMULATOR_PAUSE 40005 +#define ID_EMULATOR_RESET 40006 +#define ID_HELP_HELP 40007 +#define ID_DEBUG_ENABLE_DEBUGGER 40008 +#define ID_CONFIGURATION_GRAPHICS 40009 +#define ID_CONFIGURATION_SOUND 40010 +#define ID_CONFIGURATION_CDROM 40011 +#define ID_CONFIGURATION_MEMORYCARDMANAGER 40012 +#define ID_CONFIGURATION_CPU 40013 +#define ID_EMULATOR_RUN 40014 +#define ID_DEBUGREG 40015 +#define ID_DEBUG_MESSAGES 40015 +#define ID_CONFIGURATION_CONTROLLERS 40017 +#define ID_CONFIGURATION 40018 +#define ID_FILE_RUNCDBIOS 40026 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 108 +#define _APS_NEXT_COMMAND_VALUE 40028 +#define _APS_NEXT_CONTROL_VALUE 1022 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/PcsxSrc/ix86/iR3000A.c b/PcsxSrc/ix86/iR3000A.c new file mode 100644 index 0000000..c6ff128 --- /dev/null +++ b/PcsxSrc/ix86/iR3000A.c @@ -0,0 +1,1236 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef __WIN32__ +#pragma warning(disable:4244) +#pragma warning(disable:4761) +#endif +#include +#include +#include + +#include "PsxCommon.h" +#include "ix86.h" + +static u32 *recLUT; + +#define PC_REC(x) (recLUT[x >> 16] + (x & 0xffff)) +#define PC_REC8(x) (*(u8 *)PC_REC(x)) +#define PC_REC16(x) (*(u16*)PC_REC(x)) +#define PC_REC32(x) (*(u32*)PC_REC(x)) + +#define RECMEM_SIZE (8*1024*1024) + +static char *recMem; /* the recompiled blocks will be here */ +static char *recRAM; /* and the ptr to the blocks here */ +static char *recROM; /* and here */ + +static u32 pc; /* recompiler pc */ +static int count; /* recompiler intruction count */ +static int branch; /* set for branch */ +static u32 target; /* branch target */ + +static void (*recBSC[64])(); +static void (*recSPC[64])(); +static void (*recREG[32])(); +static void (*recCP0[32])(); +static void (*recCP2[64])(); +static void (*recCP2BSC[32])(); + +/* set a pending branch */ +#define SetBranch() { \ + branch = 1; \ + psxRegs.code = PSXMu32(pc); \ + pc+=4; count++; \ + recBSC[psxRegs.code>>26](); \ + \ + MOV32MtoR(EAX, (u32)&target); \ + MOV32RtoM((u32)&psxRegs.pc, EAX); \ + CALLFunc((u32)psxBranchTest); \ +} + +#define REC_FUNC(f) \ +void psx##f(); \ +static void rec##f() { \ + MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \ + MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \ + CALLFunc((u32)psx##f); \ +/* branch = 2; */\ +} + +#define REC_SYS(f) \ +void psx##f(); \ +static void rec##f() { \ + MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \ + MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \ + CALLFunc((u32)psx##f); \ + branch = 2; \ +} + +#define REC_BRANCH(f) \ +void psx##f(); \ +static void rec##f() { \ + MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \ + MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \ + CALLFunc((u32)psx##f); \ + branch = 2; \ + count++; \ +} + +static void recRecompile(); + +static int recInit() { + int i; + + recLUT = (u32*) malloc(0x010000 * 4); + + recMem = (char*) malloc(RECMEM_SIZE); + recRAM = (char*) malloc(0x200000); + recROM = (char*) malloc(0x080000); + if (recRAM == NULL || recROM == NULL || recMem == NULL || recLUT == NULL) { + SysMessage("Error allocating memory"); return -1; + } + + for (i=0; i<0x80; i++) recLUT[i + 0x0000] = (u32)&recRAM[(i & 0x1f) << 16]; + memcpy(recLUT + 0x8000, recLUT, 0x80 * 4); + memcpy(recLUT + 0xa000, recLUT, 0x80 * 4); + + for (i=0; i<0x08; i++) recLUT[i + 0xbfc0] = (u32)&recROM[i << 16]; + + return 0; +} + +static void recReset() { + memset(recRAM, 0, 0x200000); + memset(recROM, 0, 0x080000); + + x86Init(recMem); + branch = 0; +} + +static void recShutdown() { + if (recMem == NULL) return; + free(recLUT); + free(recMem); + free(recRAM); + free(recROM); +} + +static void recError() { + SysReset(); + ClosePlugins(); + SysMessage("Unrecoverable error while running recompiler\n"); + SysRunGui(); +} + +#define execute() { \ + void (**recFunc)(); \ + char *p; \ + \ + p = (char*)PC_REC(psxRegs.pc); \ + if (p != NULL) recFunc = (void (**)()) (u32)p; \ + else { recError(); return; } \ + \ + if (*recFunc == 0) { \ + recRecompile(); \ + } \ + (*recFunc)(); \ +} + +static void DumpRegs() { + int i, j; + + printf("%lx %lx\n", psxRegs.pc, psxRegs.cycle); + for (i=0; i<4; i++) { + for (j=0; j<8; j++) + printf("%lx ", psxRegs.GPR.r[j*i]); + printf("\n"); + } +} + +static void recExecuteBios() { + while (psxRegs.pc != 0x80030000) { + execute(); + } +} + +static void recExecute() { + for (;;) execute(); +} + +static void recExecuteBlock() { + execute(); +} + +static void recClear(u32 Addr, u32 Size) { + memset((void*)PC_REC(Addr), 0, Size * 4); +} + +static void recNULL() { +// SysMessage("recUNK: %8.8x\n", psxRegs.code); +} + +/********************************************************* +* goes to opcodes tables... * +* Format: table[something....] * +*********************************************************/ + +//REC_SYS(SPECIAL); +static void recSPECIAL() { + recSPC[_Funct_](); +} + +static void recREGIMM() { + recREG[_Rt_](); +} + +static void recCOP0() { + recCP0[_Rs_](); +} + +//REC_SYS(COP2); +static void recCOP2() { + recCP2[_Funct_](); +} + +static void recBASIC() { + recCP2BSC[_Rs_](); +} + +//end of Tables opcodes... + +/********************************************************* +* Arithmetic with immediate operand * +* Format: OP rt, rs, immediate * +*********************************************************/ +/* +REC_FUNC(ADDI); +REC_FUNC(ADDIU); +REC_FUNC(ANDI); +REC_FUNC(ORI); +REC_FUNC(XORI); +REC_FUNC(SLTI); +REC_FUNC(SLTIU); +#if 0*/ +static void recADDIU() { +// Rt = Rs + Im + if (!_Rt_) return; + + if (_Rs_) { + if (_Rs_ == _Rt_) { + ADD32ItoM((u32)&psxRegs.GPR.r[_Rt_], _Imm_); + } else { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + if (_Imm_) ADD32ItoR(EAX, _Imm_); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } + } else { + MOV32ItoM((u32)&psxRegs.GPR.r[_Rt_], _Imm_); + } +} + +static void recADDI() { +// Rt = Rs + Im + recADDIU(); +} + +static void recSLTI() { +// Rt = Rs < Im (signed) + if (!_Rt_) return; + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + CMP32ItoR(EAX, _Imm_); + SETL8R (EAX); + AND32ItoR(EAX, 0xff); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); +} + +static void recSLTIU() { +// Rt = Rs < Im (unsigned) + if (!_Rt_) return; + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + CMP32ItoR(EAX, _Imm_); + SETB8R (EAX); + AND32ItoR(EAX, 0xff); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); +} + +static void recANDI() { +// Rt = Rs And Im + if (!_Rt_) return; + + if (_Rs_ && _ImmU_) { + if (_Rs_ == _Rt_) { + AND32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_); + } else { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + AND32ItoR(EAX, _ImmU_); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } + } else { + XOR32RtoR(EAX, EAX); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } +} + +static void recORI() { +// Rt = Rs Or Im + if (!_Rt_) return; + + if (_Rs_) { + if (_Rs_ == _Rt_) { + OR32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_); + } else { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + if (_ImmU_) OR32ItoR (EAX, _ImmU_); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } + } else { + MOV32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_); + } +} + +static void recXORI() { +// Rt = Rs Xor Im + if (!_Rt_) return; + + if (_Rs_) { + if (_Rs_ == _Rt_) { + XOR32ItoM((u32)&psxRegs.GPR.r[_Rt_], _ImmU_); + } else { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + XOR32ItoR(EAX, _ImmU_); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } + } else { + MOV32ItoR(EAX, _ImmU_ ^ 0); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } +} +//#endif +//end of * Arithmetic with immediate operand + +/********************************************************* +* Load higher 16 bits of the first word in GPR with imm * +* Format: OP rt, immediate * +*********************************************************/ +/*REC_FUNC(LUI); +#if 0*/ +static void recLUI() { +// Rt = Imm << 16 + if (!_Rt_) return; + + MOV32ItoM((u32)&psxRegs.GPR.r[_Rt_], psxRegs.code << 16); +} +//#endif +//End of Load Higher ..... + + +/********************************************************* +* Register arithmetic * +* Format: OP rd, rs, rt * +*********************************************************/ +/* +REC_FUNC(ADD); +REC_FUNC(ADDU); +REC_FUNC(SUB); +REC_FUNC(SUBU); +REC_FUNC(AND); +REC_FUNC(OR); +REC_FUNC(XOR); +REC_FUNC(NOR); +REC_FUNC(SLT); +REC_FUNC(SLTU); + +#if 0*/ +static void recADDU() { +// Rd = Rs + Rt + if (!_Rd_) return; + + if (_Rs_ && _Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + ADD32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + } else if (_Rs_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + } else if (_Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + } else { + XOR32RtoR(EAX, EAX); + } + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recADD() { +// Rd = Rs + Rt + recADDU(); +} + +static void recSUBU() { +// Rd = Rs - Rt + if (!_Rd_) return; + + if (_Rs_ || _Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + SUB32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + } else { + XOR32RtoR(EAX, EAX); + } + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recSUB() { +// Rd = Rs - Rt + recSUBU(); +} + +static void recAND() { +// Rd = Rs And Rt + if (!_Rd_) return; + + if (_Rs_ && _Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + AND32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + } else { + XOR32RtoR(EAX, EAX); + } + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recOR() { +// Rd = Rs Or Rt + if (!_Rd_) return; + + if (_Rs_ && _Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + OR32MtoR (EAX, (u32)&psxRegs.GPR.r[_Rt_]); + } else if (_Rs_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + } else if (_Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + } else { + XOR32RtoR(EAX, EAX); + } + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recXOR() { +// Rd = Rs Xor Rt + if (!_Rd_) return; + + if (_Rs_ && _Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + XOR32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + } else if (_Rs_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + XOR32ItoR(EAX, 0); + } else if (_Rt_) { + XOR32RtoR(EAX, EAX); + XOR32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + } else { + XOR32RtoR(EAX, EAX); + } + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recNOR() { +// Rd = Rs Nor Rt + if (!_Rd_) return; + + if (_Rs_ && _Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + OR32MtoR (EAX, (u32)&psxRegs.GPR.r[_Rt_]); + NOT32R (EAX); + } else if (_Rs_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + NOT32R (EAX); + } else if (_Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + NOT32R (EAX); + } else { + MOV32ItoR(EAX, ~0); + } + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recSLT() { +// Rd = Rs < Rt (signed) + if (!_Rd_) return; + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + SETL8R (EAX); + AND32ItoR(EAX, 0xff); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recSLTU() { +// Rd = Rs < Rt (unsigned) + if (!_Rd_) return; + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + SBB32RtoR(EAX, EAX); + NEG32R (EAX); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} +//#endif +//End of * Register arithmetic + +/********************************************************* +* Register mult/div & Register trap logic * +* Format: OP rs, rt * +*********************************************************/ + +/*REC_FUNC(MULT); +REC_FUNC(MULTU); +REC_FUNC(DIV); +REC_FUNC(DIVU); +#if 0*/ +static void recMULT() { +// Lo/Hi = Rs * Rt (signed) + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + IMUL32M ((u32)&psxRegs.GPR.r[_Rt_]); + MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX); + MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX); +} + +static void recMULTU() { +// Lo/Hi = Rs * Rt (unsigned) + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + MUL32M ((u32)&psxRegs.GPR.r[_Rt_]); + MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX); + MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX); +} + +static void recDIV() { +// Lo/Hi = Rs / Rt (signed) + + MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]); + CMP32ItoR(ECX, 0); + j8Ptr[0] = JE8(0); + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + CDQ(); + IDIV32R (ECX); + MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX); + MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX); + x86SetJ8(j8Ptr[0]); +} + +static void recDIVU() { +// Lo/Hi = Rs / Rt (unsigned) + + MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rt_]); + CMP32ItoR(ECX, 0); + j8Ptr[0] = JE8(0); + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + XOR32RtoR(EDX, EDX); + DIV32R (ECX); + MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX); + MOV32RtoM((u32)&psxRegs.GPR.n.hi, EDX); + x86SetJ8(j8Ptr[0]); +} +//#endif +//End of * Register mult/div & Register trap logic + +/*REC_FUNC(LB); +REC_FUNC(LBU); +REC_FUNC(LH); +REC_FUNC(LHU); +REC_FUNC(LW); + +REC_FUNC(SB); +REC_FUNC(SH); +REC_FUNC(SW);*/ + +REC_FUNC(LWL); +REC_FUNC(LWR); +REC_FUNC(SWL); +REC_FUNC(SWR); +//#if 0 +static void recLB() { +// Rt = mem[Rs + Im] (signed) + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + if (_Imm_) ADD32ItoR(EAX, _Imm_); + PUSH32R (EAX); + CALLFunc((u32)psxMemRead8); + if (_Rt_) { + MOVSX32R8toR(EAX, EAX); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } + ADD32ItoR(ESP, 4); +} + +static void recLBU() { +// Rt = mem[Rs + Im] (unsigned) + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + if (_Imm_) ADD32ItoR(EAX, _Imm_); + PUSH32R (EAX); + CALLFunc((u32)psxMemRead8); + if (_Rt_) { + MOVZX32R8toR(EAX, EAX); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } + ADD32ItoR(ESP, 4); +} + +static void recLH() { +// Rt = mem[Rs + Im] (signed) + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + if (_Imm_) ADD32ItoR(EAX, _Imm_); + PUSH32R (EAX); + CALLFunc((u32)psxMemRead16); + if (_Rt_) { + MOVSX32R16toR(EAX, EAX); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } + ADD32ItoR(ESP, 4); +} + +static void recLHU() { +// Rt = mem[Rs + Im] (unsigned) + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + if (_Imm_) ADD32ItoR(EAX, _Imm_); + PUSH32R (EAX); + CALLFunc((u32)psxMemRead16); + if (_Rt_) { + MOVZX32R16toR(EAX, EAX); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } + ADD32ItoR(ESP, 4); +} + +static void recLW() { +// Rt = mem[Rs + Im] (unsigned) + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + if (_Imm_) ADD32ItoR(EAX, _Imm_); + PUSH32R (EAX); + CALLFunc((u32)psxMemRead32); + if (_Rt_) { + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); + } + ADD32ItoR(ESP, 4); +} +/* +void recLWL() { +} + +void recLWR() { +} +*/ +static void recSB() { +// mem[Rs + Im] = Rt + + PUSH32M ((u32)&psxRegs.GPR.r[_Rt_]); + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + if (_Imm_) ADD32ItoR(EAX, _Imm_); + PUSH32R (EAX); + CALLFunc((u32)psxMemWrite8); + ADD32ItoR(ESP, 8); +} + +static void recSH() { +// mem[Rs + Im] = Rt + + PUSH32M ((u32)&psxRegs.GPR.r[_Rt_]); + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + if (_Imm_) ADD32ItoR(EAX, _Imm_); + PUSH32R (EAX); + CALLFunc((u32)psxMemWrite16); + ADD32ItoR(ESP, 8); +} + +static void recSW() { +// mem[Rs + Im] = Rt + + PUSH32M ((u32)&psxRegs.GPR.r[_Rt_]); + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + if (_Imm_) ADD32ItoR(EAX, _Imm_); + PUSH32R (EAX); + CALLFunc((u32)psxMemWrite32); + ADD32ItoR(ESP, 8); +} +//#endif +/* +void recSWL() { +} + +void recSWR() { +} +*/ +/*REC_FUNC(SLL); +REC_FUNC(SRL); +REC_FUNC(SRA); +#if 0*/ +static void recSLL() { +// Rd = Rt << Sa + if (!_Rd_) return; + + if (_Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + if (_Sa_) SHL32ItoR(EAX, _Sa_); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); + } else { + XOR32RtoR(EAX, EAX); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); + } +} + +static void recSRL() { +// Rd = Rt >> Sa + if (!_Rd_) return; + + if (_Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + if (_Sa_) SHR32ItoR(EAX, _Sa_); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); + } else { + XOR32RtoR(EAX, EAX); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); + } +} + +static void recSRA() { +// Rd = Rt >> Sa + if (!_Rd_) return; + + if (_Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + if (_Sa_) SAR32ItoR(EAX, _Sa_); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); + } else { + XOR32RtoR(EAX, EAX); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); + } +} +//#endif + +/*REC_FUNC(SLLV); +REC_FUNC(SRLV); +REC_FUNC(SRAV); +#if 0*/ +static void recSLLV() { +// Rd = Rt << Rs + if (!_Rd_) return; + + if (_Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + if (_Rs_) { + MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]); + SHL32CLtoR(EAX); + } + } + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recSRLV() { +// Rd = Rt >> Rs + if (!_Rd_) return; + + if (_Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + if (_Rs_) { + MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]); + SHR32CLtoR(EAX); + } + } + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recSRAV() { +// Rd = Rt >> Rs + if (!_Rd_) return; + + if (_Rt_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + if (_Rs_) { + MOV32MtoR(ECX, (u32)&psxRegs.GPR.r[_Rs_]); + SAR32CLtoR(EAX); + } + } + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} +//#endif + +/*REC_SYS(SYSCALL); +REC_SYS(BREAK); + +#if 0*/ +static void recSYSCALL() { + MOV32ItoR(EAX, pc - 4); + MOV32RtoM((u32)&psxRegs.pc, EAX); + PUSH32I (branch == 1 ? 1 : 0); + PUSH32I (0x20); + CALLFunc ((u32)psxException); + ADD32ItoR(ESP, 8); + + if (!branch) branch = 2; +} + +static void recBREAK() { +} +//#endif +/* +REC_FUNC(MFHI); +REC_FUNC(MTHI); +REC_FUNC(MFLO); +REC_FUNC(MTLO); +#if 0*/ +static void recMFHI() { +// Rd = Hi + if (!_Rd_) return; + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.n.hi); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recMTHI() { +// Hi = Rs + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + MOV32RtoM((u32)&psxRegs.GPR.n.hi, EAX); +} + +static void recMFLO() { +// Rd = Lo + if (!_Rd_) return; + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.n.lo); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rd_], EAX); +} + +static void recMTLO() { +// Lo = Rs + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + MOV32RtoM((u32)&psxRegs.GPR.n.lo, EAX); +} +//#endif + +/*REC_BRANCH(J); +REC_BRANCH(JR); +REC_BRANCH(JAL); +REC_BRANCH(JALR); +REC_BRANCH(BLTZ); +REC_BRANCH(BGTZ); +REC_BRANCH(BLTZAL); +REC_BRANCH(BGEZAL); +REC_BRANCH(BNE); +REC_BRANCH(BEQ); +REC_BRANCH(BLEZ); +REC_BRANCH(BGEZ); + +#if 0*/ +static void recBLTZ() { +// Branch if Rs < 0 + + CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0); + j8Ptr[0] = JL8(0); + + MOV32ItoM((u32)&target, pc+4); + j8Ptr[1] = JMP8(0); + + x86SetJ8(j8Ptr[0]); + + MOV32ItoM((u32)&target, _Imm_ * 4 + pc); + + x86SetJ8(j8Ptr[1]); + + SetBranch(); +} + +static void recBGEZ() { +// Branch if Rs >= 0 + + CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0); + j8Ptr[0] = JGE8(0); + + MOV32ItoM((u32)&target, pc+4); + j8Ptr[1] = JMP8(0); + + x86SetJ8(j8Ptr[0]); + + MOV32ItoM((u32)&target, _Imm_ * 4 + pc); + + x86SetJ8(j8Ptr[1]); + + SetBranch(); +} + +static void recBLTZAL() { +// Branch if Rs < 0 + + CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0); + j8Ptr[0] = JL8(0); + + MOV32ItoM((u32)&target, pc+4); + j8Ptr[1] = JMP8(0); + + x86SetJ8(j8Ptr[0]); + + MOV32ItoM((u32)&target, _Imm_ * 4 + pc); + MOV32ItoM((u32)&psxRegs.GPR.r[31], pc + 4); + + x86SetJ8(j8Ptr[1]); + + SetBranch(); +} + +static void recBGEZAL() { +// Branch if Rs >= 0 + + CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0); + j8Ptr[0] = JGE8(0); + + MOV32ItoM((u32)&target, pc+4); + j8Ptr[1] = JMP8(0); + + x86SetJ8(j8Ptr[0]); + + MOV32ItoM((u32)&target, _Imm_ * 4 + pc); + MOV32ItoM((u32)&psxRegs.GPR.r[31], pc + 4); + + x86SetJ8(j8Ptr[1]); + + SetBranch(); +} + +static void recJ() { +// j target + MOV32ItoM((u32)&target, _Target_ * 4 + (pc & 0xf0000000)); + + SetBranch(); +} + +static void recJAL() { +// jal target + + MOV32ItoM((u32)&target, _Target_ * 4 + (pc & 0xf0000000)); + MOV32ItoM((u32)&psxRegs.GPR.r[31], pc + 4); + + SetBranch(); +} + +static void recJR() { +// jr Rs + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + MOV32RtoM((u32)&target, EAX); + + SetBranch(); +} + +static void recJALR() { +// jalr Rs + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + MOV32RtoM((u32)&target, EAX); + + if (_Rd_) { + MOV32ItoM((u32)&psxRegs.GPR.r[_Rd_], pc + 4); + } + + SetBranch(); +} + +static void recBEQ() { +// Branch if Rs == Rt + + if (_Rs_ == _Rt_) { + MOV32ItoM((u32)&target, _Imm_ * 4 + pc); + } else { + if (_Rs_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + } else { + XOR32RtoR(EAX, EAX); + } + CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + j8Ptr[0] = JE8(0); + + MOV32ItoM((u32)&target, pc+4); + j8Ptr[1] = JMP8(0); + + x86SetJ8(j8Ptr[0]); + + MOV32ItoM((u32)&target, _Imm_ * 4 + pc); + + x86SetJ8(j8Ptr[1]); + } + + SetBranch(); +} + +static void recBNE() { +// Branch if Rs != Rt + + if (_Rs_) { + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]); + } else { + XOR32RtoR(EAX, EAX); + } + CMP32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + j8Ptr[0] = JNE8(0); + + MOV32ItoM((u32)&target, pc+4); + j8Ptr[1] = JMP8(0); + + x86SetJ8(j8Ptr[0]); + + MOV32ItoM((u32)&target, _Imm_ * 4 + pc); + + x86SetJ8(j8Ptr[1]); + + SetBranch(); +} + +static void recBLEZ() { +// Branch if Rs <= 0 + + CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0); + j8Ptr[0] = JLE8(0); + + MOV32ItoM((u32)&target, pc+4); + j8Ptr[1] = JMP8(0); + + x86SetJ8(j8Ptr[0]); + + MOV32ItoM((u32)&target, _Imm_ * 4 + pc); + + x86SetJ8(j8Ptr[1]); + + SetBranch(); +} + +static void recBGTZ() { +// Branch if Rs > 0 + + CMP32ItoM((u32)&psxRegs.GPR.r[_Rs_], 0); + j8Ptr[0] = JG8(0); + + MOV32ItoM((u32)&target, pc+4); + j8Ptr[1] = JMP8(0); + + x86SetJ8(j8Ptr[0]); + + MOV32ItoM((u32)&target, _Imm_ * 4 + pc); + + x86SetJ8(j8Ptr[1]); + + SetBranch(); +} +//#endif + +/*REC_FUNC(MFC0); +REC_FUNC(MTC0); +REC_FUNC(CFC0); +REC_FUNC(CTC0); +REC_FUNC(RFE); +#if 0*/ +static void recMFC0() { +// Rt = Cop0->Rd + if (!_Rt_) return; + + MOV32MtoR(EAX, (u32)&psxRegs.CP0.r[_Rd_]); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); +} + +static void recCFC0() { +// Rt = Cop0->Rd + if (!_Rt_) return; + + MOV32MtoR(EAX, (u32)&psxRegs.CP0.r[_Rd_]); + MOV32RtoM((u32)&psxRegs.GPR.r[_Rt_], EAX); +} + +static void recMTC0() { +// Cop0->Rd = Rt + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + MOV32RtoM((u32)&psxRegs.CP0.r[_Rd_], EAX); +} + +static void recCTC0() { +// Cop0->Rd = Rt + + MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rt_]); + MOV32RtoM((u32)&psxRegs.CP0.r[_Rd_], EAX); +} + +static void recRFE() { + MOV32MtoR(EAX, (u32)&psxRegs.CP0.n.Status); + MOV32RtoR(ECX, EAX); + AND32ItoR(EAX, 0xfffffff0); + AND32ItoR(ECX, 0x3c); + SHR32ItoR(ECX, 2); + OR32RtoR (EAX, ECX); + MOV32RtoM((u32)&psxRegs.CP0.n.Status, EAX); +} +//#endif + +#define CP2_FUNC(f) \ +void gte##f(); \ +static void rec##f() { \ + MOV32ItoM((u32)&psxRegs.code, (u32)psxRegs.code); \ + MOV32ItoM((u32)&psxRegs.pc, (u32)pc); \ + CALLFunc ((u32)gte##f); \ +/* branch = 2; */\ +} + +CP2_FUNC(MFC2); +CP2_FUNC(MTC2); +CP2_FUNC(CFC2); +CP2_FUNC(CTC2); +CP2_FUNC(LWC2); +CP2_FUNC(SWC2); + +CP2_FUNC(RTPS); +CP2_FUNC(OP); +CP2_FUNC(NCLIP); +CP2_FUNC(DPCS); +CP2_FUNC(INTPL); +CP2_FUNC(MVMVA); +CP2_FUNC(NCDS); +CP2_FUNC(NCDT); +CP2_FUNC(CDP); +CP2_FUNC(NCCS); +CP2_FUNC(CC); +CP2_FUNC(NCS); +CP2_FUNC(NCT); +CP2_FUNC(SQR); +CP2_FUNC(DCPL); +CP2_FUNC(DPCT); +CP2_FUNC(AVSZ3); +CP2_FUNC(AVSZ4); +CP2_FUNC(RTPT); +CP2_FUNC(GPF); +CP2_FUNC(GPL); +CP2_FUNC(NCCT); + +static void recHLE() { + MOV32ItoR(EAX, (u32)psxHLEt[psxRegs.code & 0xff]); + CALL32R(EAX); + branch = 2; +} + +// + +static void (*recBSC[64])() = { + recSPECIAL, recREGIMM, recJ , recJAL , recBEQ , recBNE , recBLEZ, recBGTZ, + recADDI , recADDIU , recSLTI, recSLTIU, recANDI, recORI , recXORI, recLUI , + recCOP0 , recNULL , recCOP2, recNULL , recNULL, recNULL, recNULL, recNULL, + recNULL , recNULL , recNULL, recNULL , recNULL, recNULL, recNULL, recNULL, + recLB , recLH , recLWL , recLW , recLBU , recLHU , recLWR , recNULL, + recSB , recSH , recSWL , recSW , recNULL, recNULL, recSWR , recNULL, + recNULL , recNULL , recLWC2, recNULL , recNULL, recNULL, recNULL, recNULL, + recNULL , recNULL , recSWC2, recHLE , recNULL, recNULL, recNULL, recNULL +}; + +static void (*recSPC[64])() = { + recSLL , recNULL, recSRL , recSRA , recSLLV , recNULL , recSRLV, recSRAV, + recJR , recJALR, recNULL, recNULL, recSYSCALL, recBREAK, recNULL, recNULL, + recMFHI, recMTHI, recMFLO, recMTLO, recNULL , recNULL , recNULL, recNULL, + recMULT, recMULTU, recDIV, recDIVU, recNULL , recNULL , recNULL, recNULL, + recADD , recADDU, recSUB , recSUBU, recAND , recOR , recXOR , recNOR , + recNULL, recNULL, recSLT , recSLTU, recNULL , recNULL , recNULL, recNULL, + recNULL, recNULL, recNULL, recNULL, recNULL , recNULL , recNULL, recNULL, + recNULL, recNULL, recNULL, recNULL, recNULL , recNULL , recNULL, recNULL +}; + +static void (*recREG[32])() = { + recBLTZ , recBGEZ , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, + recNULL , recNULL , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, + recBLTZAL, recBGEZAL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, + recNULL , recNULL , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL +}; + +static void (*recCP0[32])() = { + recMFC0, recNULL, recCFC0, recNULL, recMTC0, recNULL, recCTC0, recNULL, + recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, + recRFE , recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, + recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL +}; + +static void (*recCP2[64])() = { + recBASIC, recRTPS , recNULL , recNULL, recNULL, recNULL , recNCLIP, recNULL, // 00 + recNULL , recNULL , recNULL , recNULL, recOP , recNULL , recNULL , recNULL, // 08 + recDPCS , recINTPL, recMVMVA, recNCDS, recCDP , recNULL , recNCDT , recNULL, // 10 + recNULL , recNULL , recNULL , recNCCS, recCC , recNULL , recNCS , recNULL, // 18 + recNCT , recNULL , recNULL , recNULL, recNULL, recNULL , recNULL , recNULL, // 20 + recSQR , recDCPL , recDPCT , recNULL, recNULL, recAVSZ3, recAVSZ4, recNULL, // 28 + recRTPT , recNULL , recNULL , recNULL, recNULL, recNULL , recNULL , recNULL, // 30 + recNULL , recNULL , recNULL , recNULL, recNULL, recGPF , recGPL , recNCCT // 38 +}; + +static void (*recCP2BSC[32])() = { + recMFC2, recNULL, recCFC2, recNULL, recMTC2, recNULL, recCTC2, recNULL, + recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, + recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, + recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL, recNULL +}; + +static void recRecompile() { + /* if x86Ptr reached the mem limit reset whole mem */ + if (((u32)x86Ptr - (u32)recMem) >= (RECMEM_SIZE - 0x10000)) + recReset(); + + PC_REC32(psxRegs.pc) = (u32)x86Ptr; + pc = psxRegs.pc; + + for (count=0; count<500;) { + char *p; + + p = (char *)PSXM(pc); + if (p == NULL) recError(); + psxRegs.code = *(u32 *)p; + + pc+=4; count++; + recBSC[psxRegs.code>>26](); + + if (branch) { + break; + } + } + + if (!branch) { + MOV32ItoM((u32)&psxRegs.pc, pc); + } + + /* store cycle */ + ADD32ItoM((u32)&psxRegs.cycle, count); + + branch = 0; + + RET(); +} + + +R3000Acpu psxRec = { + recInit, + recReset, + recExecute, + recExecuteBlock, + recClear, + recShutdown +}; diff --git a/PcsxSrc/ix86/ix86.c b/PcsxSrc/ix86/ix86.c new file mode 100644 index 0000000..d0775e4 --- /dev/null +++ b/PcsxSrc/ix86/ix86.c @@ -0,0 +1,966 @@ +/* + * ix86 core. + * Author: linuzappz + */ + +#include + +#include "ix86.h" + +void x86Init(char *ptr) { + x86Ptr = ptr; +} + +void x86Shutdown() { +} + +void x86SetJ8(u8 *j8) { + *j8 = ((u8*)x86Ptr - j8) - 1; +} + +void x86SetJ32(u32 *j32) { + *j32 = ((u32*)x86Ptr - j32) - 4; +} + +#define SIB 4 +#define DISP32 5 + +#define write8(val) *(unsigned char *)x86Ptr = val; x86Ptr++; +#define write16(val) *(unsigned short*)x86Ptr = val; x86Ptr+=2; +#define write32(val) *(u32 *)x86Ptr = val; x86Ptr+=4; + +/* macros helpers */ + +#define ModRM(mod, rm, reg) \ + write8((mod << 6) | (rm << 3) | (reg)); + +#define SibSB(ss, rm, index) \ + write8((ss << 6) | (rm << 3) | (index)); + +#define SET8R(cc, to) { \ + write8(0x0F); write8(cc); \ + write8((0xC0) | (to)); } + +#define J8Rel(cc, to) { \ + write8(cc); write8(to); return x86Ptr - 1; } + +#define CMOV32RtoR(cc, to, from) { \ + write8(0x0F); write8(cc); \ + ModRM(3, to, from); } + +#define CMOV32MtoR(cc, to, from) { \ + write8(0x0F); write8(cc); \ + ModRM(0, to, DISP32); \ + write32(from); } + +/********************/ +/* IX86 intructions */ +/********************/ + +// mov instructions + +/* mov r32 to r32 */ +void MOV32RtoR(int to, int from) { + write8(0x89); + ModRM(3, from, to); +} + +/* mov r32 to m32 */ +void MOV32RtoM(u32 to, int from) { + write8(0x89); + ModRM(0, from, DISP32); + write32(to); +} + +/* mov m32 to r32 */ +void MOV32MtoR(int to, u32 from) { + write8(0x8B); + ModRM(0, to, DISP32); + write32(from); +} + +/* mov [r32] to r32 */ +void MOV32RmtoR(int to, int from) { + write8(0x8B); + ModRM(0, to, from); +} + +/* mov [r32][r32*scale] to r32 */ +void MOV32RmStoR(int to, int from, int from2, int scale) { + write8(0x8B); + ModRM(0, to, 0x4); + SibSB(scale, from2, from); +} + +/* mov r32 to [r32] */ +void MOV32RtoRm(int to, int from) { + write8(0x89); + ModRM(0, from, to); +} + +/* mov imm32 to r32 */ +void MOV32ItoR(int to, u32 from) { + write8(0xB8 | to); + write32(from); +} + +/* mov imm32 to m32 */ +void MOV32ItoM(u32 to, u32 from) { + write8(0xC7); + ModRM(0, 0, DISP32); + write32(to); + write32(from); +} + +/* movsx r8 to r32 */ +void MOVSX32R8toR(int to, int from) { + write16(0xBE0F); + ModRM(3, to, from); +} + +/* movsx r16 to r32 */ +void MOVSX32R16toR(int to, int from) { + write16(0xBF0F); + ModRM(3, to, from); +} + +/* movzx r8 to r32 */ +void MOVZX32R8toR(int to, int from) { + write16(0xB60F); + ModRM(3, to, from); +} + +/* movzx r16 to r32 */ +void MOVZX32R16toR(int to, int from) { + write16(0xB70F); + ModRM(3, to, from); +} + +/* cmovne r32 to r32 */ +void CMOVNE32RtoR(int to, int from) { + CMOV32RtoR(0x45, to, from); +} + +/* cmovne m32 to r32*/ +void CMOVNE32MtoR(int to, u32 from) { + CMOV32MtoR(0x45, to, from); +} + +/* cmove r32 to r32*/ +void CMOVE32RtoR(int to, int from) { + CMOV32RtoR(0x44, to, from); +} + +/* cmove m32 to r32*/ +void CMOVE32MtoR(int to, u32 from) { + CMOV32MtoR(0x44, to, from); +} + +/* cmovg r32 to r32*/ +void CMOVG32RtoR(int to, int from) { + CMOV32RtoR(0x4F, to, from); +} + +/* cmovg m32 to r32*/ +void CMOVG32MtoR(int to, u32 from) { + CMOV32MtoR(0x4F, to, from); +} + +/* cmovge r32 to r32*/ +void CMOVGE32RtoR(int to, int from) { + CMOV32RtoR(0x4D, to, from); +} + +/* cmovge m32 to r32*/ +void CMOVGE32MtoR(int to, u32 from) { + CMOV32MtoR(0x4D, to, from); +} + +/* cmovl r32 to r32*/ +void CMOVL32RtoR(int to, int from) { + CMOV32RtoR(0x4C, to, from); +} + +/* cmovl m32 to r32*/ +void CMOVL32MtoR(int to, u32 from) { + CMOV32MtoR(0x4C, to, from); +} + +/* cmovle r32 to r32*/ +void CMOVLE32RtoR(int to, int from) { + CMOV32RtoR(0x4E, to, from); +} + +/* cmovle m32 to r32*/ +void CMOVLE32MtoR(int to, u32 from) { + CMOV32MtoR(0x4E, to, from); +} + +// arithmic instructions + +/* add imm32 to r32 */ +void ADD32ItoR(int to, u32 from) { + if (to == EAX) { + write8(0x05); + } else { + write8(0x81); + ModRM(3, 0, to); + } + write32(from); +} + +/* add imm32 to m32 */ +void ADD32ItoM(u32 to, u32 from) { + write8(0x81); + ModRM(0, 0, DISP32); + write32(to); + write32(from); +} + +/* add r32 to r32 */ +void ADD32RtoR(int to, int from) { + write8(0x01); + ModRM(3, from, to); +} + +/* add m32 to r32 */ +void ADD32MtoR(int to, u32 from) { + write8(0x03); + ModRM(0, to, DISP32); + write32(from); +} + +/* adc imm32 to r32 */ +void ADC32ItoR(int to, u32 from) { + if (to == EAX) { + write8(0x15); + } else { + write8(0x81); + ModRM(3, 2, to); + } + write32(from); +} + +/* adc r32 to r32 */ +void ADC32RtoR(int to, int from) { + write8(0x11); + ModRM(3, from, to); +} + +/* adc m32 to r32 */ +void ADC32MtoR(int to, u32 from) { + write8(0x13); + ModRM(0, to, DISP32); + write32(from); +} + +/* sub imm32 to r32 */ +void SUB32ItoR(int to, u32 from) { + if (to == EAX) { + write8(0x2D); + } else { + write8(0x81); + ModRM(3, 5, to); + } + write32(from); +} + +/* sub r32 to r32 */ +void SUB32RtoR(int to, int from) { + write8(0x29); + ModRM(3, from, to); +} + +/* sub m32 to r32 */ +void SUB32MtoR(int to, u32 from) { + write8(0x2B); + ModRM(0, to, DISP32); + write32(from); +} + +/* sbb imm32 to r32 */ +void SBB32ItoR(int to, u32 from) { + if (to == EAX) { + write8(0x1D); + } else { + write8(0x81); + ModRM(3, 3, to); + } + write32(from); +} + +/* sbb r32 to r32 */ +void SBB32RtoR(int to, int from) { + write8(0x19); + ModRM(3, from, to); +} + +/* sbb m32 to r32 */ +void SBB32MtoR(int to, u32 from) { + write8(0x1B); + ModRM(0, to, DISP32); + write32(from); +} + +/* mul eax by r32 to edx:eax */ +void MUL32R(int from) { + write8(0xF7); + ModRM(3, 4, from); +} + +/* imul eax by r32 to edx:eax */ +void IMUL32R(int from) { + write8(0xF7); + ModRM(3, 5, from); +} + +/* mul eax by m32 to edx:eax */ +void MUL32M(u32 from) { + write8(0xF7); + ModRM(0, 4, DISP32); + write32(from); +} + +/* imul eax by m32 to edx:eax */ +void IMUL32M(u32 from) { + write8(0xF7); + ModRM(0, 5, DISP32); + write32(from); +} + +/* div eax by r32 to edx:eax */ +void DIV32R(int from) { + write8(0xF7); + ModRM(3, 6, from); +} + +/* idiv eax by r32 to edx:eax */ +void IDIV32R(int from) { + write8(0xF7); + ModRM(3, 7, from); +} + +/* div eax by m32 to edx:eax */ +void DIV32M(u32 from) { + write8(0xF7); + ModRM(0, 6, DISP32); + write32(from); +} + +/* idiv eax by m32 to edx:eax */ +void IDIV32M(u32 from) { + write8(0xF7); + ModRM(0, 7, DISP32); + write32(from); +} + +// shifting instructions + +/* shl imm8 to r32 */ +void SHL32ItoR(int to, unsigned char from) { + write8(0xC1); + ModRM(3, 4, to); + write8(from); +} + +/* shl cl to r32 */ +void SHL32CLtoR(int to) { + write8(0xD3); + ModRM(3, 4, to); +} + +/* shr imm8 to r32 */ +void SHR32ItoR(int to, unsigned char from) { + write8(0xC1); + ModRM(3, 5, to); + write8(from); +} + +/* shr cl to r32 */ +void SHR32CLtoR(int to) { + write8(0xD3); + ModRM(3, 5, to); +} + +/* sar imm8 to r32 */ +void SAR32ItoR(int to, unsigned char from) { + write8(0xC1); + ModRM(3, 7, to); + write8(from); +} + +/* sar cl to r32 */ +void SAR32CLtoR(int to) { + write8(0xD3); + ModRM(3, 7, to); +} + + +// logical instructions + +/* or imm32 to r32 */ +void OR32ItoR(int to, u32 from) { + if (to == EAX) { + write8(0x0D); + } else { + write8(0x81); + ModRM(3, 1, to); + } + write32(from); +} + +/* or imm32 to m32 */ +void OR32ItoM(u32 to, u32 from) { + write8(0x81); + ModRM(0, 1, DISP32); + write32(to); + write32(from); +} + +/* or r32 to r32 */ +void OR32RtoR(int to, int from) { + write8(0x09); + ModRM(3, from, to); +} + +/* or m32 to r32 */ +void OR32MtoR(int to, u32 from) { + write8(0x0B); + ModRM(0, to, DISP32); + write32(from); +} + +/* xor imm32 to r32 */ +void XOR32ItoR(int to, u32 from) { + if (to == EAX) { + write8(0x35); + } else { + write8(0x81); + ModRM(3, 6, to); + } + write32(from); +} + +/* xor imm32 to m32 */ +void XOR32ItoM(u32 to, u32 from) { + write8(0x81); + ModRM(0, 6, DISP32); + write32(to); + write32(from); +} + +/* xor r32 to r32 */ +void XOR32RtoR(int to, int from) { + write8(0x31); + ModRM(3, from, to); +} + +/* xor m32 to r32 */ +void XOR32MtoR(int to, u32 from) { + write8(0x33); + ModRM(0, to, DISP32); + write32(from); +} + +/* and imm32 to r32 */ +void AND32ItoR(int to, u32 from) { + if (to == EAX) { + write8(0x25); + } else { + write8(0x81); + ModRM(3, 0x4, to); + } + write32(from); +} + +/* and imm32 to m32 */ +void AND32ItoM(u32 to, u32 from) { + write8(0x81); + ModRM(0, 0x4, DISP32); + write32(to); + write32(from); +} + +/* and r32 to r32 */ +void AND32RtoR(int to, int from) { + write8(0x21); + ModRM(3, from, to); +} + +/* and m32 to r32 */ +void AND32MtoR(int to, u32 from) { + write8(0x23); + ModRM(0, to, DISP32); + write32(from); +} + +/* not r32 */ +void NOT32R(int from) { + write8(0xF7); + ModRM(3, 2, from); +} + +/* neg r32 */ +void NEG32R(int from) { + write8(0xF7); + ModRM(3, 3, from); +} + +// jump instructions + +/* jmp rel8 */ +u8* JMP8(unsigned char to) { + write8(0xEB); + write8(to); + return x86Ptr - 1; +} + +/* jmp rel32 */ +u32* JMP32(u32 to) { + write8(0xE9); + write32(to); + return (u32*)(x86Ptr - 4); +} + +/* jmp r32 */ +void JMP32R(int to) { + write8(0xFF); + ModRM(3, 4, to); +} + +/* je rel8 */ +u8* JE8(unsigned char to) { + J8Rel(0x74, to); +} + +/* jz rel8 */ +u8* JZ8(unsigned char to) { + J8Rel(0x74, to); +} + +/* jg rel8 */ +u8* JG8(unsigned char to) { + J8Rel(0x7F, to); } + +/* jge rel8 */ +u8* JGE8(unsigned char to) { + J8Rel(0x7D, to); +} + +/* jl rel8 */ +u8* JL8(unsigned char to) { + J8Rel(0x7C, to); +} + +/* jle rel8 */ +u8* JLE8(unsigned char to) { + J8Rel(0x7E, to); +} + +/* jne rel8 */ +u8* JNE8(unsigned char to) { + J8Rel(0x75, to); +} + +/* jnz rel8 */ +u8* JNZ8(unsigned char to) { + J8Rel(0x75, to); +} + +/* jng rel8 */ +u8* JNG8(unsigned char to) { + J8Rel(0x7E, to); +} + +/* jnge rel8 */ +u8* JNGE8(unsigned char to) { + J8Rel(0x7C, to); +} + +/* jnl rel8 */ +u8* JNL8(unsigned char to) { + J8Rel(0x7D, to); +} + +/* jnle rel8 */ +u8* JNLE8(unsigned char to) { + J8Rel(0x7F, to); +} + +/* call func */ +void CALLFunc(u32 func) { + CALL32(func - ((u32)x86Ptr + 5)); +} + +/* call rel32 */ +void CALL32(u32 to) { + write8(0xE8); + write32(to); +} + +/* call r32 */ +void CALL32R(int to) { + write8(0xFF); + ModRM(3, 2, to); +} + +// misc instructions + +/* cmp imm32 to r32 */ +void CMP32ItoR(int to, u32 from) { + if (to == EAX) { + write8(0x3D); + } else { + write8(0x81); + ModRM(3, 7, to); + } + write32(from); +} + +/* cmp imm32 to m32 */ +void CMP32ItoM(u32 to, u32 from) { + write8(0x81); + ModRM(0, 7, DISP32); + write32(to); + write32(from); +} + +/* cmp r32 to r32 */ +void CMP32RtoR(int to, int from) { + write8(0x39); + ModRM(3, from, to); +} + +/* cmp m32 to r32 */ +void CMP32MtoR(int to, u32 from) { + write8(0x3B); + ModRM(0, to, DISP32); + write32(from); +} + +/* test imm32 to r32 */ +void TEST32ItoR(int to, u32 from) { + if (to == EAX) { + write8(0xA9); + } else { + write8(0xF7); + ModRM(3, 0, to); + } + write32(from); +} + +/* test r32 to r32 */ +void TEST32RtoR(int to, int from) { + write8(0x85); + ModRM(3, from, to); +} + +/* setl r8 */ +void SETL8R(int to) { + SET8R(0x9C, to); +} + +/* setb r8 */ +void SETB8R(int to) { + SET8R(0x92, to); +} + +/* cbw */ +void CBW() { + write16(0x9866); +} + +/* cwd */ +void CWD() { + write8(0x98); +} + +/* cdq */ +void CDQ() { + write8(0x99); +} + +/* push r32 */ +void PUSH32R(int from) { + write8(0x50 | from); +} + +/* push m32 */ +void PUSH32M(u32 from) { + write8(0xFF); + ModRM(0, 6, DISP32); + write32(from); +} + +/* push imm32 */ +void PUSH32I(u32 from) { + write8(0x68); write32(from); +} + +/* pop r32 */ +void POP32R(int from) { + write8(0x58 | from); +} + +/* pushad */ +void PUSHA32() { + write8(0x60); +} + +/* popad */ +void POPA32() { + write8(0x61); +} + +/* ret */ +void RET() { + write8(0xC3); +} + +/********************/ +/* FPU instructions */ +/********************/ + +/* fild m32 to fpu reg stack */ +void FILD32(u32 from) { + write8(0xDB); + ModRM(0, 0x0, DISP32); + write32(from); +} + +/* fistp m32 from fpu reg stack */ +void FISTP32(u32 from) { + write8(0xDB); + ModRM(0, 0x3, DISP32); + write32(from); +} + +/* fld m32 to fpu reg stack */ +void FLD32(u32 from) { + write8(0xD9); + ModRM(0, 0x0, DISP32); + write32(from); +} + +/* fstp m32 from fpu reg stack */ +void FSTP32(u32 to) { + write8(0xD9); + ModRM(0, 0x3, DISP32); + write32(to); +} + +// + +/* fldcw fpu control word from m16 */ +void FLDCW(u32 from) { + write8(0xD9); + ModRM(0, 0x5, DISP32); + write32(from); +} + +/* fnstcw fpu control word to m16 */ +void FNSTCW(u32 to) { + write8(0xD9); + ModRM(0, 0x7, DISP32); + write32(to); +} + +// + +/* fadd m32 to fpu reg stack */ +void FADD32(u32 from) { + write8(0xD8); + ModRM(0, 0x0, DISP32); + write32(from); +} + +/* fsub m32 to fpu reg stack */ +void FSUB32(u32 from) { + write8(0xD8); + ModRM(0, 0x4, DISP32); + write32(from); +} + +/* fmul m32 to fpu reg stack */ +void FMUL32(u32 from) { + write8(0xD8); + ModRM(0, 0x1, DISP32); + write32(from); +} + +/* fdiv m32 to fpu reg stack */ +void FDIV32(u32 from) { + write8(0xD8); + ModRM(0, 0x6, DISP32); + write32(from); +} + +/* fabs fpu reg stack */ +void FABS() { + write16(0xE1D9); +} + +/* fsqrt fpu reg stack */ +void FSQRT() { + write16(0xFAD9); +} + +/* fchs fpu reg stack */ +void FCHS() { + write16(0xE0D9); +} + +/********************/ +/* MMX instructions */ +/********************/ + +// r64 = mm + +/* movq m64 to r64 */ +void MOVQMtoR(int to, u32 from) { + write16(0x6F0F); + ModRM(0, to, DISP32); + write32(from); +} + +/* movq r64 to m64 */ +void MOVQRtoM(u32 to, int from) { + write16(0x7F0F); + ModRM(0, from, DISP32); + write32(to); +} + +/* pand r64 to r64 */ +void PANDRtoR(int to, int from) { + write16(0xDB0F); + ModRM(3, to, from); +} + +/* por r64 to r64 */ +void PORRtoR(int to, int from) { + write16(0xEB0F); + ModRM(3, to, from); +} + +/* por m64 to r64 */ +void PORMtoR(int to, u32 from) { + write16(0xEB0F); + ModRM(0, to, DISP32); + write32(from); +} + +/* pxor r64 to r64 */ +void PXORRtoR(int to, int from) { + write16(0xEF0F); + ModRM(3, to, from); +} + +/* psllq r64 to r64 */ +void PSLLQRtoR(int to, int from) { + write16(0xF30F); + ModRM(3, to, from); +} + +/* psllq m64 to r64 */ +void PSLLQMtoR(int to, u32 from) { + write16(0xF30F); + ModRM(0, to, DISP32); + write32(from); +} + +/* psllq imm8 to r64 */ +void PSLLQItoR(int to, unsigned char from) { + write16(0x730F); + ModRM(3, 6, to); + write8(from); +} + +/* psrlq r64 to r64 */ +void PSRLQRtoR(int to, int from) { + write16(0xD30F); + ModRM(3, to, from); +} + +/* psrlq m64 to r64 */ +void PSRLQMtoR(int to, u32 from) { + write16(0xD30F); + ModRM(0, to, DISP32); + write32(from); +} + +/* psrlq imm8 to r64 */ +void PSRLQItoR(int to, unsigned char from) { + write16(0x730F); + ModRM(3, 2, to); + write8(from); +} + +/* paddusb r64 to r64 */ +void PADDUSBRtoR(int to, int from) { + write16(0xDC0F); + ModRM(3, to, from); +} + +/* paddusb m64 to r64 */ +void PADDUSBMtoR(int to, u32 from) { + write16(0xDC0F); + ModRM(0, to, DISP32); + write32(from); +} + +/* paddusw r64 to r64 */ +void PADDUSWRtoR(int to, int from) { + write16(0xDD0F); + ModRM(3, to, from); +} + +/* paddusw m64 to r64 */ +void PADDUSWMtoR(int to, u32 from) { + write16(0xDD0F); + ModRM(0, to, DISP32); + write32(from); +} + +/* paddb r64 to r64 */ +void PADDBRtoR(int to, int from) { + write16(0xFC0F); + ModRM(3, to, from); +} + +/* paddb m64 to r64 */ +void PADDBMtoR(int to, u32 from) { + write16(0xFC0F); + ModRM(0, to, DISP32); + write32(from); +} + +/* paddw r64 to r64 */ +void PADDWRtoR(int to, int from) { + write16(0xFD0F); + ModRM(3, to, from); +} + +/* paddw m64 to r64 */ +void PADDWMtoR(int to, u32 from) { + write16(0xFD0F); + ModRM(0, to, DISP32); + write32(from); +} + +/* paddd r64 to r64 */ +void PADDDRtoR(int to, int from) { + write16(0xFE0F); + ModRM(3, to, from); +} + +/* paddd m64 to r64 */ +void PADDDMtoR(int to, u32 from) { + write16(0xFE0F); + ModRM(0, to, DISP32); + write32(from); +} + +/* emms */ +void EMMS() { + write16(0x770F); +} diff --git a/PcsxSrc/ix86/ix86.h b/PcsxSrc/ix86/ix86.h new file mode 100644 index 0000000..3f3d6cd --- /dev/null +++ b/PcsxSrc/ix86/ix86.h @@ -0,0 +1,397 @@ +/* + * ix86 definitions. + * Author: linuzappz + */ + +#ifndef __IX86_H__ +#define __IX86_H__ + +// include basic types +#include "PsxCommon.h" + +/* general defines */ + +#define EAX 0 +#define EBX 3 +#define ECX 1 +#define EDX 2 +#define ESI 6 +#define EDI 7 +#define EBP 5 +#define ESP 4 + +#define MM0 0 +#define MM1 1 +#define MM2 2 +#define MM3 3 +#define MM4 4 +#define MM5 5 +#define MM6 6 +#define MM7 7 + +s8 *x86Ptr; +u8 *j8Ptr[32]; +u32 *j32Ptr[32]; + +void x86Init(char *ptr); +void x86SetJ8(u8 *j8); +void x86SetJ32(u32 *j32); +void x86Shutdown(); + + +/********************/ +/* IX86 intructions */ +/********************/ + +/* + * scale values: + * 0 - *1 + * 1 - *2 + * 2 - *4 + * 3 - *8 + */ + +// mov instructions + +/* mov r32 to r32 */ +void MOV32RtoR(int to, int from); +/* mov r32 to m32 */ +void MOV32RtoM(u32 to, int from); +/* mov m32 to r32 */ +void MOV32MtoR(int to, u32 from); +/* mov [r32] to r32 */ +void MOV32RmtoR(int to, int from); +/* mov [r32][r32*scale] to r32 */ +void MOV32RmStoR(int to, int from, int from2, int scale); +/* mov r32 to [r32] */ +void MOV32RtoRm(int to, int from); +/* mov imm32 to r32 */ +void MOV32ItoR(int to, u32 from); +/* mov imm32 to m32 */ +void MOV32ItoM(u32 to, u32 from); + +/* movsx r8 to r32 */ +void MOVSX32R8toR(int to, int from); +/* movsx r16 to r32 */ +void MOVSX32R16toR(int to, int from); +/* movzx r8 to r32 */ +void MOVZX32R8toR(int to, int from); +/* movzx r16 to r32 */ +void MOVZX32R16toR(int to, int from); + +/* cmovne r32 to r32 */ +void CMOVNE32RtoR(int to, int from); +/* cmovne m32 to r32*/ +void CMOVNE32MtoR(int to, u32 from); +/* cmove r32 to r32*/ +void CMOVE32RtoR(int to, int from); +/* cmove m32 to r32*/ +void CMOVE32MtoR(int to, u32 from); +/* cmovg r32 to r32*/ +void CMOVG32RtoR(int to, int from); +/* cmovg m32 to r32*/ +void CMOVG32MtoR(int to, u32 from); +/* cmovge r32 to r32*/ +void CMOVGE32RtoR(int to, int from); +/* cmovge m32 to r32*/ +void CMOVGE32MtoR(int to, u32 from); +/* cmovl r32 to r32*/ +void CMOVL32RtoR(int to, int from); +/* cmovl m32 to r32*/ +void CMOVL32MtoR(int to, u32 from); +/* cmovle r32 to r32*/ +void CMOVLE32RtoR(int to, int from); +/* cmovle m32 to r32*/ +void CMOVLE32MtoR(int to, u32 from); + +// arithmic instructions + +/* add imm32 to r32 */ +void ADD32ItoR(int to, u32 from); +/* add imm32 to m32 */ +void ADD32ItoM(u32 to, u32 from); +/* add r32 to r32 */ +void ADD32RtoR(int to, int from); +/* add m32 to r32 */ +void ADD32MtoR(int to, u32 from); + +/* adc imm32 to r32 */ +void ADC32ItoR(int to, u32 from); +/* adc r32 to r32 */ +void ADC32RtoR(int to, int from); +/* adc m32 to r32 */ +void ADC32MtoR(int to, u32 from); + +/* sub imm32 to r32 */ +void SUB32ItoR(int to, u32 from); +/* sub r32 to r32 */ +void SUB32RtoR(int to, int from); +/* sub m32 to r32 */ +void SUB32MtoR(int to, u32 from); + +/* sbb imm32 to r32 */ +void SBB32ItoR(int to, u32 from); +/* sbb r32 to r32 */ +void SBB32RtoR(int to, int from); +/* sbb m32 to r32 */ +void SBB32MtoR(int to, u32 from); + +/* mul eax by r32 to edx:eax */ +void MUL32R(int from); +/* mul eax by m32 to edx:eax */ +void MUL32M(u32 from); + +/* imul eax by r32 to edx:eax */ +void IMUL32R(int from); +/* imul eax by m32 to edx:eax */ +void IMUL32M(u32 from); + +/* div eax by r32 to edx:eax */ +void DIV32R(int from); +/* div eax by m32 to edx:eax */ +void DIV32M(u32 from); + +/* idiv eax by r32 to edx:eax */ +void IDIV32R(int from); +/* idiv eax by m32 to edx:eax */ +void IDIV32M(u32 from); + +// shifting instructions + +/* shl imm8 to r32 */ +void SHL32ItoR(int to, unsigned char from); +/* shl cl to r32 */ +void SHL32CLtoR(int to); + +/* shr imm8 to r32 */ +void SHR32ItoR(int to, unsigned char from); +/* shr cl to r32 */ +void SHR32CLtoR(int to); + +/* sar imm8 to r32 */ +void SAR32ItoR(int to, unsigned char from); +/* sar cl to r32 */ +void SAR32CLtoR(int to); + +/* sal imm8 to r32 */ +#define SAL32ItoR SHL32ItoR +/* sal cl to r32 */ +#define SAL32CLtoR SHL32CLtoR + +// logical instructions + +/* or imm32 to r32 */ +void OR32ItoR(int to, u32 from); +/* or imm32 to m32 */ +void OR32ItoM(u32 to, u32 from); +/* or r32 to r32 */ +void OR32RtoR(int to, int from); +/* or m32 to r32 */ +void OR32MtoR(int to, u32 from); + +/* xor imm32 to r32 */ +void XOR32ItoR(int to, u32 from); +/* xor imm32 to m32 */ +void XOR32ItoM(u32 to, u32 from); +/* xor r32 to r32 */ +void XOR32RtoR(int to, int from); +/* xor m32 to r32 */ +void XOR32MtoR(int to, u32 from); + +/* and imm32 to r32 */ +void AND32ItoR(int to, u32 from); +/* and imm32 to m32 */ +void AND32ItoM(u32 to, u32 from); +/* and r32 to r32 */ +void AND32RtoR(int to, int from); +/* and m32 to r32 */ +void AND32MtoR(int to, u32 from); + +/* not r32 */ +void NOT32R(int from); +/* neg r32 */ +void NEG32R(int from); + +// jump instructions + +/* jmp rel8 */ +u8* JMP8(unsigned char to); +/* jmp rel32 */ +u32* JMP32(u32 to); +/* jmp r32 */ +void JMP32R(int to); + +/* je rel8 */ +u8* JE8(unsigned char to); +/* jz rel8 */ +u8* JZ8(unsigned char to); +/* jg rel8 */ +u8* JG8(unsigned char to); +/* jge rel8 */ +u8* JGE8(unsigned char to); +/* jl rel8 */ +u8* JL8(unsigned char to); +/* jle rel8 */ +u8* JLE8(unsigned char to); +/* jne rel8 */ +u8* JNE8(unsigned char to); +/* jnz rel8 */ +u8* JNZ8(unsigned char to); +/* jng rel8 */ +u8* JNG8(unsigned char to); +/* jnge rel8 */ +u8* JNGE8(unsigned char to); +/* jnl rel8 */ +u8* JNL8(unsigned char to); +/* jnle rel8 */ +u8* JNLE8(unsigned char to); + +/* call func */ +void CALLFunc(u32 func); // based on CALL32 +/* call rel32 */ +void CALL32(u32 to); +/* call r32 */ +void CALL32R(int to); + +// misc instructions + +/* cmp imm32 to r32 */ +void CMP32ItoR(int to, u32 from); +/* cmp imm32 to m32 */ +void CMP32ItoM(u32 to, u32 from); +/* cmp r32 to r32 */ +void CMP32RtoR(int to, int from); +/* cmp m32 to r32 */ +void CMP32MtoR(int to, u32 from); + +/* test imm32 to r32 */ +void TEST32ItoR(int to, u32 from); +/* test r32 to r32 */ +void TEST32RtoR(int to, int from); + +/* setl r8 */ +void SETL8R(int to); +/* setb r8 */ +void SETB8R(int to); + +/* cbw */ +void CBW(); +/* cwd */ +void CWD(); +/* cdq */ +void CDQ(); + +/* push r32 */ +void PUSH32R(int from); +/* push m32 */ +void PUSH32M(u32 from); +/* push imm32 */ +void PUSH32I(u32 from); + +/* pop r32 */ +void POP32R(int from); + +/* pushad */ +void PUSHA32(); +/* popad */ +void POPA32(); + +/* ret */ +void RET(); + +/********************/ +/* FPU instructions */ +/********************/ + +/* fild m32 to fpu reg stack */ +void FILD32(u32 from); +/* fistp m32 from fpu reg stack */ +void FISTP32(u32 from); +/* fld m32 to fpu reg stack */ +void FLD32(u32 from); +/* fstp m32 from fpu reg stack */ +void FSTP32(u32 to); + +/* fldcw fpu control word from m16 */ +void FLDCW(u32 from); +/* fstcw fpu control word to m16 */ +void FNSTCW(u32 to); + +/* fadd m32 to fpu reg stack */ +void FADD32(u32 from); +/* fsub m32 to fpu reg stack */ +void FSUB32(u32 from); +/* fmul m32 to fpu reg stack */ +void FMUL32(u32 from); +/* fdiv m32 to fpu reg stack */ +void FDIV32(u32 from); +/* fabs fpu reg stack */ +void FABS(); +/* fsqrt fpu reg stack */ +void FSQRT(); +/* fchs fpu reg stack */ +void FCHS(); + +/********************/ +/* MMX instructions */ +/********************/ + +// r64 = mm + +/* movq m64 to r64 */ +void MOVQMtoR(int to, u32 from); +/* movq r64 to m64 */ +void MOVQRtoM(u32 to, int from); + +/* pand r64 to r64 */ +void PANDRtoR(int to, int from); + +/* por r64 to r64 */ +void PORRtoR(int to, int from); +/* por m64 to r64 */ +void PORMtoR(int to, u32 from); + +/* pxor r64 to r64 */ +void PXORRtoR(int to, int from); + +/* psllq r64 to r64 */ +void PSLLQRtoR(int to, int from); +/* psllq m64 to r64 */ +void PSLLQMtoR(int to, u32 from); +/* psllq imm8 to r64 */ +void PSLLQItoR(int to, unsigned char from); + +/* psrlq r64 to r64 */ +void PSRLQRtoR(int to, int from); +/* psrlq m64 to r64 */ +void PSRLQMtoR(int to, u32 from); +/* psrlq imm8 to r64 */ +void PSRLQItoR(int to, unsigned char from); + +/* paddusb r64 to r64 */ +void PADDUSBRtoR(int to, int from); +/* paddusb m64 to r64 */ +void PADDUSBMtoR(int to, u32 from); +/* paddusw r64 to r64 */ +void PADDUSWRtoR(int to, int from); +/* paddusw m64 to r64 */ +void PADDUSWMtoR(int to, u32 from); + +/* paddb r64 to r64 */ +void PADDBRtoR(int to, int from); +/* paddb m64 to r64 */ +void PADDBMtoR(int to, u32 from); +/* paddw r64 to r64 */ +void PADDWRtoR(int to, int from); +/* paddw m64 to r64 */ +void PADDWMtoR(int to, u32 from); +/* paddd r64 to r64 */ +void PADDDRtoR(int to, int from); +/* paddd m64 to r64 */ +void PADDDMtoR(int to, u32 from); + +/* emms */ +void EMMS(); + + +#endif /* __IX86_H__ */ diff --git a/PcsxSrc/pcsxAbout.bmp b/PcsxSrc/pcsxAbout.bmp new file mode 100644 index 0000000..2e35d2f Binary files /dev/null and b/PcsxSrc/pcsxAbout.bmp differ diff --git a/PcsxSrc/plugins.c b/PcsxSrc/plugins.c new file mode 100644 index 0000000..20b88c3 --- /dev/null +++ b/PcsxSrc/plugins.c @@ -0,0 +1,678 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include + +#include "PsxCommon.h" + +#ifdef __WIN32__ +#pragma warning(disable:4244) +#endif + +#define CheckErr(func) \ + err = SysLibError(); \ + if (err != NULL) { SysMessage ("Error loading %s: %s\n",func,err); return -1; } + +#define LoadSym(dest, src, name, checkerr) \ + dest = (src) SysLoadSym(drv, name); if (checkerr == 1) CheckErr(name); \ + if (checkerr == 2) { err = SysLibError(); if (err != NULL) errval = 1; } + +static char *err; +static int errval; + +void *hGPUDriver; + +void ConfigurePlugins(); + +void CALLBACK GPU__readDataMem(unsigned long *pMem, int iSize) { + while (iSize > 0) { + *pMem = GPU_readData(); + iSize--; + pMem++; + } +} + +void CALLBACK GPU__writeDataMem(unsigned long *pMem, int iSize) { + while (iSize > 0) { + GPU_writeData(*pMem); + iSize--; + pMem++; + } +} + +void CALLBACK GPU__displayText(char *pText) { + SysPrintf("%s\n", pText); +} + +extern int StatesC; +long CALLBACK GPU__freeze(unsigned long ulGetFreezeData, GPUFreeze_t *pF) { + pF->ulFreezeVersion = 1; + if (ulGetFreezeData == 0) { + int val; + + val = GPU_readStatus(); + val = 0x04000000 | ((val >> 29) & 0x3); + GPU_writeStatus(0x04000003); + GPU_writeStatus(0x01000000); + GPU_writeData(0xa0000000); + GPU_writeData(0x00000000); + GPU_writeData(0x02000400); + GPU_writeDataMem((unsigned long*)pF->psxVRam, 0x100000/4); + GPU_writeStatus(val); + + val = pF->ulStatus; + GPU_writeStatus(0x00000000); + GPU_writeData(0x01000000); + GPU_writeStatus(0x01000000); + GPU_writeStatus(0x03000000 | ((val>>24)&0x1)); + GPU_writeStatus(0x04000000 | ((val>>29)&0x3)); + GPU_writeStatus(0x08000000 | ((val>>17)&0x3f) | ((val>>10)&0x40)); + GPU_writeData(0xe1000000 | (val&0x7ff)); + GPU_writeData(0xe6000000 | ((val>>11)&3)); + +/* GPU_writeData(0xe3000000 | pF->ulControl[0] & 0xffffff); + GPU_writeData(0xe4000000 | pF->ulControl[1] & 0xffffff); + GPU_writeData(0xe5000000 | pF->ulControl[2] & 0xffffff);*/ + return 1; + } + if (ulGetFreezeData == 1) { + int val; + + val = GPU_readStatus(); + val = 0x04000000 | ((val >> 29) & 0x3); + GPU_writeStatus(0x04000003); + GPU_writeStatus(0x01000000); + GPU_writeData(0xc0000000); + GPU_writeData(0x00000000); + GPU_writeData(0x02000400); + GPU_readDataMem((unsigned long*)pF->psxVRam, 0x100000/4); + GPU_writeStatus(val); + + pF->ulStatus = GPU_readStatus(); + +/* GPU_writeStatus(0x10000003); + pF->ulControl[0] = GPU_readData(); + GPU_writeStatus(0x10000004); + pF->ulControl[1] = GPU_readData(); + GPU_writeStatus(0x10000005); + pF->ulControl[2] = GPU_readData();*/ + return 1; + } + if(ulGetFreezeData==2) { + long lSlotNum=*((long *)pF); + char Text[32]; + + sprintf (Text, "*PCSX*: Selected State %ld", lSlotNum+1); + GPU_displayText(Text); + return 1; + } + return 0; +} + +long CALLBACK GPU__configure(void) { return 0; } +long CALLBACK GPU__test(void) { return 0; } +void CALLBACK GPU__about(void) {} +void CALLBACK GPU__makeSnapshot(void) {} +void CALLBACK GPU__keypressed(int key) {} +long CALLBACK GPU__getScreenPic(unsigned char *pMem) { return -1; } +long CALLBACK GPU__showScreenPic(unsigned char *pMem) { return -1; } + +#define LoadGpuSym1(dest, name) \ + LoadSym(GPU_##dest, GPU##dest, name, 1); + +#define LoadGpuSym0(dest, name) \ + LoadSym(GPU_##dest, GPU##dest, name, 0); \ + if (GPU_##dest == NULL) GPU_##dest = (GPU##dest) GPU__##dest; + +int LoadGPUplugin(char *GPUdll) { + void *drv; + + hGPUDriver = SysLoadLibrary(GPUdll); + if (hGPUDriver == NULL) { SysMessage ("Could Not Load GPU Plugin %s\n", GPUdll); return -1; } + drv = hGPUDriver; + LoadGpuSym1(init, "GPUinit"); + LoadGpuSym1(shutdown, "GPUshutdown"); + LoadGpuSym1(open, "GPUopen"); + LoadGpuSym1(close, "GPUclose"); + LoadGpuSym1(readData, "GPUreadData"); + LoadGpuSym0(readDataMem, "GPUreadDataMem"); + LoadGpuSym1(readStatus, "GPUreadStatus"); + LoadGpuSym1(writeData, "GPUwriteData"); + LoadGpuSym0(writeDataMem, "GPUwriteDataMem"); + LoadGpuSym1(writeStatus, "GPUwriteStatus"); + LoadGpuSym1(dmaChain, "GPUdmaChain"); + LoadGpuSym1(updateLace, "GPUupdateLace"); + LoadGpuSym0(keypressed, "GPUkeypressed"); + LoadGpuSym0(displayText, "GPUdisplayText"); + LoadGpuSym0(makeSnapshot, "GPUmakeSnapshot"); + LoadGpuSym0(freeze, "GPUfreeze"); + LoadGpuSym0(getScreenPic, "GPUgetScreenPic"); + LoadGpuSym0(showScreenPic, "GPUshowScreenPic"); + LoadGpuSym0(configure, "GPUconfigure"); + LoadGpuSym0(test, "GPUtest"); + LoadGpuSym0(about, "GPUabout"); + + return 0; +} + +void *hCDRDriver; + +long CALLBACK CDR__play(unsigned char *sector) { return 0; } +long CALLBACK CDR__stop(void) { return 0; } + +long CALLBACK CDR__getStatus(struct CdrStat *stat) { + if (cdOpenCase) stat->Status = 0x10; + else stat->Status = 0; + return 0; +} + +char* CALLBACK CDR__getDriveLetter(void) { return NULL; } +unsigned char* CALLBACK CDR__getBufferSub(void) { return NULL; } +long CALLBACK CDR__configure(void) { return 0; } +long CALLBACK CDR__test(void) { return 0; } +void CALLBACK CDR__about(void) {} + +#define LoadCdrSym1(dest, name) \ + LoadSym(CDR_##dest, CDR##dest, name, 1); + +#define LoadCdrSym0(dest, name) \ + LoadSym(CDR_##dest, CDR##dest, name, 0); \ + if (CDR_##dest == NULL) CDR_##dest = (CDR##dest) CDR__##dest; + +int LoadCDRplugin(char *CDRdll) { + void *drv; + + hCDRDriver = SysLoadLibrary(CDRdll); + if (hCDRDriver == NULL) { SysMessage ("Could Not load CDR plugin %s\n",CDRdll); return -1; } + drv = hCDRDriver; + LoadCdrSym1(init, "CDRinit"); + LoadCdrSym1(shutdown, "CDRshutdown"); + LoadCdrSym1(open, "CDRopen"); + LoadCdrSym1(close, "CDRclose"); + LoadCdrSym1(getTN, "CDRgetTN"); + LoadCdrSym1(getTD, "CDRgetTD"); + LoadCdrSym1(readTrack, "CDRreadTrack"); + LoadCdrSym1(getBuffer, "CDRgetBuffer"); + LoadCdrSym0(play, "CDRplay"); + LoadCdrSym0(stop, "CDRstop"); + LoadCdrSym0(getStatus, "CDRgetStatus"); + LoadCdrSym0(getDriveLetter, "CDRgetDriveLetter"); + LoadCdrSym0(getBufferSub, "CDRgetBufferSub"); + LoadCdrSym0(configure, "CDRconfigure"); + LoadCdrSym0(test, "CDRtest"); + LoadCdrSym0(about, "CDRabout"); + + return 0; +} + +void *hSPUDriver; + +long CALLBACK SPU__configure(void) { return 0; } +void CALLBACK SPU__about(void) {} +long CALLBACK SPU__test(void) { return 0; } + +unsigned short regArea[10000]; +unsigned short spuCtrl,spuStat,spuIrq; +unsigned long spuAddr; + +void CALLBACK SPU__writeRegister(unsigned long add,unsigned short value) { // Old Interface + unsigned long r=add&0xfff; + regArea[(r-0xc00)/2] = value; + + if(r>=0x0c00 && r<0x0d80) { + unsigned char ch=(r>>4)-0xc0; + switch(r&0x0f) {//switch voices + case 0: //left volume + SPU_setVolumeL(ch,value); + return; + case 2: //right volume + SPU_setVolumeR(ch,value); + return; + case 4: //frequency + SPU_setPitch(ch,value); + return; + case 6://start address + SPU_setAddr(ch,value); + return; + //------------------------------------------------// level +// case 8: +// s_chan[ch].ADSRX.AttackModeExp = (val&0x8000)?TRUE:FALSE; +// s_chan[ch].ADSRX.AttackRate = (float)((val>>8) & 0x007f)*1000.0f/240.0f; +// s_chan[ch].ADSRX.DecayRate = (float)((val>>4) & 0x000f)*1000.0f/240.0f; +// s_chan[ch].ADSRX.SustainLevel = (float)((val) & 0x000f); + +// return; +// case 10: +// s_chan[ch].ADSRX.SustainModeExp = (val&0x8000)?TRUE:FALSE; +// s_chan[ch].ADSRX.ReleaseModeExp = (val&0x0020)?TRUE:FALSE; +// s_chan[ch].ADSRX.SustainRate = ((float)((val>>6) & 0x007f))*R_SUSTAIN; +// s_chan[ch].ADSRX.ReleaseRate = ((float)((val) & 0x001f))*R_RELEASE; +// if(val & 0x4000) s_chan[ch].ADSRX.SustainModeDec=-1.0f; +// else s_chan[ch].ADSRX.SustainModeDec=1.0f; +// return; +// case 12: +// return; +// case 14: +// s_chan[ch].pRepeat=spuMemC+((unsigned long) val<<3); +// return; + } + return; + } + + switch(r) { + case H_SPUaddr://SPU-memory address + spuAddr = (unsigned long) value<<3; + // spuAddr=value * 8; + return; + case H_SPUdata://DATA to SPU +// spuMem[spuAddr/2] = value; +// spuAddr+=2; +// if(spuAddr>0x7ffff) spuAddr=0; + SPU_putOne(spuAddr,value); + spuAddr+=2; + return; + case H_SPUctrl://SPU control 1 + spuCtrl=value; + return; + case H_SPUstat://SPU status + spuStat=value & 0xf800; + return; + case H_SPUirqAddr://SPU irq + spuIrq = value; + return; + case H_SPUon1://start sound play channels 0-16 + SPU_startChannels1(value); + return; + case H_SPUon2://start sound play channels 16-24 + SPU_startChannels2(value); + return; + case H_SPUoff1://stop sound play channels 0-16 + SPU_stopChannels1(value); + return; + case H_SPUoff2://stop sound play channels 16-24 + SPU_stopChannels2(value); + return; + } +} + +unsigned short CALLBACK SPU__readRegister(unsigned long add) { + switch(add&0xfff) {// Old Interface + case H_SPUctrl://spu control + return spuCtrl; + case H_SPUstat://spu status + return spuStat; + case H_SPUaddr://SPU-memory address + return (unsigned short)(spuAddr>>3); + case H_SPUdata://DATA to SPU + spuAddr+=2; +// if(spuAddr>0x7ffff) spuAddr=0; +// return spuMem[spuAddr/2]; + return SPU_getOne(spuAddr); + case H_SPUirqAddr://spu irq + return spuIrq; + //case H_SPUIsOn1: + //return IsSoundOn(0,16); + //case H_SPUIsOn2: + //return IsSoundOn(16,24); + } + return regArea[((add&0xfff)-0xc00)/2]; +} + +void CALLBACK SPU__writeDMA(unsigned short val) { + SPU_putOne(spuAddr, val); + spuAddr += 2; + if (spuAddr > 0x7ffff) spuAddr = 0; +} + +unsigned short CALLBACK SPU__readDMA(void) { + unsigned short tmp = SPU_getOne(spuAddr); + spuAddr += 2; + if (spuAddr > 0x7ffff) spuAddr = 0; + return tmp; +} + +void CALLBACK SPU__writeDMAMem(unsigned short *pMem, int iSize) { + while (iSize > 0) { + SPU_writeDMA(*pMem); + iSize--; + pMem++; + } +} + +void CALLBACK SPU__readDMAMem(unsigned short *pMem, int iSize) { + while (iSize > 0) { + *pMem = SPU_readDMA(); + iSize--; + pMem++; + } +} + +void CALLBACK SPU__playADPCMchannel(xa_decode_t *xap) {} + +long CALLBACK SPU__freeze(unsigned long ulFreezeMode, SPUFreeze_t *pF) { + if (ulFreezeMode == 2) { + memset(pF, 0, 16); + strcpy((char *)pF->PluginName, "Pcsx"); + pF->PluginVersion = 1; + pF->Size = 0x200 + 0x80000 + 16 + sizeof(xa_decode_t); + + return 1; + } + if (ulFreezeMode == 1) { + unsigned long addr; + unsigned short val; + + val = SPU_readRegister(0x1f801da6); + SPU_writeRegister(0x1f801da6, 0); + SPU_readDMAMem((unsigned short *)pF->SPURam, 0x80000/2); + SPU_writeRegister(0x1f801da6, val); + + for (addr = 0x1f801c00; addr < 0x1f801e00; addr+=2) { + if (addr == 0x1f801da8) { pF->SPUPorts[addr - 0x1f801c00] = 0; continue; } + pF->SPUPorts[addr - 0x1f801c00] = SPU_readRegister(addr); + } + + return 1; + } + if (ulFreezeMode == 0) { + unsigned long addr; + unsigned short val; + unsigned short *regs = (unsigned short *)pF->SPUPorts; + + val = SPU_readRegister(0x1f801da6); + SPU_writeRegister(0x1f801da6, 0); + SPU_writeDMAMem((unsigned short *)pF->SPURam, 0x80000/2); + SPU_writeRegister(0x1f801da6, val); + + for (addr = 0x1f801c00; addr < 0x1f801e00; addr+=2) { + if (addr == 0x1f801da8) { regs++; continue; } + SPU_writeRegister(addr, *(regs++)); + } + + return 1; + } + + return 0; +} + +void CALLBACK SPU__registerCallback(void (CALLBACK *callback)(void)) {} + +#define LoadSpuSym1(dest, name) \ + LoadSym(SPU_##dest, SPU##dest, name, 1); + +#define LoadSpuSym2(dest, name) \ + LoadSym(SPU_##dest, SPU##dest, name, 2); + +#define LoadSpuSym0(dest, name) \ + LoadSym(SPU_##dest, SPU##dest, name, 0); \ + if (SPU_##dest == NULL) SPU_##dest = (SPU##dest) SPU__##dest; + +#define LoadSpuSymE(dest, name) \ + LoadSym(SPU_##dest, SPU##dest, name, errval); \ + if (SPU_##dest == NULL) SPU_##dest = (SPU##dest) SPU__##dest; + +#define LoadSpuSymN(dest, name) \ + LoadSym(SPU_##dest, SPU##dest, name, 0); \ + +int LoadSPUplugin(char *SPUdll) { + void *drv; + + hSPUDriver = SysLoadLibrary(SPUdll); + if (hSPUDriver == NULL) { SysMessage ("Could not open SPU plugin %s\n",SPUdll); return -1; } + drv = hSPUDriver; + LoadSpuSym1(init, "SPUinit"); + LoadSpuSym1(shutdown, "SPUshutdown"); + LoadSpuSym1(open, "SPUopen"); + LoadSpuSym1(close, "SPUclose"); + LoadSpuSym0(configure, "SPUconfigure"); + LoadSpuSym0(about, "SPUabout"); + LoadSpuSym0(test, "SPUtest"); + errval = 0; + LoadSpuSym2(startChannels1, "SPUstartChannels1"); + LoadSpuSym2(startChannels2, "SPUstartChannels2"); + LoadSpuSym2(stopChannels1, "SPUstopChannels1"); + LoadSpuSym2(stopChannels2, "SPUstopChannels2"); + LoadSpuSym2(putOne, "SPUputOne"); + LoadSpuSym2(getOne, "SPUgetOne"); + LoadSpuSym2(setAddr, "SPUsetAddr"); + LoadSpuSym2(setPitch, "SPUsetPitch"); + LoadSpuSym2(setVolumeL, "SPUsetVolumeL"); + LoadSpuSym2(setVolumeR, "SPUsetVolumeR"); + LoadSpuSymE(writeRegister, "SPUwriteRegister"); + LoadSpuSymE(readRegister, "SPUreadRegister"); + LoadSpuSymE(writeDMA, "SPUwriteDMA"); + LoadSpuSymE(readDMA, "SPUreadDMA"); + LoadSpuSym0(writeDMAMem, "SPUwriteDMAMem"); + LoadSpuSym0(readDMAMem, "SPUreadDMAMem"); + LoadSpuSym0(playADPCMchannel, "SPUplayADPCMchannel"); + LoadSpuSym0(freeze, "SPUfreeze"); + LoadSpuSym0(registerCallback, "SPUregisterCallback"); + LoadSpuSymN(update, "SPUupdate"); + LoadSpuSymN(async, "SPUasync"); + + return 0; +} + + +void *hPAD1Driver; +void *hPAD2Driver; + +static unsigned char buf[256]; +unsigned char stdpar[10] = { 0x00, 0x41, 0x5a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +unsigned char mousepar[8] = { 0x00, 0x12, 0x5a, 0xff, 0xff, 0xff, 0xff }; +unsigned char analogpar[6] = { 0x00, 0xff, 0x5a, 0xff, 0xff }; + +static int bufcount, bufc; + +unsigned char _PADstartPoll(PadDataS *pad) { + bufc = 0; + + switch (pad->controllerType) { + case PSE_PAD_TYPE_MOUSE: + mousepar[3] = pad->buttonStatus & 0xff; + mousepar[4] = pad->buttonStatus >> 8; + mousepar[5] = pad->moveX; + mousepar[6] = pad->moveY; + + memcpy(buf, mousepar, 7); + bufcount = 6; + break; + case PSE_PAD_TYPE_ANALOGPAD: // scph1150 + analogpar[1] = 0x73; + analogpar[3] = pad->buttonStatus & 0xff; + analogpar[4] = pad->buttonStatus >> 8; + analogpar[5] = pad->rightJoyX; + analogpar[6] = pad->rightJoyY; + analogpar[7] = pad->leftJoyX; + analogpar[8] = pad->leftJoyY; + + memcpy(buf, analogpar, 9); + bufcount = 8; + break; + case PSE_PAD_TYPE_ANALOGJOY: // scph1110 + analogpar[1] = 0x53; + analogpar[3] = pad->buttonStatus & 0xff; + analogpar[4] = pad->buttonStatus >> 8; + analogpar[5] = pad->rightJoyX; + analogpar[6] = pad->rightJoyY; + analogpar[7] = pad->leftJoyX; + analogpar[8] = pad->leftJoyY; + + memcpy(buf, analogpar, 9); + bufcount = 8; + break; + case PSE_PAD_TYPE_STANDARD: + default: + stdpar[3] = pad->buttonStatus & 0xff; + stdpar[4] = pad->buttonStatus >> 8; + + memcpy(buf, stdpar, 5); + bufcount = 4; + } + + return buf[bufc++]; +} + +unsigned char _PADpoll(unsigned char value) { + if (bufc > bufcount) return 0; + return buf[bufc++]; +} + +unsigned char CALLBACK PAD1__startPoll(int pad) { + PadDataS padd; + + PAD1_readPort1(&padd); + + return _PADstartPoll(&padd); +} + +unsigned char CALLBACK PAD1__poll(unsigned char value) { + return _PADpoll(value); +} + +long CALLBACK PAD1__configure(void) { return 0; } +void CALLBACK PAD1__about(void) {} +long CALLBACK PAD1__test(void) { return 0; } +long CALLBACK PAD1__query(void) { return 3; } +long CALLBACK PAD1__keypressed() { return 0; } + +#define LoadPad1Sym1(dest, name) \ + LoadSym(PAD1_##dest, PAD##dest, name, 1); + +#define LoadPad1Sym0(dest, name) \ + LoadSym(PAD1_##dest, PAD##dest, name, 0); \ + if (PAD1_##dest == NULL) PAD1_##dest = (PAD##dest) PAD1__##dest; + +int LoadPAD1plugin(char *PAD1dll) { + void *drv; + + hPAD1Driver = SysLoadLibrary(PAD1dll); + if (hPAD1Driver == NULL) { SysMessage ("Could Not load PAD1 plugin %s\n",PAD1dll); return -1; } + drv = hPAD1Driver; + LoadPad1Sym1(init, "PADinit"); + LoadPad1Sym1(shutdown, "PADshutdown"); + LoadPad1Sym1(open, "PADopen"); + LoadPad1Sym1(close, "PADclose"); + LoadPad1Sym0(query, "PADquery"); + LoadPad1Sym1(readPort1, "PADreadPort1"); + LoadPad1Sym0(configure, "PADconfigure"); + LoadPad1Sym0(test, "PADtest"); + LoadPad1Sym0(about, "PADabout"); + LoadPad1Sym0(keypressed, "PADkeypressed"); + LoadPad1Sym0(startPoll, "PADstartPoll"); + LoadPad1Sym0(poll, "PADpoll"); + + return 0; +} + +unsigned char CALLBACK PAD2__startPoll(int pad) { + PadDataS padd; + + PAD2_readPort2(&padd); + + return _PADstartPoll(&padd); +} + +unsigned char CALLBACK PAD2__poll(unsigned char value) { + return _PADpoll(value); +} + +long CALLBACK PAD2__configure(void) { return 0; } +void CALLBACK PAD2__about(void) {} +long CALLBACK PAD2__test(void) { return 0; } +long CALLBACK PAD2__query(void) { return 3; } +long CALLBACK PAD2__keypressed() { return 0; } + +#define LoadPad2Sym1(dest, name) \ + LoadSym(PAD2_##dest, PAD##dest, name, 1); + +#define LoadPad2Sym0(dest, name) \ + LoadSym(PAD2_##dest, PAD##dest, name, 0); \ + if (PAD2_##dest == NULL) PAD2_##dest = (PAD##dest) PAD2__##dest; + +int LoadPAD2plugin(char *PAD2dll) { + void *drv; + + hPAD2Driver = SysLoadLibrary(PAD2dll); + if (hPAD2Driver == NULL) { SysMessage ("Could Not load PAD plugin %s\n",PAD2dll); return -1; } + drv = hPAD2Driver; + LoadPad2Sym1(init, "PADinit"); + LoadPad2Sym1(shutdown, "PADshutdown"); + LoadPad2Sym1(open, "PADopen"); + LoadPad2Sym1(close, "PADclose"); + LoadPad2Sym0(query, "PADquery"); + LoadPad2Sym1(readPort2, "PADreadPort2"); + LoadPad2Sym0(configure, "PADconfigure"); + LoadPad2Sym0(test, "PADtest"); + LoadPad2Sym0(about, "PADabout"); + LoadPad2Sym0(keypressed, "PADkeypressed"); + LoadPad2Sym0(startPoll, "PADstartPoll"); + LoadPad2Sym0(poll, "PADpoll"); + + return 0; +} + + +/*long PAD2__readBuffer() { + return PAD2_readBuffer(); +}*/ + +int LoadPlugins() { + int ret; + char Plugin[256]; + + sprintf(Plugin, "%s%s", Config.PluginsDir, Config.Cdr); + if (LoadCDRplugin(Plugin) == -1) return -1; + sprintf(Plugin, "%s%s", Config.PluginsDir, Config.Gpu); + if (LoadGPUplugin(Plugin) == -1) return -1; + sprintf(Plugin, "%s%s", Config.PluginsDir, Config.Spu); + if (LoadSPUplugin(Plugin) == -1) return -1; + sprintf(Plugin, "%s%s", Config.PluginsDir, Config.Pad1); + if (LoadPAD1plugin(Plugin) == -1) return -1; + sprintf(Plugin, "%s%s", Config.PluginsDir, Config.Pad2); + if (LoadPAD2plugin(Plugin) == -1) return -1; + ret = CDR_init(); + if (ret != 0) { SysMessage ("CDRinit error : %d\n",ret); return -1; } + ret = GPU_init(); + if (ret != 0) { SysMessage ("GPUinit error : %d\n",ret); return -1; } + ret = SPU_init(); + if (ret != 0) { SysMessage ("SPUinit error : %d\n",ret); return -1; } + ret = PAD1_init(1); + if (ret != 0) { SysMessage ("PAD1init error : %d\n",ret); return -1; } + ret = PAD2_init(2); + if (ret != 0) { SysMessage ("PAD2init error : %d\n",ret); return -1; } + + return 0; +} + +void ReleasePlugins() { + if (hCDRDriver == NULL || hGPUDriver == NULL || hSPUDriver == NULL || + hPAD1Driver == NULL || hPAD2Driver == NULL) return; + CDR_shutdown(); + GPU_shutdown(); + SPU_shutdown(); + PAD1_shutdown(); + PAD2_shutdown(); + SysCloseLibrary(hCDRDriver); hCDRDriver = NULL; + SysCloseLibrary(hGPUDriver); hGPUDriver = NULL; + SysCloseLibrary(hSPUDriver); hSPUDriver = NULL; + SysCloseLibrary(hPAD1Driver); hPAD1Driver = NULL; + SysCloseLibrary(hPAD2Driver); hPAD2Driver = NULL; +} diff --git a/PcsxSrc/plugins.h b/PcsxSrc/plugins.h new file mode 100644 index 0000000..040df1c --- /dev/null +++ b/PcsxSrc/plugins.h @@ -0,0 +1,269 @@ +/* Pcsx - Pc Psx Emulator + * Copyright (C) 1999-2002 Pcsx Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __PLUGINS_H__ +#define __PLUGINS_H__ + +#if defined (__WIN32__) +#include "Win32\plugin.h" +#elif defined(__LINUX__) +typedef void* HWND; +#include "Linux/Plugin.h" +#endif + +#include "PSEmu_Plugin_Defs.h" +#include "Decode_XA.h" + +int LoadPlugins(); +void ReleasePlugins(); +void OpenPlugins(); +void ClosePlugins(); +void ResetPlugins(); + +#ifdef __LINUX__ +#define CALLBACK +#endif + +typedef unsigned long (CALLBACK* PSEgetLibType)(void); +typedef unsigned long (CALLBACK* PSEgetLibVersion)(void); +typedef char *(CALLBACK* PSEgetLibName)(void); + +///GPU PLUGIN STUFF +typedef long (CALLBACK* GPUinit)(void); +typedef long (CALLBACK* GPUshutdown)(void); +typedef long (CALLBACK* GPUclose)(void); +typedef void (CALLBACK* GPUwriteStatus)(unsigned long); +typedef void (CALLBACK* GPUwriteData)(unsigned long); +typedef void (CALLBACK* GPUwriteDataMem)(unsigned long *, int); +typedef unsigned long (CALLBACK* GPUreadStatus)(void); +typedef unsigned long (CALLBACK* GPUreadData)(void); +typedef void (CALLBACK* GPUreadDataMem)(unsigned long *, int); +typedef long (CALLBACK* GPUdmaChain)(unsigned long *,unsigned long); +typedef void (CALLBACK* GPUupdateLace)(void); +typedef long (CALLBACK* GPUconfigure)(void); +typedef long (CALLBACK* GPUtest)(void); +typedef void (CALLBACK* GPUabout)(void); +typedef void (CALLBACK* GPUmakeSnapshot)(void); +typedef void (CALLBACK* GPUkeypressed)(int); +typedef void (CALLBACK* GPUdisplayText)(char *); +typedef struct { + unsigned long ulFreezeVersion; + unsigned long ulStatus; + unsigned long ulControl[256]; + unsigned char psxVRam[1024*512*2]; +} GPUFreeze_t; +typedef long (CALLBACK* GPUfreeze)(unsigned long, GPUFreeze_t *); +typedef long (CALLBACK* GPUgetScreenPic)(unsigned char *); +typedef long (CALLBACK* GPUshowScreenPic)(unsigned char *); + +//plugin stuff From Shadow +// *** walking in the valley of your darking soul i realize that i was alone +//Gpu function pointers +GPUupdateLace GPU_updateLace; +GPUinit GPU_init; +GPUshutdown GPU_shutdown; +GPUconfigure GPU_configure; +GPUtest GPU_test; +GPUabout GPU_about; +GPUopen GPU_open; +GPUclose GPU_close; +GPUreadStatus GPU_readStatus; +GPUreadData GPU_readData; +GPUreadDataMem GPU_readDataMem; +GPUwriteStatus GPU_writeStatus; +GPUwriteData GPU_writeData; +GPUwriteDataMem GPU_writeDataMem; +GPUdmaChain GPU_dmaChain; +GPUkeypressed GPU_keypressed; +GPUdisplayText GPU_displayText; +GPUmakeSnapshot GPU_makeSnapshot; +GPUfreeze GPU_freeze; +GPUgetScreenPic GPU_getScreenPic; +GPUshowScreenPic GPU_showScreenPic; + +//cd rom plugin ;) +typedef long (CALLBACK* CDRinit)(void); +typedef long (CALLBACK* CDRshutdown)(void); +typedef long (CALLBACK* CDRopen)(void); +typedef long (CALLBACK* CDRclose)(void); +typedef long (CALLBACK* CDRgetTN)(unsigned char *); +typedef long (CALLBACK* CDRgetTD)(unsigned char , unsigned char *); +typedef long (CALLBACK* CDRreadTrack)(unsigned char *); +typedef unsigned char * (CALLBACK* CDRgetBuffer)(void); +typedef long (CALLBACK* CDRconfigure)(void); +typedef long (CALLBACK* CDRtest)(void); +typedef void (CALLBACK* CDRabout)(void); +typedef long (CALLBACK* CDRplay)(unsigned char *); +typedef long (CALLBACK* CDRstop)(void); +struct CdrStat { + unsigned long Type; + unsigned long Status; + unsigned char Time[3]; +}; +typedef long (CALLBACK* CDRgetStatus)(struct CdrStat *); +typedef char* (CALLBACK* CDRgetDriveLetter)(void); +struct SubQ { + char res0[11]; + unsigned char ControlAndADR; + unsigned char TrackNumber; + unsigned char IndexNumber; + unsigned char TrackRelativeAddress[3]; + unsigned char Filler; + unsigned char AbsoluteAddress[3]; + char res1[72]; +}; +typedef unsigned char* (CALLBACK* CDRgetBufferSub)(void); + +//cd rom function pointers +CDRinit CDR_init; +CDRshutdown CDR_shutdown; +CDRopen CDR_open; +CDRclose CDR_close; +CDRtest CDR_test; +CDRgetTN CDR_getTN; +CDRgetTD CDR_getTD; +CDRreadTrack CDR_readTrack; +CDRgetBuffer CDR_getBuffer; +CDRplay CDR_play; +CDRstop CDR_stop; +CDRgetStatus CDR_getStatus; +CDRgetDriveLetter CDR_getDriveLetter; +CDRgetBufferSub CDR_getBufferSub; +CDRconfigure CDR_configure; +CDRabout CDR_about; + +// spu plugin +typedef long (CALLBACK* SPUinit)(void); +typedef long (CALLBACK* SPUshutdown)(void); +typedef long (CALLBACK* SPUclose)(void); +typedef void (CALLBACK* SPUplaySample)(unsigned char); +typedef void (CALLBACK* SPUstartChannels1)(unsigned short); +typedef void (CALLBACK* SPUstartChannels2)(unsigned short); +typedef void (CALLBACK* SPUstopChannels1)(unsigned short); +typedef void (CALLBACK* SPUstopChannels2)(unsigned short); +typedef void (CALLBACK* SPUputOne)(unsigned long,unsigned short); +typedef unsigned short (CALLBACK* SPUgetOne)(unsigned long); +typedef void (CALLBACK* SPUsetAddr)(unsigned char, unsigned short); +typedef void (CALLBACK* SPUsetPitch)(unsigned char, unsigned short); +typedef void (CALLBACK* SPUsetVolumeL)(unsigned char, short ); +typedef void (CALLBACK* SPUsetVolumeR)(unsigned char, short ); +//psemu pro 2 functions from now.. +typedef void (CALLBACK* SPUwriteRegister)(unsigned long, unsigned short); +typedef unsigned short (CALLBACK* SPUreadRegister)(unsigned long); +typedef void (CALLBACK* SPUwriteDMA)(unsigned short); +typedef unsigned short (CALLBACK* SPUreadDMA)(void); +typedef void (CALLBACK* SPUwriteDMAMem)(unsigned short *, int); +typedef void (CALLBACK* SPUreadDMAMem)(unsigned short *, int); +typedef void (CALLBACK* SPUplayADPCMchannel)(xa_decode_t *); +typedef void (CALLBACK* SPUregisterCallback)(void (CALLBACK *callback)(void)); +typedef long (CALLBACK* SPUconfigure)(void); +typedef long (CALLBACK* SPUtest)(void); +typedef void (CALLBACK* SPUabout)(void); +typedef struct { + unsigned char PluginName[8]; + unsigned long PluginVersion; + unsigned long Size; + unsigned char SPUPorts[0x200]; + unsigned char SPURam[0x80000]; + xa_decode_t xa; + unsigned char *SPUInfo; +} SPUFreeze_t; +typedef long (CALLBACK* SPUfreeze)(unsigned long, SPUFreeze_t *); +typedef void (CALLBACK* SPUupdate)(void); +typedef void (CALLBACK* SPUasync)(unsigned long); + +//SPU POINTERS +SPUconfigure SPU_configure; +SPUabout SPU_about; +SPUinit SPU_init; +SPUshutdown SPU_shutdown; +SPUtest SPU_test; +SPUopen SPU_open; +SPUclose SPU_close; +SPUplaySample SPU_playSample; +SPUstartChannels1 SPU_startChannels1; +SPUstartChannels2 SPU_startChannels2; +SPUstopChannels1 SPU_stopChannels1; +SPUstopChannels2 SPU_stopChannels2; +SPUputOne SPU_putOne; +SPUgetOne SPU_getOne; +SPUsetAddr SPU_setAddr; +SPUsetPitch SPU_setPitch; +SPUsetVolumeL SPU_setVolumeL; +SPUsetVolumeR SPU_setVolumeR; +SPUwriteRegister SPU_writeRegister; +SPUreadRegister SPU_readRegister; +SPUwriteDMA SPU_writeDMA; +SPUreadDMA SPU_readDMA; +SPUwriteDMAMem SPU_writeDMAMem; +SPUreadDMAMem SPU_readDMAMem; +SPUplayADPCMchannel SPU_playADPCMchannel; +SPUfreeze SPU_freeze; +SPUregisterCallback SPU_registerCallback; +SPUupdate SPU_update; +SPUasync SPU_async; + +// PAD Functions + +typedef long (CALLBACK* PADconfigure)(void); +typedef void (CALLBACK* PADabout)(void); +typedef long (CALLBACK* PADinit)(long); +typedef long (CALLBACK* PADshutdown)(void); +typedef long (CALLBACK* PADtest)(void); +typedef long (CALLBACK* PADclose)(void); +typedef long (CALLBACK* PADquery)(void); +typedef long (CALLBACK* PADreadPort1)(PadDataS*); +typedef long (CALLBACK* PADreadPort2)(PadDataS*); +typedef long (CALLBACK* PADkeypressed)(void); +typedef unsigned char (CALLBACK* PADstartPoll)(int); +typedef unsigned char (CALLBACK* PADpoll)(unsigned char); + +//PAD POINTERS +PADconfigure PAD1_configure; +PADabout PAD1_about; +PADinit PAD1_init; +PADshutdown PAD1_shutdown; +PADtest PAD1_test; +PADopen PAD1_open; +PADclose PAD1_close; +PADquery PAD1_query; +PADreadPort1 PAD1_readPort1; +PADkeypressed PAD1_keypressed; +PADstartPoll PAD1_startPoll; +PADpoll PAD1_poll; + +PADconfigure PAD2_configure; +PADabout PAD2_about; +PADinit PAD2_init; +PADshutdown PAD2_shutdown; +PADtest PAD2_test; +PADopen PAD2_open; +PADclose PAD2_close; +PADquery PAD2_query; +PADreadPort2 PAD2_readPort2; +PADkeypressed PAD2_keypressed; +PADstartPoll PAD2_startPoll; +PADpoll PAD2_poll; + +int LoadCDRplugin(char *CDRdll); +int LoadGPUplugin(char *GPUdll); +int LoadSPUplugin(char *SPUdll); +int LoadPAD1plugin(char *PAD1dll); +int LoadPAD2plugin(char *PAD2dll); + +#endif /* __PLUGINS_H__ */ -- cgit v1.2.3