From e3c3ead90279ecfabebe075aa17d112c595488bf Mon Sep 17 00:00:00 2001 From: tearex Date: Sun, 11 Jun 2006 15:49:38 +0000 Subject: [PATCH] Illegal opcodes support Separate NMOS 6502 and CMOS 65C02 support CPU flag handling improvement NMI support Apple II (original model) support Apple II/IIPlus mode font improvement "M" glyph improvement Small _M14 / CLK_6502 fix. Reset behavior improvement Small monochrome video improvement - mono text now honors color selection just like mono graphics. --- AppleWin/Applewin.vcproj | 3 + AppleWin/ApplewinExpress.vcproj | 6 +- AppleWin/resource/Apple2orig.rom | Bin 0 -> 20480 bytes .../resource/{Apple2.rom => Apple2plus.rom} | Bin AppleWin/resource/Applewin.rc | 53 +- AppleWin/resource/CHARSET4.BMP | Bin 16446 -> 24638 bytes AppleWin/resource/resource.h | 5 +- AppleWin/source/Applewin.cpp | 6 +- AppleWin/source/Applewin.h | 1 + AppleWin/source/CPU.cpp | 1973 +++++++++++------ AppleWin/source/CPU.h | 7 +- AppleWin/source/Common.h | 4 +- AppleWin/source/Debugger_Assembler.cpp | 265 ++- AppleWin/source/Debugger_Help.cpp | 2 +- AppleWin/source/Frame.cpp | 17 +- AppleWin/source/Keyboard.cpp | 49 +- AppleWin/source/Memory.cpp | 10 +- AppleWin/source/Mockingboard.cpp | 18 +- AppleWin/source/PropertySheetPage.cpp | 7 +- AppleWin/source/Video.cpp | 39 +- 20 files changed, 1584 insertions(+), 881 deletions(-) create mode 100644 AppleWin/resource/Apple2orig.rom rename AppleWin/resource/{Apple2.rom => Apple2plus.rom} (100%) diff --git a/AppleWin/Applewin.vcproj b/AppleWin/Applewin.vcproj index c0cf1ef0..8c48bde1 100644 --- a/AppleWin/Applewin.vcproj +++ b/AppleWin/Applewin.vcproj @@ -358,6 +358,9 @@ + + diff --git a/AppleWin/ApplewinExpress.vcproj b/AppleWin/ApplewinExpress.vcproj index 0b1c78e5..7534a100 100644 --- a/AppleWin/ApplewinExpress.vcproj +++ b/AppleWin/ApplewinExpress.vcproj @@ -1,7 +1,7 @@ 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 literal 0 HcmV?d00001 diff --git a/AppleWin/resource/Apple2.rom b/AppleWin/resource/Apple2plus.rom similarity index 100% rename from AppleWin/resource/Apple2.rom rename to AppleWin/resource/Apple2plus.rom diff --git a/AppleWin/resource/Applewin.rc b/AppleWin/resource/Applewin.rc index b3de36cd..92e7111f 100644 --- a/AppleWin/resource/Applewin.rc +++ b/AppleWin/resource/Applewin.rc @@ -46,6 +46,23 @@ END #endif // APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDS_TFE_CAPTION "Ethernet Settings" + IDS_TFE_ETHERNET "Ethernet" + IDS_TFE_INTERFACE "Interface" +END + +STRINGTABLE +BEGIN + IDS_OK "OK" + IDS_CANCEL "Cancel" +END ///////////////////////////////////////////////////////////////////////////// // @@ -199,8 +216,8 @@ BEGIN GROUPBOX "Harddisk Controller",IDC_STATIC,2,113,205,71 END -IDD_TFE_SETTINGS_DIALOG DIALOG 0, 0, 270, 100 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +IDD_TFE_SETTINGS_DIALOG DIALOG DISCARDABLE 0, 0, 270, 100 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Ethernet Settings" FONT 8, "MS Sans Serif" BEGIN @@ -216,7 +233,6 @@ BEGIN PUSHBUTTON "Cancel",IDCANCEL,80,75,50,14 END - ///////////////////////////////////////////////////////////////////////////// // // Icon @@ -233,8 +249,8 @@ DISK_ICON ICON "DISK.ICO" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,13,1,0 - PRODUCTVERSION 1,13,1,0 + FILEVERSION 1,12,9,2 + PRODUCTVERSION 1,12,9,2 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -252,12 +268,12 @@ BEGIN VALUE "Comments", "http://applewin.berlios.de" VALUE "CompanyName", "Michael O'Brien, Oliver Schmidt, Tom Charlesworth" VALUE "FileDescription", "Apple //e Emulator for Windows" - VALUE "FileVersion", "1, 13, 1, 0" + VALUE "FileVersion", "1, 12, 9, 2" VALUE "InternalName", "APPLEWIN" VALUE "LegalCopyright", "© 1994-2006 Michael O'Brien, Oliver Schmidt, Tom Charlesworth, Michael Pohoreski" VALUE "OriginalFilename", "APPLEWIN.EXE" VALUE "ProductName", "Apple //e Emulator" - VALUE "ProductVersion", "1, 13, 1, 0" + VALUE "ProductVersion", "1, 12, 9, 2" END END BLOCK "VarFileInfo" @@ -286,12 +302,14 @@ END IDR_HDDRVR FIRMWARE "Hddrvr.bin" + ///////////////////////////////////////////////////////////////////////////// // // ROM // -IDR_APPLE2_ROM ROM "Apple2.rom" +IDR_APPLE2ORIG_ROM ROM "Apple2orig.rom" +IDR_APPLE2PLUS_ROM ROM "Apple2plus.rom" IDR_APPLE2E_ROM ROM "Apple2e.rom" ///////////////////////////////////////////////////////////////////////////// @@ -324,25 +342,6 @@ BEGIN END END - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE -BEGIN - IDS_TFE_CAPTION "Ethernet Settings" - IDS_TFE_ETHERNET "Ethernet" - IDS_TFE_INTERFACE "Interface" -END - -STRINGTABLE -BEGIN - IDS_OK "OK" - IDS_CANCEL "Cancel" -END - #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/AppleWin/resource/CHARSET4.BMP b/AppleWin/resource/CHARSET4.BMP index 61d19a1c017c4d9a2d75b57fc930209c844d29aa..b449f1cfde4db50d404a2b1216a84ae2b82439ef 100644 GIT binary patch delta 413 zcmdnjz_{-Kql%NST>=9b*a1lm5Q`CrnL!kY0R#z?6IsNV|NsBLxt8NT^W+#drO9>A2#n}nZ?9tJUNoRp2_CJ}dyq@XI`N^}y?U)YpZ= 0x1FF) ? (regs.sp = 0x100) : ++regs.sp))) -#define PUSH(a) *(mem+regs.sp--) = (a); \ - if (regs.sp < 0x100) \ - regs.sp = 0x1FF; -#define READ ( \ - ((addr & 0xFF00) == 0xC000) \ - ? ioread[addr & 0xFF](regs.pc,(BYTE)addr,0,0,nInternalCyclesLeft) \ - : ( \ - (((addr & 0xFF00) == 0xC400) || ((addr & 0xFF00) == 0xC500)) \ - ? CxReadFunc(regs.pc, addr, 0, 0, nInternalCyclesLeft) \ - : *(mem+addr) \ - ) \ - ) -#define SETNZ(a) { \ - flagn = ((a) & 0x80); \ - flagz = !(a & 0xFF); \ - } -#define SETZ(a) flagz = !(a & 0xFF); -#define TOBCD(a) (((((a)/10) % 10) << 4) | ((a) % 10)) -#define TOBIN(a) (((a) >> 4)*10 + ((a) & 0x0F)) -#define WRITE(a) { \ - memdirty[addr >> 8] = 0xFF; \ - LPBYTE page = memwrite[0][addr >> 8]; \ - if (page) \ - *(page+(addr & 0xFF)) = (BYTE)(a); \ - else if ((addr & 0xFF00) == 0xC000) \ - iowrite[addr & 0xFF](regs.pc,(BYTE)addr,1,(BYTE)(a),nInternalCyclesLeft); \ - else if(((addr & 0xFF00) == 0xC400) || ((addr & 0xFF00) == 0xC500)) \ - CxWriteFunc(regs.pc, addr, 1, (BYTE)(a), nInternalCyclesLeft); \ - } +#define CYC(a) cycles += (a)+uExtraCycles; MB_UpdateCycles((a)+uExtraCycles); +#define POP (*(mem+((regs.sp >= 0x1FF) ? (regs.sp = 0x100) : ++regs.sp))) +#define PUSH(a) *(mem+regs.sp--) = (a); \ + if (regs.sp < 0x100) \ + regs.sp = 0x1FF; +#define READ ( \ + ((addr & 0xFF00) == 0xC000) \ + ? ioread[addr & 0xFF](regs.pc,(BYTE)addr,0,0,nInternalCyclesLeft) \ + : ( \ + (((addr & 0xFF00) == 0xC400) || ((addr & 0xFF00) == 0xC500)) \ + ? CxReadFunc(regs.pc, addr, 0, 0, nInternalCyclesLeft) \ + : *(mem+addr) \ + ) \ + ) +#define SETNZ(a) { \ + flagn = ((a) & 0x80); \ + flagz = !((a) & 0xFF); \ + } +#define SETZ(a) flagz = !((a) & 0xFF); +#define WRITE(a) { \ + memdirty[addr >> 8] = 0xFF; \ + LPBYTE page = memwrite[0][addr >> 8]; \ + if (page) \ + *(page+(addr & 0xFF)) = (BYTE)(a); \ + else if ((addr & 0xFF00) == 0xC000) \ + iowrite[addr & 0xFF](regs.pc,(BYTE)addr,1,(BYTE)(a),nInternalCyclesLeft); \ + else if(((addr & 0xFF00) == 0xC400) || ((addr & 0xFF00) == 0xC500)) \ + CxWriteFunc(regs.pc, addr, 1, (BYTE)(a), nInternalCyclesLeft); \ + } // -#define CLKS_BRANCH 2 - // ExtraCycles: // +1 if branch taken // +1 if page boundary crossed -#define BRANCH_TAKEN { \ - base = regs.pc; \ - regs.pc += addr; \ - if ((base ^ regs.pc) & 0xFF00) \ - uExtraCycles=2; \ - else \ - uExtraCycles=1; \ - } +#define BRANCH_TAKEN { \ + base = regs.pc; \ + regs.pc += addr; \ + if ((base ^ regs.pc) & 0xFF00) \ + uExtraCycles=2; \ + else \ + uExtraCycles=1; \ + } // -#define CHECK_PAGE_CHANGE if (!bWrtMem) { \ - if ((base ^ addr) & 0xFF00) \ - uExtraCycles=1; \ - } +#define CHECK_PAGE_CHANGE if (bSlowerOnPagecross) { \ + if ((base ^ addr) & 0xFF00) \ + uExtraCycles=1; \ + } /**************************************************************************** * @@ -197,19 +213,42 @@ static volatile UINT32 g_bmIRQ = 0; * ***/ -#define ABS addr = *(LPWORD)(mem+regs.pc); regs.pc += 2; -#define ABSIINDX addr = *(LPWORD)(mem+(*(LPWORD)(mem+regs.pc))+(WORD)regs.x); regs.pc += 2; -#define ABSX base = (*(LPWORD)(mem+regs.pc)); addr = base+(WORD)regs.x; regs.pc += 2; CHECK_PAGE_CHANGE; -#define ABSY base = (*(LPWORD)(mem+regs.pc)); addr = base+(WORD)regs.y; regs.pc += 2; CHECK_PAGE_CHANGE; -#define IABS addr = *(LPWORD)(mem+*(LPWORD)(mem+regs.pc)); regs.pc += 2; -#define IMM addr = regs.pc++; -#define INDX addr = *(LPWORD)(mem+(((*(mem+regs.pc++))+regs.x) & 0xFF)); -#define INDY base = (*(LPWORD)(mem+*(mem+regs.pc++))); addr = base+(WORD)regs.y; CHECK_PAGE_CHANGE; -#define IZPG addr = *(LPWORD)(mem+*(mem+regs.pc++)); -#define REL addr = (signed char)*(mem+regs.pc++); -#define ZPG addr = *(mem+regs.pc++); -#define ZPGX addr = ((*(mem+regs.pc++))+regs.x) & 0xFF; -#define ZPGY addr = ((*(mem+regs.pc++))+regs.y) & 0xFF; +#define ABS addr = *(LPWORD)(mem+regs.pc); regs.pc += 2; +#define IABSX addr = *(LPWORD)(mem+(*(LPWORD)(mem+regs.pc))+(WORD)regs.x); regs.pc += 2; +#define ABSX base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.x; regs.pc += 2; CHECK_PAGE_CHANGE; +#define ABSY base = *(LPWORD)(mem+regs.pc); addr = base+(WORD)regs.y; regs.pc += 2; CHECK_PAGE_CHANGE; +#define IABSCMOS base = *(LPWORD)(mem+regs.pc); \ + addr = *(LPWORD)(mem+base); \ + if ((base & 0xFF) == 0xFF) uExtraCycles=1; \ + regs.pc += 2; +#define IABSNMOS base = *(LPWORD)(mem+regs.pc); \ + if ((base & 0xFF) == 0xFF) \ + addr = *(mem+base)+((WORD)*(mem+(base&0xFF00))<<8);\ + else \ + addr = *(LPWORD)(mem+base); \ + regs.pc += 2; +#define IMM addr = regs.pc++; +#define INDX base = ((*(mem+regs.pc++))+regs.x) & 0xFF; \ + if (base == 0xFF) \ + addr = *(mem+0xFF)+(((WORD)*mem)<<8); \ + else \ + addr = *(LPWORD)(mem+base); +#define INDY if (*(mem+regs.pc) == 0xFF) \ + base = *(mem+0xFF)+(((WORD)*mem)<<8); \ + else \ + base = *(LPWORD)(mem+*(mem+regs.pc)); \ + regs.pc++; \ + addr = base+(WORD)regs.y; \ + CHECK_PAGE_CHANGE; +#define IZPG base = *(mem+regs.pc++); \ + if (base == 0xFF) \ + addr = *(mem+0xFF)+(((WORD)*mem)<<8); \ + else \ + addr = *(LPWORD)(mem+base); +#define REL addr = (signed char)*(mem+regs.pc++); +#define ZPG addr = *(mem+regs.pc++); +#define ZPGX addr = ((*(mem+regs.pc++))+regs.x) & 0xFF; +#define ZPGY addr = ((*(mem+regs.pc++))+regs.y) & 0xFF; /**************************************************************************** * @@ -217,217 +256,491 @@ static volatile UINT32 g_bmIRQ = 0; * ***/ -#define ADC bWrtMem = 0; \ - temp = READ; \ - if (regs.ps & AF_DECIMAL) { \ - val = TOBIN(regs.a)+TOBIN(temp)+(flagc != 0); \ - flagc = (val > 99); \ - regs.a = TOBCD(val); \ - if (apple2e) \ - SETNZ(regs.a); \ - } \ - else { \ - val = regs.a+temp+(flagc != 0); \ - flagc = (val > 0xFF); \ - flagv = (((regs.a & 0x80) == (temp & 0x80)) && \ - ((regs.a & 0x80) != (val & 0x80))); \ - regs.a = val & 0xFF; \ - SETNZ(regs.a); \ - } -#define AND bWrtMem = 0; \ - regs.a &= READ; \ +#define ADC_NMOS bSlowerOnPagecross = 1; \ + temp = READ; \ + if (regs.ps & AF_DECIMAL) { \ + val = (regs.a & 0x0F) + (temp & 0x0F) + flagc; \ + if (val > 0x09) \ + val += 0x06; \ + if (val <= 0x0F) \ + val = (val & 0x0F) + (regs.a & 0xF0) + (temp & 0xF0); \ + else \ + val = (val & 0x0F) + (regs.a & 0xF0) + (temp & 0xF0) + 0x10;\ + flagz = !((regs.a + temp + flagc) & 0xFF); \ + flagn = (val & 0x80); \ + flagv = ((regs.a ^ val) & 0x80) && !((regs.a ^ temp) & 0x80);\ + if ((val & 0x1F0) > 0x90) \ + val += 0x60; \ + flagc = ((val & 0xFF0) > 0xF0); \ + regs.a = val & 0xFF; \ + } \ + else { \ + val = regs.a + temp + flagc; \ + flagc = (val > 0xFF); \ + flagv = (((regs.a & 0x80) == (temp & 0x80)) && \ + ((regs.a & 0x80) != (val & 0x80))); \ + regs.a = val & 0xFF; \ + SETNZ(regs.a); \ + } +#define ADC_CMOS bSlowerOnPagecross = 1; \ + temp = READ; \ + flagv = !((regs.a ^ temp) & 0x80); \ + if (regs.ps & AF_DECIMAL) { \ + uExtraCycles++; \ + val = (regs.a & 0x0f) + (temp & 0x0f) + flagc; \ + if (val >= 0x0A) \ + val = 0x10 | ((val + 6) & 0x0f); \ + val += (regs.a & 0xf0) + (temp & 0xf0); \ + if (val >= 0xA0) { \ + flagc = 1; \ + if (val >= 0x180) \ + flagv = 0; \ + val += 0x60; \ + } \ + else { \ + flagc = 0; \ + if (val < 0x80) \ + flagv = 0; \ + } \ + } \ + else { \ + val = regs.a + temp + flagc; \ + if (val >= 0x100) { \ + flagc = 1; \ + if (val >= 0x180) flagv = 0; \ + } \ + else { \ + flagc = 0; \ + if (val < 0x80) flagv = 0; \ + } \ + } \ + regs.a = val & 0xFF; \ + SETNZ(regs.a) +#define ALR regs.a &= READ; \ + flagc = (regs.a & 1); \ + flagn = 0; \ + regs.a >>= 1; \ + SETZ(regs.a) +#define AND bSlowerOnPagecross = 1; \ + regs.a &= READ; \ + SETNZ(regs.a) +#define ANC regs.a &= READ; \ + SETNZ(regs.a) \ + flagc = !!flagn; +#define ARR temp = regs.a & READ; /* Yes, this is sick */ \ + if (regs.ps & AF_DECIMAL) { \ + val = temp; \ + val |= (flagc ? 0x100 : 0); \ + val >>= 1; \ + flagn = (flagc ? 0x80 : 0); \ + SETZ(val) \ + flagv = ((val ^ temp) & 0x40); \ + if (((val & 0x0F) + (val & 0x01)) > 0x05) \ + val = (val & 0xF0) | ((val + 0x06) & 0x0F); \ + if (((val & 0xF0) + (val & 0x10)) > 0x50) { \ + val = (val & 0x0F) | ((val + 0x60) & 0xF0); \ + flagc = 1; \ + } \ + else \ + flagc = 0; \ + regs.a = (val & 0xFF); \ + } \ + else { \ + val = temp | (flagc ? 0x100 : 0); \ + val >>= 1; \ + SETNZ(val) \ + flagc = !!(val & 0x40); \ + flagv = ((val & 0x40) ^ ((val & 0x20) << 1)); \ + regs.a = (val & 0xFF); \ + } +#define ASL_NMOS bSlowerOnPagecross = 0; \ + val = READ << 1; \ + flagc = (val > 0xFF); \ + SETNZ(val) \ + WRITE(val) +#define ASL_CMOS bSlowerOnPagecross = 1; \ + val = READ << 1; \ + flagc = (val > 0xFF); \ + SETNZ(val) \ + WRITE(val) +#define ASLA val = regs.a << 1; \ + flagc = (val > 0xFF); \ + SETNZ(val) \ + regs.a = (BYTE)val; +#define ASO bSlowerOnPagecross = 0; \ + val = READ << 1; \ + flagc = (val > 0xFF); \ + WRITE(val) \ + regs.a |= val; \ + SETNZ(regs.a) +#define AXA bSlowerOnPagecross = 0;/*FIXME: $93 case is still unclear*/ \ + val = regs.a & regs.x & (((base >> 8) + 1) & 0xFF); \ + WRITE(val) +#define AXS bSlowerOnPagecross = 0; \ + WRITE(regs.a & regs.x) +#define BCC if (!flagc) BRANCH_TAKEN; +#define BCS if ( flagc) BRANCH_TAKEN; +#define BEQ if ( flagz) BRANCH_TAKEN; +#define BIT bSlowerOnPagecross = 1; \ + val = READ; \ + flagz = !(regs.a & val); \ + flagn = val & 0x80; \ + flagv = val & 0x40; +#define BITI flagz = !(regs.a & READ); +#define BMI if ( flagn) BRANCH_TAKEN; +#define BNE if (!flagz) BRANCH_TAKEN; +#define BPL if (!flagn) BRANCH_TAKEN; +#define BRA BRANCH_TAKEN; +#define BRK regs.pc++; \ + PUSH(regs.pc >> 8) \ + PUSH(regs.pc & 0xFF) \ + EF_TO_AF \ + PUSH(regs.ps); \ + regs.ps |= AF_INTERRUPT; \ + regs.pc = *(LPWORD)(mem+0xFFFE); +#define BVC if (!flagv) BRANCH_TAKEN; +#define BVS if ( flagv) BRANCH_TAKEN; +#define CLC flagc = 0; +#define CLD regs.ps &= ~AF_DECIMAL; +#define CLI regs.ps &= ~AF_INTERRUPT; +#define CLV flagv = 0; +#define CMP bSlowerOnPagecross = 1; \ + val = READ; \ + flagc = (regs.a >= val); \ + val = regs.a-val; \ + SETNZ(val) +#define CPX val = READ; \ + flagc = (regs.x >= val); \ + val = regs.x-val; \ + SETNZ(val) +#define CPY val = READ; \ + flagc = (regs.y >= val); \ + val = regs.y-val; \ + SETNZ(val) +#define DCM bSlowerOnPagecross = 0; \ + val = READ-1; \ + WRITE(val) \ + flagc = (regs.a >= val); \ + val = regs.a-val; \ + SETNZ(val) +#define DEA --regs.a; \ + SETNZ(regs.a) +#define DEC_NMOS bSlowerOnPagecross = 0; \ + val = READ-1; \ + SETNZ(val) \ + WRITE(val) +#define DEC_CMOS bSlowerOnPagecross = 1; \ + val = READ-1; \ + SETNZ(val) \ + WRITE(val) +#define DEX --regs.x; \ + SETNZ(regs.x) +#define DEY --regs.y; \ + SETNZ(regs.y) +#define EOR bSlowerOnPagecross = 1; \ + regs.a ^= READ; \ + SETNZ(regs.a) +#define HLT regs.bJammed = 1; \ + --regs.pc; +#define INA ++regs.a; \ + SETNZ(regs.a) +#define INC_NMOS bSlowerOnPagecross = 0; \ + val = READ+1; \ + SETNZ(val) \ + WRITE(val) +#define INC_CMOS bSlowerOnPagecross = 1; \ + val = READ+1; \ + SETNZ(val) \ + WRITE(val) +#define INS bSlowerOnPagecross = 0; \ + val = READ+1; \ + WRITE(val) \ + temp = val; \ + temp2 = regs.a - temp - !flagc; \ + if (regs.ps & AF_DECIMAL) { \ + val = (regs.a & 0x0F) - (temp & 0x0F) - !flagc; \ + if (val & 0x10) \ + val = ((val - 0x06) & 0x0F) | ((regs.a & 0xF0) - (temp & 0xF0) - 0x10);\ + else \ + val = (val & 0x0F) | ((regs.a & 0xF0) - (temp & 0xF0));\ + if (val & 0x100) \ + val -= 0x60; \ + flagc = (temp2 < 0x100); \ + SETNZ(temp2 & 0xFF); \ + flagv = ((regs.a ^ temp2) & 0x80) && ((regs.a ^ temp) & 0x80);\ + regs.a = val & 0xFF; \ + } \ + else { \ + val = temp2; \ + flagc = (val < 0x100); \ + flagv = (((regs.a & 0x80) != (temp & 0x80)) && \ + ((regs.a & 0x80) != (val & 0x80))); \ + regs.a = val & 0xFF; \ + SETNZ(regs.a); \ + } +#define INX ++regs.x; \ + SETNZ(regs.x) +#define INY ++regs.y; \ + SETNZ(regs.y) +#define JMP regs.pc = addr; +#define JSR --regs.pc; \ + PUSH(regs.pc >> 8) \ + PUSH(regs.pc & 0xFF) \ + regs.pc = addr; +#define LAS bSlowerOnPagecross = 1; \ + val = (BYTE)(READ & regs.sp); \ + regs.a = regs.x = (BYTE) val; \ + regs.sp = val | 0x100; \ + SETNZ(val) +#define LAX bSlowerOnPagecross = 1; \ + regs.a = regs.x = READ; \ + SETNZ(regs.a) +#define LDA bSlowerOnPagecross = 1; \ + regs.a = READ; \ + SETNZ(regs.a) +#define LDX bSlowerOnPagecross = 1; \ + regs.x = READ; \ + SETNZ(regs.x) +#define LDY bSlowerOnPagecross = 1; \ + regs.y = READ; \ + SETNZ(regs.y) +#define LSE bSlowerOnPagecross = 0; \ + val = READ; \ + flagc = (val & 1); \ + val >>= 1; \ + WRITE(val) \ + regs.a ^= val; \ + SETNZ(regs.a) +#define LSR_NMOS bSlowerOnPagecross = 0; \ + val = READ; \ + flagc = (val & 1); \ + flagn = 0; \ + val >>= 1; \ + SETZ(val) \ + WRITE(val) +#define LSR_CMOS bSlowerOnPagecross = 1; \ + val = READ; \ + flagc = (val & 1); \ + flagn = 0; \ + val >>= 1; \ + SETZ(val) \ + WRITE(val) +#define LSRA flagc = (regs.a & 1); \ + flagn = 0; \ + regs.a >>= 1; \ + SETZ(regs.a) +#define NOP bSlowerOnPagecross = 1; +#define OAL regs.a |= 0xEE; \ + regs.a &= READ; \ + regs.x = regs.a; \ + SETNZ(regs.a) +#define ORA bSlowerOnPagecross = 1; \ + regs.a |= READ; \ + SETNZ(regs.a) +#define PHA PUSH(regs.a) +#define PHP EF_TO_AF \ + PUSH(regs.ps) +#define PHX PUSH(regs.x) +#define PHY PUSH(regs.y) +#define PLA regs.a = POP; \ + SETNZ(regs.a) +#define PLP regs.ps = POP | AF_RESERVED | AF_BREAK; \ + AF_TO_EF +#define PLX regs.x = POP; \ + SETNZ(regs.x) +#define PLY regs.y = POP; \ + SETNZ(regs.y) +#define RLA bSlowerOnPagecross = 0; \ + val = (READ << 1) | flagc; \ + flagc = (val > 0xFF); \ + WRITE(val) \ + regs.a &= val; \ + SETNZ(regs.a) +#define ROL_NMOS bSlowerOnPagecross = 0; \ + val = (READ << 1) | flagc; \ + flagc = (val > 0xFF); \ + SETNZ(val) \ + WRITE(val) +#define ROL_CMOS bSlowerOnPagecross = 1; \ + val = (READ << 1) | flagc; \ + flagc = (val > 0xFF); \ + SETNZ(val) \ + WRITE(val) +#define ROLA val = (((WORD)regs.a) << 1) | flagc; \ + flagc = (val > 0xFF); \ + regs.a = val & 0xFF; \ + SETNZ(regs.a); +#define ROR_NMOS bSlowerOnPagecross = 0; \ + temp = READ; \ + val = (temp >> 1) | (flagc ? 0x80 : 0); \ + flagc = (temp & 1); \ + SETNZ(val) \ + WRITE(val) +#define ROR_CMOS bSlowerOnPagecross = 1; \ + temp = READ; \ + val = (temp >> 1) | (flagc ? 0x80 : 0); \ + flagc = (temp & 1); \ + SETNZ(val) \ + WRITE(val) +#define RORA val = (((WORD)regs.a) >> 1) | (flagc ? 0x80 : 0); \ + flagc = (regs.a & 1); \ + regs.a = val & 0xFF; \ + SETNZ(regs.a) +#define RRA bSlowerOnPagecross = 0; \ + temp = READ; \ + val = (temp >> 1) | (flagc ? 0x80 : 0); \ + flagc = (temp & 1); \ + WRITE(val) \ + temp = val; \ + if (regs.ps & AF_DECIMAL) { \ + val = (regs.a & 0x0F) + (temp & 0x0F) + flagc; \ + if (val > 0x09) \ + val += 0x06; \ + if (val <= 0x0F) \ + val = (val & 0x0F) + (regs.a & 0xF0) + (temp & 0xF0); \ + else \ + val = (val & 0x0F) + (regs.a & 0xF0) + (temp & 0xF0) + 0x10;\ + flagz = !((regs.a + temp + flagc) & 0xFF); \ + flagn = (val & 0x80); \ + flagv = ((regs.a ^ val) & 0x80) && !((regs.a ^ temp) & 0x80);\ + if ((val & 0x1F0) > 0x90) \ + val += 0x60; \ + flagc = ((val & 0xFF0) > 0xF0); \ + regs.a = val & 0xFF; \ + } \ + else { \ + val = regs.a + temp + flagc; \ + flagc = (val > 0xFF); \ + flagv = (((regs.a & 0x80) == (temp & 0x80)) && \ + ((regs.a & 0x80) != (val & 0x80))); \ + regs.a = val & 0xFF; \ + SETNZ(regs.a); \ + } +#define RTI regs.ps = POP | AF_RESERVED | AF_BREAK; \ + AF_TO_EF \ + regs.pc = POP; \ + regs.pc |= (((WORD)POP) << 8); +#define RTS regs.pc = POP; \ + regs.pc |= (((WORD)POP) << 8); \ + ++regs.pc; +#define SAX temp = regs.a & regs.x; \ + val = READ; \ + flagc = (temp >= val); \ + regs.x = temp-val; \ + SETNZ(regs.x) +#define SAY bSlowerOnPagecross = 0; \ + val = regs.y & (((base >> 8) + 1) & 0xFF); \ + WRITE(val) +#define SBC_NMOS bSlowerOnPagecross = 1; \ + temp = READ; \ + temp2 = regs.a - temp - !flagc; \ + if (regs.ps & AF_DECIMAL) { \ + val = (regs.a & 0x0F) - (temp & 0x0F) - !flagc; \ + if (val & 0x10) \ + val = ((val - 0x06) & 0x0F) | ((regs.a & 0xF0) - (temp & 0xF0) - 0x10);\ + else \ + val = (val & 0x0F) | ((regs.a & 0xF0) - (temp & 0xF0));\ + if (val & 0x100) \ + val -= 0x60; \ + flagc = (temp2 < 0x100); \ + SETNZ(temp2 & 0xFF); \ + flagv = ((regs.a ^ temp2) & 0x80) && ((regs.a ^ temp) & 0x80);\ + regs.a = val & 0xFF; \ + } \ + else { \ + val = temp2; \ + flagc = (val < 0x100); \ + flagv = (((regs.a & 0x80) != (temp & 0x80)) && \ + ((regs.a & 0x80) != (val & 0x80))); \ + regs.a = val & 0xFF; \ + SETNZ(regs.a); \ + } +#define SBC_CMOS bSlowerOnPagecross = 1; \ + temp = READ; \ + flagv = ((regs.a ^ temp) & 0x80); \ + if (regs.ps & AF_DECIMAL) { \ + uExtraCycles++; \ + temp2 = 0x0F + (regs.a & 0x0F) - (temp & 0x0F) + flagc; \ + if (temp2 < 0x10) { \ + val = 0; \ + temp2 -= 0x06; \ + } \ + else { \ + val = 0x10; \ + temp2 -= 0x10; \ + } \ + val += 0xF0 + (regs.a & 0xF0) - (temp & 0xF0); \ + if (val < 0x100) { \ + flagc = 0; \ + if (val < 0x80) \ + flagv = 0; \ + val -= 0x60; \ + } \ + else { \ + flagc = 1; \ + if (val >= 0x180) \ + flagv = 0; \ + } \ + val += temp2; \ + } \ + else { \ + val = 0xff + regs.a - temp + flagc; \ + if (val < 0x100) { \ + flagc = 0; \ + if (val < 0x80) \ + flagv = 0; \ + } \ + else { \ + flagc = 1; \ + if (val >= 0x180) \ + flagv = 0; \ + } \ + } \ + regs.a = val & 0xFF; \ SETNZ(regs.a) -#define ASL bWrtMem = 1; \ - val = READ << 1; \ - flagc = (val > 0xFF); \ - SETNZ(val) \ - WRITE(val) -#define ASLA val = regs.a << 1; \ - flagc = (val > 0xFF); \ - SETNZ(val) \ - regs.a = (BYTE)val; -#define BCC if (!flagc) BRANCH_TAKEN; -#define BCS if ( flagc) BRANCH_TAKEN; -#define BEQ if ( flagz) BRANCH_TAKEN; -#define BIT val = READ; \ - flagz = !(regs.a & val); \ - flagn = val & 0x80; \ - flagv = val & 0x40; -#define BITI flagz = !(regs.a & READ); -#define BMI if ( flagn) BRANCH_TAKEN; -#define BNE if (!flagz) BRANCH_TAKEN; -#define BPL if (!flagn) BRANCH_TAKEN; -#define BRA BRANCH_TAKEN; -#define BRK regs.pc++; \ - PUSH(regs.pc >> 8) \ - PUSH(regs.pc & 0xFF) \ - EF_TO_AF \ - regs.ps |= AF_BREAK; \ - PUSH(regs.ps) \ - regs.ps |= AF_INTERRUPT; \ - regs.pc = *(LPWORD)(mem+0xFFFE); -#define BVC if (!flagv) BRANCH_TAKEN; -#define BVS if ( flagv) BRANCH_TAKEN; -#define CLC flagc = 0; -#define CLD regs.ps &= ~AF_DECIMAL; -#define CLI regs.ps &= ~AF_INTERRUPT; -#define CLV flagv = 0; -#define CMP bWrtMem = 0; \ - val = READ; \ - flagc = (regs.a >= val); \ - val = regs.a-val; \ - SETNZ(val) -#define CPX val = READ; \ - flagc = (regs.x >= val); \ - val = regs.x-val; \ - SETNZ(val) -#define CPY val = READ; \ - flagc = (regs.y >= val); \ - val = regs.y-val; \ - SETNZ(val) -#define DEA --regs.a; \ - SETNZ(regs.a) -#define DEC bWrtMem = 1; \ - val = READ-1; \ - SETNZ(val) \ - WRITE(val) -#define DEX --regs.x; \ - SETNZ(regs.x) -#define DEY --regs.y; \ - SETNZ(regs.y) -#define EOR bWrtMem = 0; \ - regs.a ^= READ; \ - SETNZ(regs.a) -#define INA ++regs.a; \ - SETNZ(regs.a) -#define INC bWrtMem = 1; \ - val = READ+1; \ - SETNZ(val) \ - WRITE(val) -#define INX ++regs.x; \ - SETNZ(regs.x) -#define INY ++regs.y; \ - SETNZ(regs.y) -#define JMP regs.pc = addr; -#define JSR --regs.pc; \ - PUSH(regs.pc >> 8) \ - PUSH(regs.pc & 0xFF) \ - regs.pc = addr; -#define LDA bWrtMem = 0; \ - regs.a = READ; \ - SETNZ(regs.a) -#define LDX bWrtMem = 0; \ - regs.x = READ; \ - SETNZ(regs.x) -#define LDY bWrtMem = 0; \ - regs.y = READ; \ - SETNZ(regs.y) -#define LSR bWrtMem = 1; \ - val = READ; \ - flagc = (val & 1); \ - flagn = 0; \ - val >>= 1; \ - SETZ(val) \ - WRITE(val) -#define LSRA flagc = (regs.a & 1); \ - flagn = 0; \ - regs.a >>= 1; \ - SETZ(regs.a) -#define NOP -#define ORA bWrtMem = 0; \ - regs.a |= READ; \ - SETNZ(regs.a) -#define PHA PUSH(regs.a) -#define PHP EF_TO_AF \ - regs.ps |= AF_RESERVED; \ - PUSH(regs.ps) -#define PHX PUSH(regs.x) -#define PHY PUSH(regs.y) -#define PLA regs.a = POP; \ - SETNZ(regs.a) -#define PLP regs.ps = POP; \ - AF_TO_EF -#define PLX regs.x = POP; \ - SETNZ(regs.x) -#define PLY regs.y = POP; \ - SETNZ(regs.y) -#define ROL bWrtMem = 1; \ - val = (READ << 1) | (flagc != 0); \ - flagc = (val > 0xFF); \ - SETNZ(val) \ - WRITE(val) -#define ROLA val = (((WORD)regs.a) << 1) | (flagc != 0); \ - flagc = (val > 0xFF); \ - regs.a = val & 0xFF; \ - SETNZ(regs.a); -#define ROR bWrtMem = 1; \ - temp = READ; \ - val = (temp >> 1) | (flagc ? 0x80 : 0); \ - flagc = temp & 1; \ - SETNZ(val) \ - WRITE(val) -#define RORA val = (((WORD)regs.a) >> 1) | (flagc ? 0x80 : 0); \ - flagc = regs.a & 1; \ - regs.a = val & 0xFF; \ - SETNZ(regs.a) -#define RTI regs.ps = POP; \ - AF_TO_EF \ - regs.pc = POP; \ - regs.pc |= (((WORD)POP) << 8); -#define RTS regs.pc = POP; \ - regs.pc |= (((WORD)POP) << 8); \ - ++regs.pc; -#define SBC bWrtMem = 0; \ - temp = READ; \ - if (regs.ps & AF_DECIMAL) { \ - val = TOBIN(regs.a)-TOBIN(temp)-!flagc; \ - flagc = (val < 0x8000); \ - if (!flagc) val += 100; /* adjust val if carry so TOBCD macro works as intended */ \ - regs.a = TOBCD(val); \ - if (apple2e) \ - SETNZ(regs.a); \ - } \ - else { \ - val = regs.a-temp-!flagc; \ - flagc = (val < 0x8000); \ - flagv = (((regs.a & 0x80) != (temp & 0x80)) && \ - ((regs.a & 0x80) != (val & 0x80))); \ - regs.a = val & 0xFF; \ - SETNZ(regs.a); \ - } -#define SEC flagc = 1; -#define SED regs.ps |= AF_DECIMAL; -#define SEI regs.ps |= AF_INTERRUPT; -#define STA bWrtMem = 1; \ - WRITE(regs.a) -#define STX bWrtMem = 1; \ - WRITE(regs.x) -#define STY bWrtMem = 1; \ - WRITE(regs.y) -#define STZ bWrtMem = 1; \ - WRITE(0) -#define TAX regs.x = regs.a; \ - SETNZ(regs.x) -#define TAY regs.y = regs.a; \ - SETNZ(regs.y) -#define TRB bWrtMem = 1; \ - val = READ; \ - flagz = !(regs.a & val); \ - val &= ~regs.a; \ - WRITE(val) -#define TSB bWrtMem = 1; \ - val = READ; \ - flagz = !(regs.a & val); \ - val |= regs.a; \ - WRITE(val) -#define TSX regs.x = regs.sp & 0xFF; \ - SETNZ(regs.x) -#define TXA regs.a = regs.x; \ - SETNZ(regs.a) -#define TXS regs.sp = 0x100 | regs.x; -#define TYA regs.a = regs.y; \ - SETNZ(regs.a) - +#define SEC flagc = 1; +#define SED regs.ps |= AF_DECIMAL; +#define SEI regs.ps |= AF_INTERRUPT; +#define STA bSlowerOnPagecross = 0; \ + WRITE(regs.a) +#define STX bSlowerOnPagecross = 0; \ + WRITE(regs.x) +#define STY bSlowerOnPagecross = 0; \ + WRITE(regs.y) +#define STZ bSlowerOnPagecross = 0; \ + WRITE(0) +#define TAS bSlowerOnPagecross = 0; \ + val = regs.a & regs.x; \ + regs.sp = 0x100 | val; \ + val &= (((base >> 8) + 1) & 0xFF); \ + WRITE(val) +#define TAX regs.x = regs.a; \ + SETNZ(regs.x) +#define TAY regs.y = regs.a; \ + SETNZ(regs.y) +#define TRB bSlowerOnPagecross = 0; \ + val = READ; \ + flagz = !(regs.a & val); \ + val &= ~regs.a; \ + WRITE(val) +#define TSB bSlowerOnPagecross = 0; \ + val = READ; \ + flagz = !(regs.a & val); \ + val |= regs.a; \ + WRITE(val) +#define TSX regs.x = regs.sp & 0xFF; \ + SETNZ(regs.x) +#define TXA regs.a = regs.x; \ + SETNZ(regs.a) +#define TXS regs.sp = 0x100 | regs.x; +#define TYA regs.a = regs.y; \ + SETNZ(regs.a) +#define XAA regs.a = regs.x; \ + regs.a &= READ; \ + SETNZ(regs.a) +#define XAS bSlowerOnPagecross = 0; \ + val = regs.x & (((base >> 8) + 1) & 0xFF); \ + WRITE(val) void RequestDebugger() { @@ -452,9 +765,7 @@ bool CheckDebugBreak( int iOpcode ) } // Break into debugger on invalid opcodes -#define INVALID1 ; if (IsDebugBreakOnInvalid(1)) { RequestDebugger(); bBreakOnInvalid = true; } -#define INVALID2 if (apple2e) ++regs.pc ; if (IsDebugBreakOnInvalid(2)) { RequestDebugger(); bBreakOnInvalid = true; } -#define INVALID3 if (apple2e) regs.pc += 2; if (IsDebugBreakOnInvalid(3)) { RequestDebugger(); bBreakOnInvalid = true; } +#define INV if (IsDebugBreakOnInvalid(1)) { RequestDebugger(); bBreakOnInvalid = true; } /**************************************************************************** * @@ -505,317 +816,644 @@ static inline void DoIrqProfiling(DWORD cycles) //=========================================================================== static DWORD InternalCpuExecute (DWORD totalcycles) { - WORD addr; - BOOL flagc; - BOOL flagn; - BOOL flagv; - BOOL flagz; - WORD temp; - WORD val; - AF_TO_EF - DWORD cycles = 0; - BOOL bWrtMem; // Set if opcode writes to memory (eg. ASL, STA) - WORD base; + WORD addr; + BOOL flagc; // must always be 0 or 1, no other values allowed + BOOL flagn; // must always be 0 or 0x80. + BOOL flagv; // any value allowed + BOOL flagz; // any value allowed + WORD temp; + WORD temp2; + WORD val; + AF_TO_EF + DWORD cycles = 0; + BOOL bSlowerOnPagecross; // Set if opcode writes to memory (eg. ASL, STA) + WORD base; + bool bBreakOnInvalid = false; - bool bBreakOnInvalid = false; + if (apple2e) + { + do + { - do - { - nInternalCyclesLeft = (totalcycles<<8) - (cycles<<8); - USHORT uExtraCycles = 0; + nInternalCyclesLeft = (totalcycles<<8) - (cycles<<8); + USHORT uExtraCycles = 0; - BYTE iOpcode = *(mem+regs.pc); - if (CheckDebugBreak( iOpcode )) - break; + if (regs.bRESET) + { + regs.bRESET = 0; + EF_TO_AF + regs.ps = (regs.ps | AF_INTERRUPT) & ~AF_DECIMAL; + regs.pc = * (WORD*) (mem+0xFFFC); + regs.sp = 0x0100 | ((regs.sp - 3) & 0xFF); + CYC(7); + continue; + } + + BYTE iOpcode = *(mem+regs.pc); + if (CheckDebugBreak( iOpcode )) + break; + regs.pc++; + switch (iOpcode) { + case 0x00: BRK CYC(7) break; + case 0x01: INDX ORA CYC(6) break; + case 0x02: INV IMM NOP CYC(2) break; + case 0x03: INV NOP CYC(2) break; + case 0x04: ZPG TSB CYC(5) break; + case 0x05: ZPG ORA CYC(3) break; + case 0x06: ZPG ASL_CMOS CYC(5) break; + case 0x07: INV NOP CYC(2) break; + case 0x08: PHP CYC(3) break; + case 0x09: IMM ORA CYC(2) break; + case 0x0A: ASLA CYC(2) break; + case 0x0B: INV NOP CYC(2) break; + case 0x0C: ABS TSB CYC(6) break; + case 0x0D: ABS ORA CYC(4) break; + case 0x0E: ABS ASL_CMOS CYC(6) break; + case 0x0F: INV NOP CYC(2) break; + case 0x10: REL BPL CYC(2) break; + case 0x11: INDY ORA CYC(5) break; + case 0x12: IZPG ORA CYC(5) break; + case 0x13: INV NOP CYC(2) break; + case 0x14: ZPG TRB CYC(5) break; + case 0x15: ZPGX ORA CYC(4) break; + case 0x16: ZPGX ASL_CMOS CYC(6) break; + case 0x17: INV NOP CYC(2) break; + case 0x18: CLC CYC(2) break; + case 0x19: ABSY ORA CYC(4) break; + case 0x1A: INA CYC(2) break; + case 0x1B: INV NOP CYC(2) break; + case 0x1C: ABS TRB CYC(6) break; + case 0x1D: ABSX ORA CYC(4) break; + case 0x1E: ABSX ASL_CMOS CYC(6) break; + case 0x1F: INV NOP CYC(2) break; + case 0x20: ABS JSR CYC(6) break; + case 0x21: INDX AND CYC(6) break; + case 0x22: INV IMM NOP CYC(2) break; + case 0x23: INV NOP CYC(2) break; + case 0x24: ZPG BIT CYC(3) break; + case 0x25: ZPG AND CYC(3) break; + case 0x26: ZPG ROL_CMOS CYC(5) break; + case 0x27: INV NOP CYC(2) break; + case 0x28: PLP CYC(4) break; + case 0x29: IMM AND CYC(2) break; + case 0x2A: ROLA CYC(2) break; + case 0x2B: INV NOP CYC(2) break; + case 0x2C: ABS BIT CYC(4) break; + case 0x2D: ABS AND CYC(2) break; + case 0x2E: ABS ROL_CMOS CYC(6) break; + case 0x2F: INV NOP CYC(2) break; + case 0x30: REL BMI CYC(2) break; + case 0x31: INDY AND CYC(5) break; + case 0x32: IZPG AND CYC(5) break; + case 0x33: INV NOP CYC(2) break; + case 0x34: ZPGX BIT CYC(4) break; + case 0x35: ZPGX AND CYC(4) break; + case 0x36: ZPGX ROL_CMOS CYC(6) break; + case 0x37: INV NOP CYC(2) break; + case 0x38: SEC CYC(2) break; + case 0x39: ABSY AND CYC(4) break; + case 0x3A: DEA CYC(2) break; + case 0x3B: INV NOP CYC(2) break; + case 0x3C: ABSX BIT CYC(4) break; + case 0x3D: ABSX AND CYC(4) break; + case 0x3E: ABSX ROL_CMOS CYC(6) break; + case 0x3F: INV NOP CYC(2) break; + case 0x40: RTI CYC(6) DoIrqProfiling(cycles); break; + case 0x41: INDX EOR CYC(6) break; + case 0x42: INV IMM NOP CYC(2) break; + case 0x43: INV NOP CYC(2) break; + case 0x44: INV ZPG NOP CYC(3) break; + case 0x45: ZPG EOR CYC(3) break; + case 0x46: ZPG LSR_CMOS CYC(5) break; + case 0x47: INV NOP CYC(2) break; + case 0x48: PHA CYC(3) break; + case 0x49: IMM EOR CYC(2) break; + case 0x4A: LSRA CYC(2) break; + case 0x4B: INV NOP CYC(2) break; + case 0x4C: ABS JMP CYC(3) break; + case 0x4D: ABS EOR CYC(4) break; + case 0x4E: ABS LSR_CMOS CYC(6) break; + case 0x4F: INV NOP CYC(2) break; + case 0x50: REL BVC CYC(2) break; + case 0x51: INDY EOR CYC(5) break; + case 0x52: IZPG EOR CYC(5) break; + case 0x53: INV NOP CYC(2) break; + case 0x54: INV ZPGX NOP CYC(4) break; + case 0x55: ZPGX EOR CYC(4) break; + case 0x56: ZPGX LSR_CMOS CYC(6) break; + case 0x57: INV NOP CYC(2) break; + case 0x58: CLI CYC(2) break; + case 0x59: ABSY EOR CYC(4) break; + case 0x5A: PHY CYC(3) break; + case 0x5B: INV NOP CYC(2) break; + case 0x5C: INV ABSX NOP CYC(8) break; + case 0x5D: ABSX EOR CYC(4) break; + case 0x5E: ABSX LSR_CMOS CYC(6) break; + case 0x5F: INV NOP CYC(2) break; + case 0x60: RTS CYC(6) break; + case 0x61: INDX ADC_CMOS CYC(6) break; + case 0x62: INV IMM NOP CYC(2) break; + case 0x63: INV NOP CYC(2) break; + case 0x64: ZPG STZ CYC(3) break; + case 0x65: ZPG ADC_CMOS CYC(3) break; + case 0x66: ZPG ROR_CMOS CYC(5) break; + case 0x67: INV NOP CYC(2) break; + case 0x68: PLA CYC(4) break; + case 0x69: IMM ADC_CMOS CYC(2) break; + case 0x6A: RORA CYC(2) break; + case 0x6B: INV NOP CYC(2) break; + case 0x6C: IABSCMOS JMP CYC(6) break; + case 0x6D: ABS ADC_CMOS CYC(4) break; + case 0x6E: ABS ROR_CMOS CYC(6) break; + case 0x6F: INV NOP CYC(2) break; + case 0x70: REL BVS CYC(2) break; + case 0x71: INDY ADC_CMOS CYC(5) break; + case 0x72: IZPG ADC_CMOS CYC(5) break; + case 0x73: INV NOP CYC(2) break; + case 0x74: ZPGX STZ CYC(4) break; + case 0x75: ZPGX ADC_CMOS CYC(4) break; + case 0x76: ZPGX ROR_CMOS CYC(6) break; + case 0x77: INV NOP CYC(2) break; + case 0x78: SEI CYC(2) break; + case 0x79: ABSY ADC_CMOS CYC(4) break; + case 0x7A: PLY CYC(4) break; + case 0x7B: INV NOP CYC(2) break; + case 0x7C: IABSX JMP CYC(6) break; + case 0x7D: ABSX ADC_CMOS CYC(4) break; + case 0x7E: ABSX ROR_CMOS CYC(6) break; + case 0x7F: INV NOP CYC(2) break; + case 0x80: REL BRA CYC(2) break; + case 0x81: INDX STA CYC(6) break; + case 0x82: INV IMM NOP CYC(2) break; + case 0x83: INV NOP CYC(2) break; + case 0x84: ZPG STY CYC(3) break; + case 0x85: ZPG STA CYC(3) break; + case 0x86: ZPG STX CYC(3) break; + case 0x87: INV NOP CYC(2) break; + case 0x88: DEY CYC(2) break; + case 0x89: IMM BITI CYC(2) break; + case 0x8A: TXA CYC(2) break; + case 0x8B: INV NOP CYC(2) break; + case 0x8C: ABS STY CYC(4) break; + case 0x8D: ABS STA CYC(4) break; + case 0x8E: ABS STX CYC(4) break; + case 0x8F: INV NOP CYC(2) break; + case 0x90: REL BCC CYC(2) break; + case 0x91: INDY STA CYC(6) break; + case 0x92: IZPG STA CYC(5) break; + case 0x93: INV NOP CYC(2) break; + case 0x94: ZPGX STY CYC(4) break; + case 0x95: ZPGX STA CYC(4) break; + case 0x96: ZPGY STX CYC(4) break; + case 0x97: INV NOP CYC(2) break; + case 0x98: TYA CYC(2) break; + case 0x99: ABSY STA CYC(5) break; + case 0x9A: TXS CYC(2) break; + case 0x9B: INV NOP CYC(2) break; + case 0x9C: ABS STZ CYC(4) break; + case 0x9D: ABSX STA CYC(5) break; + case 0x9E: ABSX STZ CYC(5) break; + case 0x9F: INV NOP CYC(2) break; + case 0xA0: IMM LDY CYC(2) break; + case 0xA1: INDX LDA CYC(6) break; + case 0xA2: IMM LDX CYC(2) break; + case 0xA3: INV NOP CYC(2) break; + case 0xA4: ZPG LDY CYC(3) break; + case 0xA5: ZPG LDA CYC(3) break; + case 0xA6: ZPG LDX CYC(3) break; + case 0xA7: INV NOP CYC(2) break; + case 0xA8: TAY CYC(2) break; + case 0xA9: IMM LDA CYC(2) break; + case 0xAA: TAX CYC(2) break; + case 0xAB: INV NOP CYC(2) break; + case 0xAC: ABS LDY CYC(4) break; + case 0xAD: ABS LDA CYC(4) break; + case 0xAE: ABS LDX CYC(4) break; + case 0xAF: INV NOP CYC(2) break; + case 0xB0: REL BCS CYC(2) break; + case 0xB1: INDY LDA CYC(5) break; + case 0xB2: IZPG LDA CYC(5) break; + case 0xB3: INV NOP CYC(2) break; + case 0xB4: ZPGX LDY CYC(4) break; + case 0xB5: ZPGX LDA CYC(4) break; + case 0xB6: ZPGY LDX CYC(4) break; + case 0xB7: INV NOP CYC(2) break; + case 0xB8: CLV CYC(2) break; + case 0xB9: ABSY LDA CYC(4) break; + case 0xBA: TSX CYC(2) break; + case 0xBB: INV NOP CYC(2) break; + case 0xBC: ABSX LDY CYC(4) break; + case 0xBD: ABSX LDA CYC(4) break; + case 0xBE: ABSY LDX CYC(4) break; + case 0xBF: INV NOP CYC(2) break; + case 0xC0: IMM CPY CYC(2) break; + case 0xC1: INDX CMP CYC(6) break; + case 0xC2: INV IMM NOP CYC(2) break; + case 0xC3: INV NOP CYC(2) break; + case 0xC4: ZPG CPY CYC(3) break; + case 0xC5: ZPG CMP CYC(3) break; + case 0xC6: ZPG DEC_CMOS CYC(5) break; + case 0xC7: INV NOP CYC(2) break; + case 0xC8: INY CYC(2) break; + case 0xC9: IMM CMP CYC(2) break; + case 0xCA: DEX CYC(2) break; + case 0xCB: INV NOP CYC(2) break; + case 0xCC: ABS CPY CYC(4) break; + case 0xCD: ABS CMP CYC(4) break; + case 0xCE: ABS DEC_CMOS CYC(5) break; + case 0xCF: INV NOP CYC(2) break; + case 0xD0: REL BNE CYC(2) break; + case 0xD1: INDY CMP CYC(5) break; + case 0xD2: IZPG CMP CYC(5) break; + case 0xD3: INV NOP CYC(2) break; + case 0xD4: INV ZPGX NOP CYC(4) break; + case 0xD5: ZPGX CMP CYC(4) break; + case 0xD6: ZPGX DEC_CMOS CYC(6) break; + case 0xD7: INV NOP CYC(2) break; + case 0xD8: CLD CYC(2) break; + case 0xD9: ABSY CMP CYC(4) break; + case 0xDA: PHX CYC(3) break; + case 0xDB: INV NOP CYC(2) break; + case 0xDC: INV ABSX NOP CYC(4) break; + case 0xDD: ABSX CMP CYC(4) break; + case 0xDE: ABSX DEC_CMOS CYC(6) break; + case 0xDF: INV NOP CYC(2) break; + case 0xE0: IMM CPX CYC(2) break; + case 0xE1: INDX SBC_CMOS CYC(6) break; + case 0xE2: INV IMM NOP CYC(2) break; + case 0xE3: INV NOP CYC(2) break; + case 0xE4: ZPG CPX CYC(3) break; + case 0xE5: ZPG SBC_CMOS CYC(3) break; + case 0xE6: ZPG INC_CMOS CYC(5) break; + case 0xE7: INV NOP CYC(2) break; + case 0xE8: INX CYC(2) break; + case 0xE9: IMM SBC_CMOS CYC(2) break; + case 0xEA: NOP CYC(2) break; + case 0xEB: INV NOP CYC(2) break; + case 0xEC: ABS CPX CYC(4) break; + case 0xED: ABS SBC_CMOS CYC(4) break; + case 0xEE: ABS INC_CMOS CYC(6) break; + case 0xEF: INV NOP CYC(2) break; + case 0xF0: REL BEQ CYC(2) break; + case 0xF1: INDY SBC_CMOS CYC(5) break; + case 0xF2: IZPG SBC_CMOS CYC(5) break; + case 0xF3: INV NOP CYC(2) break; + case 0xF4: INV ZPGX NOP CYC(4) break; + case 0xF5: ZPGX SBC_CMOS CYC(4) break; + case 0xF6: ZPGX INC_CMOS CYC(6) break; + case 0xF7: INV NOP CYC(2) break; + case 0xF8: SED CYC(2) break; + case 0xF9: ABSY SBC_CMOS CYC(4) break; + case 0xFA: PLX CYC(4) break; + case 0xFB: INV NOP CYC(2) break; + case 0xFC: INV ABSX NOP CYC(4) break; + case 0xFD: ABSX SBC_CMOS CYC(4) break; + case 0xFE: ABSX INC_CMOS CYC(6) break; + case 0xFF: INV NOP CYC(2) break; + } + if(g_bNmiFlank) + { + // NMI signals are only serviced once + g_bNmiFlank = FALSE; + g_nCycleIrqStart = g_nCumulativeCycles + cycles; + PUSH(regs.pc >> 8) + PUSH(regs.pc & 0xFF) + EF_TO_AF + PUSH(regs.ps & ~AF_BREAK) + regs.ps = regs.ps | AF_INTERRUPT & ~AF_DECIMAL; + regs.pc = * (WORD*) (mem+0xFFFA); + CYC(7) + } + if(g_bmIRQ && !(regs.ps & AF_INTERRUPT)) + { + // IRQ signals are deasserted when a specific r/w operation is done on device + g_nCycleIrqStart = g_nCumulativeCycles + cycles; + PUSH(regs.pc >> 8) + PUSH(regs.pc & 0xFF) + EF_TO_AF + PUSH(regs.ps & ~AF_BREAK) + regs.ps = regs.ps | AF_INTERRUPT & ~AF_DECIMAL; + regs.pc = * (WORD*) (mem+0xFFFE); + CYC(7) + } + if (bBreakOnInvalid) + break; + } while (cycles < totalcycles); + EF_TO_AF + return cycles; + } + else + { + do + { + nInternalCyclesLeft = (totalcycles<<8) - (cycles<<8); + USHORT uExtraCycles = 0; - regs.pc++; - - - switch (iOpcode) - { - case 0x00: BRK CYC(7) break; - case 0x01: INDX ORA CYC(6) break; - case 0x02: INVALID2 CYC(2) break; - case 0x03: INVALID1 CYC(1) break; - case 0x04: CMOS ZPG TSB CYC(5) break; - case 0x05: ZPG ORA CYC(3) break; - case 0x06: ZPG ASL CYC(5) break; - case 0x07: INVALID1 CYC(1) break; - case 0x08: PHP CYC(3) break; - case 0x09: IMM ORA CYC(2) break; - case 0x0A: ASLA CYC(2) break; - case 0x0B: INVALID1 CYC(1) break; - case 0x0C: CMOS ABS TSB CYC(6) break; - case 0x0D: ABS ORA CYC(4) break; - case 0x0E: ABS ASL CYC(6) break; -// case 0x0F: INVALID1 CYC(1) break; - case 0x0F: INVALID3 CYC(4) break; // Fix: GI-Joe - case 0x10: REL BPL CYC(CLKS_BRANCH) break; - case 0x11: INDY ORA CYC(5) break; - case 0x12: CMOS IZPG ORA CYC(5) break; - case 0x13: INVALID1 CYC(1) break; - case 0x14: CMOS ZPG TRB CYC(5) break; - case 0x15: ZPGX ORA CYC(4) break; - case 0x16: ZPGX ASL CYC(6) break; - case 0x17: INVALID1 CYC(1) break; - case 0x18: CLC CYC(2) break; - case 0x19: ABSY ORA CYC(4) break; - case 0x1A: CMOS INA CYC(2) break; - case 0x1B: INVALID1 CYC(1) break; - case 0x1C: CMOS ABS TRB CYC(6) break; - case 0x1D: ABSX ORA CYC(4) break; - case 0x1E: ABSX ASL CYC(6) break; - case 0x1F: INVALID1 CYC(1) break; - case 0x20: ABS JSR CYC(6) break; - case 0x21: INDX AND CYC(6) break; - case 0x22: INVALID2 CYC(2) break; - case 0x23: INVALID1 CYC(1) break; - case 0x24: ZPG BIT CYC(3) break; - case 0x25: ZPG AND CYC(3) break; - case 0x26: ZPG ROL CYC(5) break; - case 0x27: INVALID1 CYC(1) break; - case 0x28: PLP CYC(4) break; - case 0x29: IMM AND CYC(2) break; - case 0x2A: ROLA CYC(2) break; - case 0x2B: INVALID1 CYC(1) break; - case 0x2C: ABS BIT CYC(4) break; - case 0x2D: ABS AND CYC(2) break; - case 0x2E: ABS ROL CYC(6) break; -// case 0x2F: INVALID1 CYC(1) break; - case 0x2F: INVALID3 CYC(4) break; // Fix: GI-Joe - case 0x30: REL BMI CYC(CLKS_BRANCH) break; - case 0x31: INDY AND CYC(5) break; - case 0x32: CMOS IZPG AND CYC(5) break; - case 0x33: INVALID1 CYC(1) break; - case 0x34: CMOS ZPGX BIT CYC(4) break; - case 0x35: ZPGX AND CYC(4) break; - case 0x36: ZPGX ROL CYC(6) break; - case 0x37: INVALID1 CYC(1) break; - case 0x38: SEC CYC(2) break; - case 0x39: ABSY AND CYC(4) break; - case 0x3A: CMOS DEA CYC(2) break; - case 0x3B: INVALID1 CYC(1) break; - case 0x3C: CMOS ABSX BIT CYC(4) break; - case 0x3D: ABSX AND CYC(4) break; - case 0x3E: ABSX ROL CYC(6) break; - case 0x3F: INVALID1 CYC(1) break; - case 0x40: RTI CYC(6) DoIrqProfiling(cycles); break; - case 0x41: INDX EOR CYC(6) break; - case 0x42: INVALID2 CYC(2) break; - case 0x43: INVALID1 CYC(1) break; - case 0x44: INVALID2 CYC(3) break; - case 0x45: ZPG EOR CYC(3) break; - case 0x46: ZPG LSR CYC(5) break; - case 0x47: INVALID1 CYC(1) break; - case 0x48: PHA CYC(3) break; - case 0x49: IMM EOR CYC(2) break; - case 0x4A: LSRA CYC(2) break; - case 0x4B: INVALID1 CYC(1) break; - case 0x4C: ABS JMP CYC(3) break; - case 0x4D: ABS EOR CYC(4) break; - case 0x4E: ABS LSR CYC(6) break; - case 0x4F: INVALID1 CYC(1) break; - case 0x50: REL BVC CYC(CLKS_BRANCH) break; - case 0x51: INDY EOR CYC(5) break; - case 0x52: CMOS IZPG EOR CYC(5) break; - case 0x53: INVALID1 CYC(1) break; - case 0x54: INVALID2 CYC(4) break; - case 0x55: ZPGX EOR CYC(4) break; - case 0x56: ZPGX LSR CYC(6) break; - case 0x57: INVALID1 CYC(1) break; - case 0x58: CLI CYC(2) break; - case 0x59: ABSY EOR CYC(4) break; - case 0x5A: CMOS PHY CYC(3) break; - case 0x5B: INVALID1 CYC(1) break; - case 0x5C: INVALID3 CYC(8) break; - case 0x5D: ABSX EOR CYC(4) break; - case 0x5E: ABSX LSR CYC(6) break; - case 0x5F: INVALID1 CYC(1) break; - case 0x60: RTS CYC(6) break; - case 0x61: INDX ADC CYC(6) break; - case 0x62: INVALID2 CYC(2) break; - case 0x63: INVALID1 CYC(1) break; - case 0x64: CMOS ZPG STZ CYC(3) break; - case 0x65: ZPG ADC CYC(3) break; - case 0x66: ZPG ROR CYC(5) break; - case 0x67: INVALID1 CYC(1) break; - case 0x68: PLA CYC(4) break; - case 0x69: IMM ADC CYC(2) break; - case 0x6A: RORA CYC(2) break; - case 0x6B: INVALID1 CYC(1) break; - case 0x6C: IABS JMP CYC(6) break; - case 0x6D: ABS ADC CYC(4) break; - case 0x6E: ABS ROR CYC(6) break; - case 0x6F: INVALID1 CYC(1) break; - case 0x70: REL BVS CYC(CLKS_BRANCH) break; - case 0x71: INDY ADC CYC(5) break; - case 0x72: CMOS IZPG ADC CYC(5) break; - case 0x73: INVALID1 CYC(1) break; - case 0x74: CMOS ZPGX STZ CYC(4) break; - case 0x75: ZPGX ADC CYC(4) break; - case 0x76: ZPGX ROR CYC(6) break; - case 0x77: INVALID1 CYC(1) break; - case 0x78: SEI CYC(2) break; - case 0x79: ABSY ADC CYC(4) break; - case 0x7A: CMOS PLY CYC(4) break; - case 0x7B: INVALID1 CYC(1) break; - case 0x7C: CMOS ABSIINDX JMP CYC(6) break; - case 0x7D: ABSX ADC CYC(4) break; - case 0x7E: ABSX ROR CYC(6) break; - case 0x7F: INVALID1 CYC(1) break; - case 0x80: CMOS REL BRA CYC(CLKS_BRANCH) break; - case 0x81: INDX STA CYC(6) break; - case 0x82: INVALID2 CYC(2) break; - case 0x83: INVALID1 CYC(1) break; - case 0x84: ZPG STY CYC(3) break; - case 0x85: ZPG STA CYC(3) break; - case 0x86: ZPG STX CYC(3) break; - case 0x87: INVALID1 CYC(1) break; - case 0x88: DEY CYC(2) break; - case 0x89: CMOS IMM BITI CYC(2) break; - case 0x8A: TXA CYC(2) break; - case 0x8B: INVALID1 CYC(1) break; - case 0x8C: ABS STY CYC(4) break; - case 0x8D: ABS STA CYC(4) break; - case 0x8E: ABS STX CYC(4) break; - case 0x8F: INVALID1 CYC(1) break; - case 0x90: REL BCC CYC(CLKS_BRANCH) break; - case 0x91: INDY STA CYC(6) break; - case 0x92: CMOS IZPG STA CYC(5) break; - case 0x93: INVALID1 CYC(1) break; - case 0x94: ZPGX STY CYC(4) break; - case 0x95: ZPGX STA CYC(4) break; - case 0x96: ZPGY STX CYC(4) break; - case 0x97: INVALID1 CYC(1) break; - case 0x98: TYA CYC(2) break; - case 0x99: ABSY STA CYC(5) break; - case 0x9A: TXS CYC(2) break; - case 0x9B: INVALID1 CYC(1) break; - case 0x9C: CMOS ABS STZ CYC(4) break; - case 0x9D: ABSX STA CYC(5) break; - case 0x9E: CMOS ABSX STZ CYC(5) break; - case 0x9F: INVALID1 CYC(1) break; - case 0xA0: IMM LDY CYC(2) break; - case 0xA1: INDX LDA CYC(6) break; - case 0xA2: IMM LDX CYC(2) break; - case 0xA3: INVALID1 CYC(1) break; - case 0xA4: ZPG LDY CYC(3) break; - case 0xA5: ZPG LDA CYC(3) break; - case 0xA6: ZPG LDX CYC(3) break; - case 0xA7: INVALID1 CYC(1) break; - case 0xA8: TAY CYC(2) break; - case 0xA9: IMM LDA CYC(2) break; - case 0xAA: TAX CYC(2) break; - case 0xAB: INVALID1 CYC(1) break; - case 0xAC: ABS LDY CYC(4) break; - case 0xAD: ABS LDA CYC(4) break; - case 0xAE: ABS LDX CYC(4) break; - case 0xAF: INVALID1 CYC(1) break; - case 0xB0: REL BCS CYC(CLKS_BRANCH) break; - case 0xB1: INDY LDA CYC(5) break; - case 0xB2: CMOS IZPG LDA CYC(5) break; - case 0xB3: INVALID1 CYC(1) break; - case 0xB4: ZPGX LDY CYC(4) break; - case 0xB5: ZPGX LDA CYC(4) break; - case 0xB6: ZPGY LDX CYC(4) break; - case 0xB7: INVALID1 CYC(1) break; - case 0xB8: CLV CYC(2) break; - case 0xB9: ABSY LDA CYC(4) break; - case 0xBA: TSX CYC(2) break; - case 0xBB: INVALID1 CYC(1) break; - case 0xBC: ABSX LDY CYC(4) break; - case 0xBD: ABSX LDA CYC(4) break; - case 0xBE: ABSY LDX CYC(4) break; - case 0xBF: INVALID1 CYC(1) break; - case 0xC0: IMM CPY CYC(2) break; - case 0xC1: INDX CMP CYC(6) break; - case 0xC2: INVALID2 CYC(2) break; - case 0xC3: INVALID1 CYC(1) break; - case 0xC4: ZPG CPY CYC(3) break; - case 0xC5: ZPG CMP CYC(3) break; - case 0xC6: ZPG DEC CYC(5) break; - case 0xC7: INVALID1 CYC(1) break; - case 0xC8: INY CYC(2) break; - case 0xC9: IMM CMP CYC(2) break; - case 0xCA: DEX CYC(2) break; - case 0xCB: INVALID1 CYC(1) break; - case 0xCC: ABS CPY CYC(4) break; - case 0xCD: ABS CMP CYC(4) break; - case 0xCE: ABS DEC CYC(5) break; - case 0xCF: INVALID1 CYC(1) break; - case 0xD0: REL BNE CYC(CLKS_BRANCH) break; - case 0xD1: INDY CMP CYC(5) break; - case 0xD2: CMOS IZPG CMP CYC(5) break; - case 0xD3: INVALID1 CYC(1) break; - case 0xD4: INVALID2 CYC(4) break; - case 0xD5: ZPGX CMP CYC(4) break; - case 0xD6: ZPGX DEC CYC(6) break; - case 0xD7: INVALID1 CYC(1) break; - case 0xD8: CLD CYC(2) break; - case 0xD9: ABSY CMP CYC(4) break; - case 0xDA: CMOS PHX CYC(3) break; - case 0xDB: INVALID1 CYC(1) break; - case 0xDC: INVALID3 CYC(4) break; - case 0xDD: ABSX CMP CYC(4) break; - case 0xDE: ABSX DEC CYC(6) break; - case 0xDF: INVALID1 CYC(1) break; - case 0xE0: IMM CPX CYC(2) break; - case 0xE1: INDX SBC CYC(6) break; - case 0xE2: INVALID2 CYC(2) break; - case 0xE3: INVALID1 CYC(1) break; - case 0xE4: ZPG CPX CYC(3) break; - case 0xE5: ZPG SBC CYC(3) break; - case 0xE6: ZPG INC CYC(5) break; - case 0xE7: INVALID1 CYC(1) break; - case 0xE8: INX CYC(2) break; - case 0xE9: IMM SBC CYC(2) break; - case 0xEA: NOP CYC(2) break; - case 0xEB: INVALID1 CYC(1) break; - case 0xEC: ABS CPX CYC(4) break; - case 0xED: ABS SBC CYC(4) break; - case 0xEE: ABS INC CYC(6) break; - case 0xEF: INVALID1 CYC(1) break; - case 0xF0: REL BEQ CYC(CLKS_BRANCH) break; - case 0xF1: INDY SBC CYC(5) break; - case 0xF2: CMOS IZPG SBC CYC(5) break; - case 0xF3: INVALID1 CYC(1) break; - case 0xF4: INVALID2 CYC(4) break; - case 0xF5: ZPGX SBC CYC(4) break; - case 0xF6: ZPGX INC CYC(6) break; - case 0xF7: INVALID2 CYC(1) break; // Lock N' Chase calls $F3D4 - case 0xF8: SED CYC(2) break; - case 0xF9: ABSY SBC CYC(4) break; - case 0xFA: CMOS PLX CYC(4) break; - case 0xFB: INVALID1 CYC(1) break; - case 0xFC: INVALID3 CYC(4) break; - case 0xFD: ABSX SBC CYC(4) break; - case 0xFE: ABSX INC CYC(6) break; - case 0xFF: INVALID1 CYC(1) break; + if (regs.bRESET) + { + regs.bRESET = 0; + EF_TO_AF + regs.ps = regs.ps | AF_INTERRUPT; + regs.pc = * (WORD*) (mem+0xFFFC); + regs.sp = 0x0100 | ((regs.sp - 3) & 0xFF); + CYC(7); + continue; } - if(g_bmIRQ && !(regs.ps & AF_INTERRUPT)) - { - // IRQ signals are deasserted when a specific r/w operation is done on device - g_nCycleIrqStart = g_nCumulativeCycles + cycles; - PUSH(regs.pc >> 8) - PUSH(regs.pc & 0xFF) - EF_TO_AF - regs.ps |= AF_RESERVED; - PUSH(regs.ps) - regs.ps |= AF_INTERRUPT; - regs.pc = * (WORD*) (mem+0xFFFE); - CYC(7) - } - - if (bBreakOnInvalid) - break; - - } - while (cycles < totalcycles); - + BYTE iOpcode = *(mem+regs.pc); + if (CheckDebugBreak( iOpcode )) + break; + regs.pc++; + switch (iOpcode) + { + case 0x00: BRK CYC(7) break; + case 0x01: INDX ORA CYC(6) break; + case 0x02: INV HLT CYC(2) break; + case 0x03: INV INDX ASO CYC(8) break; + case 0x04: INV ZPG NOP CYC(3) break; + case 0x05: ZPG ORA CYC(3) break; + case 0x06: ZPG ASL_NMOS CYC(5) break; + case 0x07: INV ZPG ASO CYC(5) break; + case 0x08: PHP CYC(3) break; + case 0x09: IMM ORA CYC(2) break; + case 0x0A: ASLA CYC(2) break; + case 0x0B: INV IMM ANC CYC(2) break; + case 0x0C: INV ABSX NOP CYC(4) break; + case 0x0D: ABS ORA CYC(4) break; + case 0x0E: ABS ASL_NMOS CYC(6) break; + case 0x0F: INV ABS ASO CYC(6) break; + case 0x10: REL BPL CYC(2) break; + case 0x11: INDY ORA CYC(5) break; + case 0x12: INV HLT CYC(2) break; + case 0x13: INV INDY ASO CYC(8) break; + case 0x14: INV ZPGX NOP CYC(4) break; + case 0x15: ZPGX ORA CYC(4) break; + case 0x16: ZPGX ASL_NMOS CYC(6) break; + case 0x17: INV ZPGX ASO CYC(6) break; + case 0x18: CLC CYC(2) break; + case 0x19: ABSY ORA CYC(4) break; + case 0x1A: INV NOP CYC(2) break; + case 0x1B: INV ABSY ASO CYC(7) break; + case 0x1C: INV ABSX NOP CYC(4) break; + case 0x1D: ABSX ORA CYC(4) break; + case 0x1E: ABSX ASL_NMOS CYC(6) break; + case 0x1F: INV ABSX ASO CYC(7) break; + case 0x20: ABS JSR CYC(6) break; + case 0x21: INDX AND CYC(6) break; + case 0x22: INV HLT CYC(2) break; + case 0x23: INV INDX RLA CYC(8) break; + case 0x24: ZPG BIT CYC(3) break; + case 0x25: ZPG AND CYC(3) break; + case 0x26: ZPG ROL_NMOS CYC(5) break; + case 0x27: INV ZPG RLA CYC(5) break; + case 0x28: PLP CYC(4) break; + case 0x29: IMM AND CYC(2) break; + case 0x2A: ROLA CYC(2) break; + case 0x2B: INV IMM ANC CYC(2) break; + case 0x2C: ABS BIT CYC(4) break; + case 0x2D: ABS AND CYC(2) break; + case 0x2E: ABS ROL_NMOS CYC(6) break; + case 0x2F: INV ABS RLA CYC(6) break; + case 0x30: REL BMI CYC(2) break; + case 0x31: INDY AND CYC(5) break; + case 0x32: INV HLT CYC(2) break; + case 0x33: INV INDY RLA CYC(8) break; + case 0x34: INV ZPGX NOP CYC(4) break; + case 0x35: ZPGX AND CYC(4) break; + case 0x36: ZPGX ROL_NMOS CYC(6) break; + case 0x37: INV ZPGX RLA CYC(6) break; + case 0x38: SEC CYC(2) break; + case 0x39: ABSY AND CYC(4) break; + case 0x3A: INV NOP CYC(2) break; + case 0x3B: INV ABSY RLA CYC(7) break; + case 0x3C: INV ABSX NOP CYC(4) break; + case 0x3D: ABSX AND CYC(4) break; + case 0x3E: ABSX ROL_NMOS CYC(6) break; + case 0x3F: INV ABSX RLA CYC(7) break; + case 0x40: RTI CYC(6) DoIrqProfiling(cycles); break; + case 0x41: INDX EOR CYC(6) break; + case 0x42: INV HLT CYC(2) break; + case 0x43: INV INDX LSE CYC(8) break; + case 0x44: INV ZPG NOP CYC(3) break; + case 0x45: ZPG EOR CYC(3) break; + case 0x46: ZPG LSR_NMOS CYC(5) break; + case 0x47: INV ZPG LSE CYC(5) break; + case 0x48: PHA CYC(3) break; + case 0x49: IMM EOR CYC(2) break; + case 0x4A: LSRA CYC(2) break; + case 0x4B: INV IMM ALR CYC(2) break; + case 0x4C: ABS JMP CYC(3) break; + case 0x4D: ABS EOR CYC(4) break; + case 0x4E: ABS LSR_NMOS CYC(6) break; + case 0x4F: INV ABS LSE CYC(6) break; + case 0x50: REL BVC CYC(2) break; + case 0x51: INDY EOR CYC(5) break; + case 0x52: INV HLT CYC(2) break; + case 0x53: INV INDY LSE CYC(8) break; + case 0x54: INV ZPGX NOP CYC(4) break; + case 0x55: ZPGX EOR CYC(4) break; + case 0x56: ZPGX LSR_NMOS CYC(6) break; + case 0x57: INV ZPGX LSE CYC(6) break; + case 0x58: CLI CYC(2) break; + case 0x59: ABSY EOR CYC(4) break; + case 0x5A: INV NOP CYC(2) break; + case 0x5B: INV ABSY LSE CYC(7) break; + case 0x5C: INV ABSX NOP CYC(4) break; + case 0x5D: ABSX EOR CYC(4) break; + case 0x5E: ABSX LSR_NMOS CYC(6) break; + case 0x5F: INV ABSX LSE CYC(7) break; + case 0x60: RTS CYC(6) break; + case 0x61: INDX ADC_NMOS CYC(6) break; + case 0x62: INV HLT CYC(2) break; + case 0x63: INV INDX RRA CYC(8) break; + case 0x64: INV ZPG NOP CYC(3) break; + case 0x65: ZPG ADC_NMOS CYC(3) break; + case 0x66: ZPG ROR_NMOS CYC(5) break; + case 0x67: INV ZPG RRA CYC(5) break; + case 0x68: PLA CYC(4) break; + case 0x69: IMM ADC_NMOS CYC(2) break; + case 0x6A: RORA CYC(2) break; + case 0x6B: INV IMM ARR CYC(2) break; + case 0x6C: IABSNMOS JMP CYC(6) break; + case 0x6D: ABS ADC_NMOS CYC(4) break; + case 0x6E: ABS ROR_NMOS CYC(6) break; + case 0x6F: INV ABS RRA CYC(6) break; + case 0x70: REL BVS CYC(2) break; + case 0x71: INDY ADC_NMOS CYC(5) break; + case 0x72: INV HLT CYC(2) break; + case 0x73: INV INDY RRA CYC(8) break; + case 0x74: INV ZPGX NOP CYC(4) break; + case 0x75: ZPGX ADC_NMOS CYC(4) break; + case 0x76: ZPGX ROR_NMOS CYC(6) break; + case 0x77: INV ZPGX RRA CYC(6) break; + case 0x78: SEI CYC(2) break; + case 0x79: ABSY ADC_NMOS CYC(4) break; + case 0x7A: INV NOP CYC(2) break; + case 0x7B: INV ABSY RRA CYC(7) break; + case 0x7C: INV ABSX NOP CYC(4) break; + case 0x7D: ABSX ADC_NMOS CYC(4) break; + case 0x7E: ABSX ROR_NMOS CYC(6) break; + case 0x7F: INV ABSX RRA CYC(7) break; + case 0x80: INV IMM NOP CYC(2) break; + case 0x81: INDX STA CYC(6) break; + case 0x82: INV IMM NOP CYC(2) break; + case 0x83: INV INDX AXS CYC(6) break; + case 0x84: ZPG STY CYC(3) break; + case 0x85: ZPG STA CYC(3) break; + case 0x86: ZPG STX CYC(3) break; + case 0x87: INV ZPG AXS CYC(3) break; + case 0x88: DEY CYC(2) break; + case 0x89: INV IMM NOP CYC(2) break; + case 0x8A: TXA CYC(2) break; + case 0x8B: INV IMM XAA CYC(2) break; + case 0x8C: ABS STY CYC(4) break; + case 0x8D: ABS STA CYC(4) break; + case 0x8E: ABS STX CYC(4) break; + case 0x8F: INV ABS AXS CYC(4) break; + case 0x90: REL BCC CYC(2) break; + case 0x91: INDY STA CYC(6) break; + case 0x92: INV HLT CYC(2) break; + case 0x93: INV INDY AXA CYC(6) break; + case 0x94: ZPGX STY CYC(4) break; + case 0x95: ZPGX STA CYC(4) break; + case 0x96: ZPGY STX CYC(4) break; + case 0x97: INV ZPGY AXS CYC(4) break; + case 0x98: TYA CYC(2) break; + case 0x99: ABSY STA CYC(5) break; + case 0x9A: TXS CYC(2) break; + case 0x9B: INV ABSY TAS CYC(5) break; + case 0x9C: INV ABSX SAY CYC(5) break; + case 0x9D: ABSX STA CYC(5) break; + case 0x9E: INV ABSY XAS CYC(5) break; + case 0x9F: INV ABSY AXA CYC(5) break; + case 0xA0: IMM LDY CYC(2) break; + case 0xA1: INDX LDA CYC(6) break; + case 0xA2: IMM LDX CYC(2) break; + case 0xA3: INV INDX LAX CYC(6) break; + case 0xA4: ZPG LDY CYC(3) break; + case 0xA5: ZPG LDA CYC(3) break; + case 0xA6: ZPG LDX CYC(3) break; + case 0xA7: INV ZPG LAX CYC(3) break; + case 0xA8: TAY CYC(2) break; + case 0xA9: IMM LDA CYC(2) break; + case 0xAA: TAX CYC(2) break; + case 0xAB: INV IMM OAL CYC(2) break; + case 0xAC: ABS LDY CYC(4) break; + case 0xAD: ABS LDA CYC(4) break; + case 0xAE: ABS LDX CYC(4) break; + case 0xAF: INV ABS LAX CYC(4) break; + case 0xB0: REL BCS CYC(2) break; + case 0xB1: INDY LDA CYC(5) break; + case 0xB2: INV HLT CYC(2) break; + case 0xB3: INV INDY LAX CYC(5) break; + case 0xB4: ZPGX LDY CYC(4) break; + case 0xB5: ZPGX LDA CYC(4) break; + case 0xB6: ZPGY LDX CYC(4) break; + case 0xB7: INV ZPGY LAX CYC(4) break; + case 0xB8: CLV CYC(2) break; + case 0xB9: ABSY LDA CYC(4) break; + case 0xBA: TSX CYC(2) break; + case 0xBB: INV ABSY LAS CYC(4) break; + case 0xBC: ABSX LDY CYC(4) break; + case 0xBD: ABSX LDA CYC(4) break; + case 0xBE: ABSY LDX CYC(4) break; + case 0xBF: INV ABSY LAX CYC(4) break; + case 0xC0: IMM CPY CYC(2) break; + case 0xC1: INDX CMP CYC(6) break; + case 0xC2: INV IMM NOP CYC(2) break; + case 0xC3: INV INDX DCM CYC(8) break; + case 0xC4: ZPG CPY CYC(3) break; + case 0xC5: ZPG CMP CYC(3) break; + case 0xC6: ZPG DEC_NMOS CYC(5) break; + case 0xC7: INV ZPG DCM CYC(5) break; + case 0xC8: INY CYC(2) break; + case 0xC9: IMM CMP CYC(2) break; + case 0xCA: DEX CYC(2) break; + case 0xCB: INV IMM SAX CYC(2) break; + case 0xCC: ABS CPY CYC(4) break; + case 0xCD: ABS CMP CYC(4) break; + case 0xCE: ABS DEC_NMOS CYC(5) break; + case 0xCF: INV ABS DCM CYC(6) break; + case 0xD0: REL BNE CYC(2) break; + case 0xD1: INDY CMP CYC(5) break; + case 0xD2: INV HLT CYC(2) break; + case 0xD3: INV INDY DCM CYC(8) break; + case 0xD4: INV ZPGX NOP CYC(4) break; + case 0xD5: ZPGX CMP CYC(4) break; + case 0xD6: ZPGX DEC_NMOS CYC(6) break; + case 0xD7: INV ZPGX DCM CYC(6) break; + case 0xD8: CLD CYC(2) break; + case 0xD9: ABSY CMP CYC(4) break; + case 0xDA: INV NOP CYC(2) break; + case 0xDB: INV ABSY DCM CYC(7) break; + case 0xDC: INV ABSX NOP CYC(4) break; + case 0xDD: ABSX CMP CYC(4) break; + case 0xDE: ABSX DEC_NMOS CYC(6) break; + case 0xDF: INV ABSX DCM CYC(7) break; + case 0xE0: IMM CPX CYC(2) break; + case 0xE1: INDX SBC_NMOS CYC(6) break; + case 0xE2: INV IMM NOP CYC(2) break; + case 0xE3: INV INDX INS CYC(8) break; + case 0xE4: ZPG CPX CYC(3) break; + case 0xE5: ZPG SBC_NMOS CYC(3) break; + case 0xE6: ZPG INC_NMOS CYC(5) break; + case 0xE7: INV ZPG INS CYC(5) break; + case 0xE8: INX CYC(2) break; + case 0xE9: IMM SBC_NMOS CYC(2) break; + case 0xEA: NOP CYC(2) break; + case 0xEB: INV IMM SBC_NMOS CYC(2) break; + case 0xEC: ABS CPX CYC(4) break; + case 0xED: ABS SBC_NMOS CYC(4) break; + case 0xEE: ABS INC_NMOS CYC(6) break; + case 0xEF: INV ABS INS CYC(6) break; + case 0xF0: REL BEQ CYC(2) break; + case 0xF1: INDY SBC_NMOS CYC(5) break; + case 0xF2: INV HLT CYC(2) break; + case 0xF3: INV INDY INS CYC(8) break; + case 0xF4: INV ZPGX NOP CYC(4) break; + case 0xF5: ZPGX SBC_NMOS CYC(4) break; + case 0xF6: ZPGX INC_NMOS CYC(6) break; + case 0xF7: INV ZPGX INS CYC(6) break; + case 0xF8: SED CYC(2) break; + case 0xF9: ABSY SBC_NMOS CYC(4) break; + case 0xFA: INV NOP CYC(2) break; + case 0xFB: INV ABSY INS CYC(7) break; + case 0xFC: INV ABSX NOP CYC(4) break; + case 0xFD: ABSX SBC_NMOS CYC(4) break; + case 0xFE: ABSX INC_NMOS CYC(6) break; + case 0xFF: INV ABSX INS CYC(7) break; + } + if(g_bNmiFlank && !regs.bJammed) + { + // NMI signals are only serviced once + g_bNmiFlank = FALSE; + g_nCycleIrqStart = g_nCumulativeCycles + cycles; + PUSH(regs.pc >> 8) + PUSH(regs.pc & 0xFF) EF_TO_AF - - return cycles; + PUSH(regs.ps & ~AF_BREAK) + regs.ps = regs.ps | AF_INTERRUPT; + regs.pc = * (WORD*) (mem+0xFFFA); + CYC(7) + } + if(g_bmIRQ && !(regs.ps & AF_INTERRUPT) && !regs.bJammed) + { + // IRQ signals are deasserted when a specific r/w operation is done on device + g_nCycleIrqStart = g_nCumulativeCycles + cycles; + PUSH(regs.pc >> 8) + PUSH(regs.pc & 0xFF) + EF_TO_AF + PUSH(regs.ps & ~AF_BREAK) + regs.ps = regs.ps | AF_INTERRUPT; + regs.pc = * (WORD*) (mem+0xFFFE); + CYC(7) + } + if (bBreakOnInvalid) + break; + } while (cycles < totalcycles); + EF_TO_AF + return cycles; + } } // @@ -830,7 +1468,7 @@ void CpuDestroy () { FreeLibrary(cpulibrary[loop]); cpuexecutefunc[loop] = NULL; cpugetcodefunc[loop] = NULL; - cpulibrary[loop] = (HINSTANCE)0; + cpulibrary[loop] = (HINSTANCE)0; } if (g_bCritSectionValid) @@ -841,7 +1479,6 @@ void CpuDestroy () { } //=========================================================================== - // Pre: // Call this when an IO-reg is access & accurate cycle info is needed // Post: @@ -874,7 +1511,6 @@ void CpuCalcCycles(ULONG nCyclesLeft) } //=========================================================================== - ULONG CpuGetCyclesThisFrame() { CpuCalcCycles(nInternalCyclesLeft); // TODO: simplify the whole cycle system! @@ -882,7 +1518,6 @@ ULONG CpuGetCyclesThisFrame() } //=========================================================================== - DWORD CpuExecute (DWORD cycles) { static BOOL laststep = 0; @@ -930,7 +1565,7 @@ DWORD CpuExecute (DWORD cycles) g_nCumulativeCycles += nRemainingCycles; if (cpuexecutefunc[cpuemtype]) - MB_UpdateCycles((USHORT) nRemainingCycles); // OLD: Support external dll emulator + MB_UpdateCycles((USHORT) nRemainingCycles); // OLD: Support external dll emulator return result; } @@ -944,22 +1579,20 @@ void CpuGetCode (WORD address, LPBYTE *codeptr, DWORD *codelength) { } //=========================================================================== - #define MIN_DLL_VERSION 1 void CpuInitialize () { CpuDestroy(); - - regs.a = 0; - regs.x = 0; - regs.y = 0; - regs.ps = 0x20; - regs.pc = *(LPWORD)(mem+0xFFFC); + regs.a = regs.x = regs.y = regs.ps = 0xFF; regs.sp = 0x01FF; + regs.pc=*(LPWORD)(mem+0xFFFC); + regs.bRESET = 1; + regs.bJammed = 0; InitializeCriticalSection(&g_CriticalSection); g_bCritSectionValid = true; CpuIrqReset(); + CpuNmiReset(); #ifdef _X86_ // TO DO: @@ -987,8 +1620,8 @@ void CpuInitialize () { int loop = 3; while (loop--) if (cpulibrary[loop]) { - cpuversionfunc[loop] = (cpuversiontype)GetProcAddress(cpulibrary[loop], - TEXT("CpuVersion")); + cpuversionfunc[loop] = (cpuversiontype)GetProcAddress(cpulibrary[loop], + TEXT("CpuVersion")); if (cpuversionfunc[loop] && (cpuversionfunc[loop]()>=MIN_DLL_VERSION)) { cpuexecutefunc[loop] = (cpuexecutetype)GetProcAddress(cpulibrary[loop], @@ -1012,8 +1645,8 @@ void CpuInitialize () { void CpuReinitialize () { if (cpulibrary[cpuemtype] && cpuinitfunc[cpuemtype]) cpuinitfunc[cpuemtype](mem,memshadow[0],memwrite[0], - image,lastimage, - ®s,ioread,iowrite,memdirty, + image,lastimage, + ®s,ioread,iowrite,memdirty, CxReadFunc,CxWriteFunc); } @@ -1040,14 +1673,14 @@ void CpuSetupBenchmark () { *(mem+addr++) = benchopcode[opcode]; *(mem+addr++) = benchopcode[opcode]; if (opcode >= SHORTOPCODES) - *(mem+addr++) = 0; + *(mem+addr++) = 0; if ((++opcode >= BENCHOPCODES) || ((addr & 0x0F) >= 0x0B)) { - *(mem+addr++) = 0x4C; - *(mem+addr++) = (opcode >= BENCHOPCODES) ? 0x00 - : ((addr >> 4)+1) << 4; - *(mem+addr++) = 0x03; - while (addr & 0x0F) - ++addr; + *(mem+addr++) = 0x4C; + *(mem+addr++) = (opcode >= BENCHOPCODES) ? 0x00 + : ((addr >> 4)+1) << 4; + *(mem+addr++) = 0x03; + while (addr & 0x0F) + ++addr; } } while (opcode < BENCHOPCODES); } @@ -1059,7 +1692,6 @@ BOOL CpuSupportsFastPaging () { } //=========================================================================== - void CpuIrqReset() { _ASSERT(g_bCritSectionValid); @@ -1083,14 +1715,48 @@ void CpuIrqDeassert(eIRQSRC Device) g_bmIRQ &= ~(1<A = regs.a; pSS->X = regs.x; pSS->Y = regs.y; - pSS->P = regs.ps; + pSS->P = regs.ps | AF_RESERVED | AF_BREAK; pSS->S = (BYTE) (regs.sp & 0xff); pSS->PC = regs.pc; pSS->g_nCumulativeCycles = g_nCumulativeCycles; @@ -1103,10 +1769,11 @@ DWORD CpuSetSnapshot(SS_CPU6502* pSS) regs.a = pSS->A; regs.x = pSS->X; regs.y = pSS->Y; - regs.ps = pSS->P; - regs.sp = (USHORT)pSS->S + 0x100; + regs.ps = pSS->P | AF_RESERVED | AF_BREAK; + regs.sp = (USHORT)pSS->S | 0x100; regs.pc = pSS->PC; CpuIrqReset(); + CpuNmiReset(); g_nCumulativeCycles = pSS->g_nCumulativeCycles; return 0; diff --git a/AppleWin/source/CPU.h b/AppleWin/source/CPU.h index 77f3f776..89df0b25 100644 --- a/AppleWin/source/CPU.h +++ b/AppleWin/source/CPU.h @@ -11,7 +11,8 @@ typedef struct _regsrec { BYTE ps; // processor status WORD pc; // program counter WORD sp; // stack pointer - BYTE bIRQ; // IRQ asserted flag + BYTE bRESET; // RESET asserted flag + BYTE bJammed; // CPU has crashed (NMOS 6502 only) } regsrec, *regsptr; extern DWORD cpuemtype; @@ -31,5 +32,9 @@ BOOL CpuSupportsFastPaging (); void CpuIrqReset(); void CpuIrqAssert(eIRQSRC Device); void CpuIrqDeassert(eIRQSRC Device); +void CpuNmiReset(); +void CpuNmiAssert(eIRQSRC Device); +void CpuNmiDeassert(eIRQSRC Device); +void CpuReset (); DWORD CpuGetSnapshot(SS_CPU6502* pSS); DWORD CpuSetSnapshot(SS_CPU6502* pSS); diff --git a/AppleWin/source/Common.h b/AppleWin/source/Common.h index c0b913d2..bd091e00 100644 --- a/AppleWin/source/Common.h +++ b/AppleWin/source/Common.h @@ -1,7 +1,7 @@ #pragma once -const double _M14 = 14.31818e6; -const double CLK_6502 = (_M14 / 14.0); // 1022727 + 1/7 +const double _M14 = (157500000.0 / 11.0); // 14.3181818... * 10^6 +const double CLK_6502 = ((_M14 * 65.0) / 912.0); // 65 cycles per 912 14M clocks //const double CLK_6502 = 23 * 44100; // 1014300 const UINT uCyclesPerLine = 65; // 25 cycles of HBL & 40 cycles of HBL' diff --git a/AppleWin/source/Debugger_Assembler.cpp b/AppleWin/source/Debugger_Assembler.cpp index f667c547..e986b9e3 100644 --- a/AppleWin/source/Debugger_Assembler.cpp +++ b/AppleWin/source/Debugger_Assembler.cpp @@ -82,91 +82,88 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define SR MEM_S | MEM_RI const Opcodes_t g_aOpcodes65C02[ NUM_OPCODES ] = { - {"BRK", 0 , 0}, {"ORA", AM_IZX, R_}, {"NOP", AM_2 , 0 }, {"NOP", AM_1 , 0 }, // 00 .. 03 - {"TSB", AM_Z , _W}, {"ORA", AM_Z , R_}, {"ASL", AM_Z , RW}, {"NOP", AM_1 , 0 }, // 04 .. 07 - {"PHP", 0 , SW}, {"ORA", AM_M , im}, {"ASL", 0 , 0}, {"NOP", AM_1 , 0 }, // 08 .. 0B - {"TSB", AM_A , _W}, {"ORA", AM_A , R_}, {"ASL", AM_A , RW}, {"NOP", AM_3 , 0 }, // 0C .. 0F - {"BPL", AM_R , 0}, {"ORA", AM_NZY, R_}, {"ORA", AM_NZ , R_}, {"NOP", AM_1 , 0 }, // 10 .. 13 - {"TRB", AM_Z , _W}, {"ORA", AM_ZX , R_}, {"ASL", AM_ZX , RW}, {"NOP", AM_1 , 0 }, // 14 .. 17 - {"CLC", 0 , 0}, {"ORA", AM_AY , R_}, {"INA", 0 , 0}, {"NOP", AM_1 , 0 }, // 18 .. 1B - {"TRB", AM_A , _W}, {"ORA", AM_AX , R_}, {"ASL", AM_AX , RW}, {"NOP", AM_1 , 0 }, // 1C .. 1F + {"BRK", 0 , 0}, {"ORA", AM_IZX, R_}, {"nop", AM_M , im}, {"nop", 0 , 0 }, // 00 .. 03 + {"TSB", AM_Z , _W}, {"ORA", AM_Z , R_}, {"ASL", AM_Z , RW}, {"nop", 0 , 0 }, // 04 .. 07 + {"PHP", 0 , SW}, {"ORA", AM_M , im}, {"ASL", 0 , 0}, {"nop", 0 , 0 }, // 08 .. 0B + {"TSB", AM_A , _W}, {"ORA", AM_A , R_}, {"ASL", AM_A , RW}, {"nop", 0 , 0 }, // 0C .. 0F + {"BPL", AM_R , 0}, {"ORA", AM_NZY, R_}, {"ORA", AM_NZ , R_}, {"nop", 0 , 0 }, // 10 .. 13 + {"TRB", AM_Z , _W}, {"ORA", AM_ZX , R_}, {"ASL", AM_ZX , RW}, {"nop", 0 , 0 }, // 14 .. 17 + {"CLC", 0 , 0}, {"ORA", AM_AY , R_}, {"INC", 0 , 0}, {"nop", 0 , 0 }, // 18 .. 1B + {"TRB", AM_A , _W}, {"ORA", AM_AX , R_}, {"ASL", AM_AX , RW}, {"nop", 0 , 0 }, // 1C .. 1F - {"JSR", AM_A , SW}, {"AND", AM_IZX, R_}, {"NOP", AM_2 , 0}, {"NOP", AM_1 , 0 }, // 20 .. 23 - {"BIT", AM_Z , R_}, {"AND", AM_Z , R_}, {"ROL", AM_Z , RW}, {"NOP", AM_1 , 0 }, // 24 .. 27 - {"PLP", 0 , SR}, {"AND", AM_M , im}, {"ROL", 0 , 0}, {"NOP", AM_1 , 0 }, // 28 .. 2B - {"BIT", AM_A , R_}, {"AND", AM_A , R_}, {"ROL", AM_A , RW}, {"NOP", AM_3 , 0 }, // 2C .. 2F - {"BMI", AM_R , 0}, {"AND", AM_NZY, R_}, {"AND", AM_NZ , R_}, {"NOP", AM_1 , 0 }, // 30 .. 33 - {"BIT", AM_ZX , R_}, {"AND", AM_ZX , R_}, {"ROL", AM_ZX , RW}, {"NOP", AM_1 , 0 }, // 34 .. 37 - {"SEC", 0 , 0}, {"AND", AM_AY , R_}, {"DEA", 0 , 0}, {"NOP", AM_1 , 0 }, // 38 .. 3B - {"BIT", AM_AX , R_}, {"AND", AM_AX , R_}, {"ROL", AM_AX , RW}, {"NOP", AM_1 , 0 }, // 3C .. 3F + {"JSR", AM_A , SW}, {"AND", AM_IZX, R_}, {"nop", AM_M , im}, {"nop", 0 , 0 }, // 20 .. 23 + {"BIT", AM_Z , R_}, {"AND", AM_Z , R_}, {"ROL", AM_Z , RW}, {"nop", 0 , 0 }, // 24 .. 27 + {"PLP", 0 , SR}, {"AND", AM_M , im}, {"ROL", 0 , 0}, {"nop", 0 , 0 }, // 28 .. 2B + {"BIT", AM_A , R_}, {"AND", AM_A , R_}, {"ROL", AM_A , RW}, {"nop", 0 , 0 }, // 2C .. 2F + {"BMI", AM_R , 0}, {"AND", AM_NZY, R_}, {"AND", AM_NZ , R_}, {"nop", 0 , 0 }, // 30 .. 33 + {"BIT", AM_ZX , R_}, {"AND", AM_ZX , R_}, {"ROL", AM_ZX , RW}, {"nop", 0 , 0 }, // 34 .. 37 + {"SEC", 0 , 0}, {"AND", AM_AY , R_}, {"DEC", 0 , 0}, {"nop", 0 , 0 }, // 38 .. 3B + {"BIT", AM_AX , R_}, {"AND", AM_AX , R_}, {"ROL", AM_AX , RW}, {"nop", 0 , 0 }, // 3C .. 3F - {"RTI", 0 , 0}, {"EOR", AM_IZX, R_}, {"NOP", AM_2 , 0}, {"NOP", AM_1 , 0 }, // 40 .. 43 - {"NOP", AM_2 , 0}, {"EOR", AM_Z , R_}, {"LSR", AM_Z , _W}, {"NOP", AM_1 , 0 }, // 44 .. 47 - {"PHA", 0 , SW}, {"EOR", AM_M , im}, {"LSR", 0 , 0}, {"NOP", AM_1 , 0 }, // 48 .. 4B - {"JMP", AM_A , 0}, {"EOR", AM_A , R_}, {"LSR", AM_A , _W}, {"NOP", AM_1 , 0 }, // 4C .. 4F - {"BVC", AM_R , 0}, {"EOR", AM_NZY, R_}, {"EOR", AM_NZ , R_}, {"NOP", AM_1 , 0 }, // 50 .. 53 - {"NOP", AM_2 , 0}, {"EOR", AM_ZX , R_}, {"LSR", AM_ZX , _W}, {"NOP", AM_1 , 0 }, // 54 .. 57 - {"CLI", 0 , 0}, {"EOR", AM_AY , R_}, {"PHY", 0 , SW}, {"NOP", AM_1 , 0 }, // 58 .. 5B - {"NOP", AM_3 , 0}, {"EOR", AM_AX , R_}, {"LSR", AM_AX , RW}, {"NOP", AM_1 , 0 }, // 5C .. 5F + {"RTI", 0 , 0}, {"EOR", AM_IZX, R_}, {"nop", AM_M , im}, {"nop", 0 , 0 }, // 40 .. 43 + {"nop", AM_Z , 0}, {"EOR", AM_Z , R_}, {"LSR", AM_Z , _W}, {"nop", 0 , 0 }, // 44 .. 47 + {"PHA", 0 , SW}, {"EOR", AM_M , im}, {"LSR", 0 , 0}, {"nop", 0 , 0 }, // 48 .. 4B + {"JMP", AM_A , 0}, {"EOR", AM_A , R_}, {"LSR", AM_A , _W}, {"nop", 0 , 0 }, // 4C .. 4F + {"BVC", AM_R , 0}, {"EOR", AM_NZY, R_}, {"EOR", AM_NZ , R_}, {"nop", 0 , 0 }, // 50 .. 53 + {"nop", AM_ZX , 0}, {"EOR", AM_ZX , R_}, {"LSR", AM_ZX , _W}, {"nop", 0 , 0 }, // 54 .. 57 + {"CLI", 0 , 0}, {"EOR", AM_AY , R_}, {"PHY", 0 , SW}, {"nop", 0 , 0 }, // 58 .. 5B + {"nop", AM_AX , 0}, {"EOR", AM_AX , R_}, {"LSR", AM_AX , RW}, {"nop", 0 , 0 }, // 5C .. 5F - {"RTS", 0 , SR}, {"ADC", AM_IZX, R_}, {"NOP", AM_2 , 0}, {"NOP", AM_1 , 0 }, // 60 .. 63 - {"STZ", AM_Z , _W}, {"ADC", AM_Z , R_}, {"ROR", AM_Z , RW}, {"NOP", AM_1 , 0 }, // 64 .. 67 - {"PLA", 0 , SR}, {"ADC", AM_M , im}, {"ROR", 0 , 0}, {"NOP", AM_1 , 0 }, // 68 .. 6B - {"JMP", AM_NA , 0}, {"ADC", AM_A , R_}, {"ROR", AM_A , RW}, {"NOP", AM_1 , 0 }, // 6C .. 6F - {"BVS", AM_R , 0}, {"ADC", AM_NZY, R_}, {"ADC", AM_NZ , R_}, {"NOP", AM_1 , 0 }, // 70 .. 73 - {"STZ", AM_ZX , _W}, {"ADC", AM_ZX , R_}, {"ROR", AM_ZX , RW}, {"NOP", AM_1 , 0 }, // 74 .. 77 - {"SEI", 0 , 0}, {"ADC", AM_AY , R_}, {"PLY", 0 , SR}, {"NOP", AM_1 , 0 }, // 78 .. 7B - {"JMP", AM_IAX, 0}, {"ADC", AM_AX , R_}, {"ROR", AM_AX , RW}, {"NOP", AM_1 , 0 }, // 7C .. 7F + {"RTS", 0 , SR}, {"ADC", AM_IZX, R_}, {"nop", AM_M , im}, {"nop", 0 , 0 }, // 60 .. 63 + {"STZ", AM_Z , _W}, {"ADC", AM_Z , R_}, {"ROR", AM_Z , RW}, {"nop", 0 , 0 }, // 64 .. 67 + {"PLA", 0 , SR}, {"ADC", AM_M , im}, {"ROR", 0 , 0}, {"nop", 0 , 0 }, // 68 .. 6B + {"JMP", AM_NA , 0}, {"ADC", AM_A , R_}, {"ROR", AM_A , RW}, {"nop", 0 , 0 }, // 6C .. 6F + {"BVS", AM_R , 0}, {"ADC", AM_NZY, R_}, {"ADC", AM_NZ , R_}, {"nop", 0 , 0 }, // 70 .. 73 + {"STZ", AM_ZX , _W}, {"ADC", AM_ZX , R_}, {"ROR", AM_ZX , RW}, {"nop", 0 , 0 }, // 74 .. 77 + {"SEI", 0 , 0}, {"ADC", AM_AY , R_}, {"PLY", 0 , SR}, {"nop", 0 , 0 }, // 78 .. 7B + {"JMP", AM_IAX, 0}, {"ADC", AM_AX , R_}, {"ROR", AM_AX , RW}, {"nop", 0 , 0 }, // 7C .. 7F - {"BRA", AM_R , 0}, {"STA", AM_IZX, _W}, {"NOP", AM_2 , 0}, {"NOP", AM_1 , 0 }, // 80 .. 83 - {"STY", AM_Z , _W}, {"STA", AM_Z , _W}, {"STX", AM_Z , _W}, {"NOP", AM_1 , 0 }, // 84 .. 87 - {"DEY", 0 , 0}, {"BIT", AM_M , im}, {"TXA", 0 , 0}, {"NOP", AM_1 , 0 }, // 88 .. 8B - {"STY", AM_A , _W}, {"STA", AM_A , _W}, {"STX", AM_A , _W}, {"NOP", AM_1 , 0 }, // 8C .. 8F - {"BCC", AM_R , 0}, {"STA", AM_NZY, _W}, {"STA", AM_NZ , _W}, {"NOP", AM_1 , 0 }, // 90 .. 93 - {"STY", AM_ZX , _W}, {"STA", AM_ZX , _W}, {"STX", AM_ZY , _W}, {"NOP", AM_1 , 0 }, // 94 .. 97 - {"TYA", 0 , 0}, {"STA", AM_AY , _W}, {"TXS", 0 , 0}, {"NOP", AM_1 , 0 }, // 98 .. 9B - {"STZ", AM_A , _W}, {"STA", AM_AX , _W}, {"STZ", AM_AX , _W}, {"NOP", AM_1 , 0 }, // 9C .. 9F + {"BRA", AM_R , 0}, {"STA", AM_IZX, _W}, {"nop", AM_M , im}, {"nop", 0 , 0 }, // 80 .. 83 + {"STY", AM_Z , _W}, {"STA", AM_Z , _W}, {"STX", AM_Z , _W}, {"nop", 0 , 0 }, // 84 .. 87 + {"DEY", 0 , 0}, {"BIT", AM_M , im}, {"TXA", 0 , 0}, {"nop", 0 , 0 }, // 88 .. 8B + {"STY", AM_A , _W}, {"STA", AM_A , _W}, {"STX", AM_A , _W}, {"nop", 0 , 0 }, // 8C .. 8F + {"BCC", AM_R , 0}, {"STA", AM_NZY, _W}, {"STA", AM_NZ , _W}, {"nop", 0 , 0 }, // 90 .. 93 + {"STY", AM_ZX , _W}, {"STA", AM_ZX , _W}, {"STX", AM_ZY , _W}, {"nop", 0 , 0 }, // 94 .. 97 + {"TYA", 0 , 0}, {"STA", AM_AY , _W}, {"TXS", 0 , 0}, {"nop", 0 , 0 }, // 98 .. 9B + {"STZ", AM_A , _W}, {"STA", AM_AX , _W}, {"STZ", AM_AX , _W}, {"nop", 0 , 0 }, // 9C .. 9F - {"LDY", AM_M , im}, {"LDA", AM_IZX, R_}, {"LDX", AM_M , im}, {"NOP", AM_1 , 0 }, // A0 .. A3 - {"LDY", AM_Z , R_}, {"LDA", AM_Z , R_}, {"LDX", AM_Z , R_}, {"NOP", AM_1 , 0 }, // A4 .. A7 - {"TAY", 0 , 0}, {"LDA", AM_M , im}, {"TAX", 0 , 0 }, {"NOP", AM_1 , 0 }, // A8 .. AB - {"LDY", AM_A , R_}, {"LDA", AM_A , R_}, {"LDX", AM_A , R_}, {"NOP", AM_1 , 0 }, // AC .. AF - {"BCS", AM_R , 0}, {"LDA", AM_NZY, R_}, {"LDA", AM_NZ , R_}, {"NOP", AM_1 , 0 }, // B0 .. B3 - {"LDY", AM_ZX , R_}, {"LDA", AM_ZX , R_}, {"LDX", AM_ZY , R_}, {"NOP", AM_1 , 0 }, // B4 .. B7 - {"CLV", 0 , 0}, {"LDA", AM_AY , R_}, {"TSX", 0 , 0 }, {"NOP", AM_1 , 0 }, // B8 .. BB - {"LDY", AM_AX , R_}, {"LDA", AM_AX , R_}, {"LDX", AM_AY , R_}, {"NOP", AM_1 , 0 }, // BC .. BF + {"LDY", AM_M , im}, {"LDA", AM_IZX, R_}, {"LDX", AM_M , im}, {"nop", 0 , 0 }, // A0 .. A3 + {"LDY", AM_Z , R_}, {"LDA", AM_Z , R_}, {"LDX", AM_Z , R_}, {"nop", 0 , 0 }, // A4 .. A7 + {"TAY", 0 , 0}, {"LDA", AM_M , im}, {"TAX", 0 , 0 }, {"nop", 0 , 0 }, // A8 .. AB + {"LDY", AM_A , R_}, {"LDA", AM_A , R_}, {"LDX", AM_A , R_}, {"nop", 0 , 0 }, // AC .. AF + {"BCS", AM_R , 0}, {"LDA", AM_NZY, R_}, {"LDA", AM_NZ , R_}, {"nop", 0 , 0 }, // B0 .. B3 + {"LDY", AM_ZX , R_}, {"LDA", AM_ZX , R_}, {"LDX", AM_ZY , R_}, {"nop", 0 , 0 }, // B4 .. B7 + {"CLV", 0 , 0}, {"LDA", AM_AY , R_}, {"TSX", 0 , 0 }, {"nop", 0 , 0 }, // B8 .. BB + {"LDY", AM_AX , R_}, {"LDA", AM_AX , R_}, {"LDX", AM_AY , R_}, {"nop", 0 , 0 }, // BC .. BF - {"CPY", AM_M , im}, {"CMP", AM_IZX, R_}, {"NOP", AM_2 , 0}, {"NOP", AM_1 , 0 }, // C0 .. C3 - {"CPY", AM_Z , R_}, {"CMP", AM_Z , R_}, {"DEC", AM_Z , RW}, {"NOP", AM_1 , 0 }, // C4 .. C7 - {"INY", 0 , 0}, {"CMP", AM_M , im}, {"DEX", 0 , 0}, {"NOP", AM_1 , 0 }, // C8 .. CB - {"CPY", AM_A , R_}, {"CMP", AM_A , R_}, {"DEC", AM_A , RW}, {"NOP", AM_1 , 0 }, // CC .. CF - {"BNE", AM_R , 0}, {"CMP", AM_NZY, R_}, {"CMP", AM_NZ , 0}, {"NOP", AM_1 , 0 }, // D0 .. D3 - {"NOP", AM_2 , 0}, {"CMP", AM_ZX , R_}, {"DEC", AM_ZX , RW}, {"NOP", AM_1 , 0 }, // D4 .. D7 - {"CLD", 0 , 0}, {"CMP", AM_AY , R_}, {"PHX", 0 , 0}, {"NOP", AM_1 , 0 }, // D8 .. DB - {"NOP", AM_3 , 0}, {"CMP", AM_AX , R_}, {"DEC", AM_AX , RW}, {"NOP", AM_1 , 0 }, // DC .. DF + {"CPY", AM_M , im}, {"CMP", AM_IZX, R_}, {"nop", AM_M , im}, {"nop", 0 , 0 }, // C0 .. C3 + {"CPY", AM_Z , R_}, {"CMP", AM_Z , R_}, {"DEC", AM_Z , RW}, {"nop", 0 , 0 }, // C4 .. C7 + {"INY", 0 , 0}, {"CMP", AM_M , im}, {"DEX", 0 , 0}, {"nop", 0 , 0 }, // C8 .. CB + {"CPY", AM_A , R_}, {"CMP", AM_A , R_}, {"DEC", AM_A , RW}, {"nop", 0 , 0 }, // CC .. CF + {"BNE", AM_R , 0}, {"CMP", AM_NZY, R_}, {"CMP", AM_NZ , 0}, {"nop", 0 , 0 }, // D0 .. D3 + {"nop", AM_ZX , 0}, {"CMP", AM_ZX , R_}, {"DEC", AM_ZX , RW}, {"nop", 0 , 0 }, // D4 .. D7 + {"CLD", 0 , 0}, {"CMP", AM_AY , R_}, {"PHX", 0 , 0}, {"nop", 0 , 0 }, // D8 .. DB + {"nop", AM_AX , 0}, {"CMP", AM_AX , R_}, {"DEC", AM_AX , RW}, {"nop", 0 , 0 }, // DC .. DF - {"CPX", AM_M , im}, {"SBC", AM_IZX, R_}, {"NOP", AM_2 , 0}, {"NOP", AM_1 , 0 }, // E0 .. E3 - {"CPX", AM_Z , R_}, {"SBC", AM_Z , R_}, {"INC", AM_Z , RW}, {"NOP", AM_1 , 0 }, // E4 .. E7 - {"INX", 0 , 0}, {"SBC", AM_M , R_}, {"NOP", 0 , 0}, {"NOP", AM_1 , 0 }, // E8 .. EB - {"CPX", AM_A , R_}, {"SBC", AM_A , R_}, {"INC", AM_A , RW}, {"NOP", AM_1 , 0 }, // EC .. EF - {"BEQ", AM_R , 0}, {"SBC", AM_NZY, R_}, {"SBC", AM_NZ , 0}, {"NOP", AM_1 , 0 }, // F0 .. F3 - {"NOP", AM_2 , 0}, {"SBC", AM_ZX , R_}, {"INC", AM_ZX , RW}, {"???", AM_ZX , 0 }, // F4 .. F7 - {"SED", 0 , 0}, {"SBC", AM_AY , R_}, {"PLX", 0 , 0}, {"NOP", AM_1 , 0 }, // F8 .. FB - {"NOP", AM_3 , 0}, {"SBC", AM_AX , R_}, {"INC", AM_AX , RW}, {"NOP", AM_1 , 0 } // FF .. FF + {"CPX", AM_M , im}, {"SBC", AM_IZX, R_}, {"nop", AM_M , im}, {"nop", 0 , 0 }, // E0 .. E3 + {"CPX", AM_Z , R_}, {"SBC", AM_Z , R_}, {"INC", AM_Z , RW}, {"nop", 0 , 0 }, // E4 .. E7 + {"INX", 0 , 0}, {"SBC", AM_M , R_}, {"NOP", 0 , 0}, {"nop", 0 , 0 }, // E8 .. EB + {"CPX", AM_A , R_}, {"SBC", AM_A , R_}, {"INC", AM_A , RW}, {"nop", 0 , 0 }, // EC .. EF + {"BEQ", AM_R , 0}, {"SBC", AM_NZY, R_}, {"SBC", AM_NZ , 0}, {"nop", 0 , 0 }, // F0 .. F3 + {"nop", AM_ZX , 0}, {"SBC", AM_ZX , R_}, {"INC", AM_ZX , RW}, {"nop", 0 , 0 }, // F4 .. F7 + {"SED", 0 , 0}, {"SBC", AM_AY , R_}, {"PLX", 0 , 0}, {"nop", 0 , 0 }, // F8 .. FB + {"nop", AM_AX , 0}, {"SBC", AM_AX , R_}, {"INC", AM_AX , RW}, {"nop", 0 , 0 } // FF .. FF }; - -// TODO:FIXME //e uses 65C02, ][ uses 6502 - const Opcodes_t g_aOpcodes6502[ NUM_OPCODES ] = { // Should match Cpu.cpp InternalCpuExecute() switch (*(mem+regs.pc++)) !! /* Based on: http://axis.llx.com/~nparker/a2/opcodes.html - If you really want to know what the undocumented --- (n/a) opcodes do, see: - http://www.strotmann.de/twiki/bin/view/APG/AsmUnusedOpcodes - + If you really want to know what the undocumented --- (n/a) opcodes do, see + CPU.cpp + x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF 0x BRK ORA (d,X) --- --- tsb d ORA d ASL d --- PHP ORA # ASL A --- tsb a ORA a ASL a --- 1x BPL r ORA (d),Y ora (d) --- trb d ORA d,X ASL d,X --- CLC ORA a,Y ina A --- trb a ORA a,X ASL a,X --- @@ -205,77 +202,77 @@ Fx BEQ r SBC (d),Y sbc (d) --- --- SBC d,X INC d,X --- SED SBC a,Y (d),Y */ - {"BRK", 0 , 0}, {"ORA", AM_IZX, R_}, {"NOP", AM_2 , 0 }, {"NOP", AM_1 , 0 }, // 00 .. 03 - {"TSB", AM_Z , _W}, {"ORA", AM_Z , R_}, {"ASL", AM_Z , RW}, {"NOP", AM_1 , 0 }, // 04 .. 07 - {"PHP", 0 , SW}, {"ORA", AM_M , im}, {"ASL", 0 , 0}, {"NOP", AM_1 , 0 }, // 08 .. 0B - {"TSB", AM_A , _W}, {"ORA", AM_A , R_}, {"ASL", AM_A , RW}, {"NOP", AM_3 , 0 }, // 0C .. 0F - {"BPL", AM_R , 0}, {"ORA", AM_NZY, R_}, {"ORA", AM_NZ , R_}, {"NOP", AM_1 , 0 }, // 10 .. 13 - {"TRB", AM_Z , _W}, {"ORA", AM_ZX , R_}, {"ASL", AM_ZX , RW}, {"NOP", AM_1 , 0 }, // 14 .. 17 - {"CLC", 0 , 0}, {"ORA", AM_AY , R_}, {"INA", 0 , 0}, {"NOP", AM_1 , 0 }, // 18 .. 1B - {"TRB", AM_A , _W}, {"ORA", AM_AX , R_}, {"ASL", AM_AX , RW}, {"NOP", AM_1 , 0 }, // 1C .. 1F + {"BRK", 0 , 0}, {"ORA", AM_IZX, R_}, {"hlt", 0 , 0 }, {"aso", AM_IZX, RW}, // 00 .. 03 + {"nop", AM_Z , R_}, {"ORA", AM_Z , R_}, {"ASL", AM_Z , RW}, {"aso", AM_Z , RW}, // 04 .. 07 + {"PHP", 0 , SW}, {"ORA", AM_M , im}, {"ASL", 0 , 0}, {"anc", AM_M , im}, // 08 .. 0B + {"nop", AM_AX , 0}, {"ORA", AM_A , R_}, {"ASL", AM_A , RW}, {"aso", AM_A , RW}, // 0C .. 0F + {"BPL", AM_R , 0}, {"ORA", AM_NZY, R_}, {"hlt", 0 , 0}, {"aso", AM_NZY, RW}, // 10 .. 13 + {"nop", AM_ZX , 0}, {"ORA", AM_ZX , R_}, {"ASL", AM_ZX , RW}, {"aso", AM_ZX , RW}, // 14 .. 17 + {"CLC", 0 , 0}, {"ORA", AM_AY , R_}, {"nop", 0 , 0}, {"aso", AM_AY , RW}, // 18 .. 1B + {"nop", AM_AX , 0}, {"ORA", AM_AX , R_}, {"ASL", AM_AX , RW}, {"aso", AM_AX , RW}, // 1C .. 1F - {"JSR", AM_A , SW}, {"AND", AM_IZX, R_}, {"NOP", AM_2 , 0}, {"NOP", AM_1 , 0 }, // 20 .. 23 - {"BIT", AM_Z , R_}, {"AND", AM_Z , R_}, {"ROL", AM_Z , RW}, {"NOP", AM_1 , 0 }, // 24 .. 27 - {"PLP", 0 , SR}, {"AND", AM_M , im}, {"ROL", 0 , 0}, {"NOP", AM_1 , 0 }, // 28 .. 2B - {"BIT", AM_A , R_}, {"AND", AM_A , R_}, {"ROL", AM_A , RW}, {"NOP", AM_3 , 0 }, // 2C .. 2F - {"BMI", AM_R , 0}, {"AND", AM_NZY, R_}, {"AND", AM_NZ , R_}, {"NOP", AM_1 , 0 }, // 30 .. 33 - {"BIT", AM_ZX , R_}, {"AND", AM_ZX , R_}, {"ROL", AM_ZX , RW}, {"NOP", AM_1 , 0 }, // 34 .. 37 - {"SEC", 0 , 0}, {"AND", AM_AY , R_}, {"DEA", 0 , 0}, {"NOP", AM_1 , 0 }, // 38 .. 3B - {"BIT", AM_AX , R_}, {"AND", AM_AX , R_}, {"ROL", AM_AX , RW}, {"NOP", AM_1 , 0 }, // 3C .. 3F + {"JSR", AM_A , SW}, {"AND", AM_IZX, R_}, {"hlt", 0 , 0}, {"rla", AM_IZX, RW}, // 20 .. 23 + {"BIT", AM_Z , R_}, {"AND", AM_Z , R_}, {"ROL", AM_Z , RW}, {"rla", AM_Z , RW}, // 24 .. 27 + {"PLP", 0 , SR}, {"AND", AM_M , im}, {"ROL", 0 , 0}, {"anc", AM_M , im}, // 28 .. 2B + {"BIT", AM_A , R_}, {"AND", AM_A , R_}, {"ROL", AM_A , RW}, {"rla", AM_A , RW}, // 2C .. 2F + {"BMI", AM_R , 0}, {"AND", AM_NZY, R_}, {"hlt", 0 , 0}, {"rla", AM_NZY, RW}, // 30 .. 33 + {"nop", AM_ZX , 0}, {"AND", AM_ZX , R_}, {"ROL", AM_ZX , RW}, {"rla", AM_ZX , RW}, // 34 .. 37 + {"SEC", 0 , 0}, {"AND", AM_AY , R_}, {"nop", 0 , 0}, {"rla", AM_AY , RW}, // 38 .. 3B + {"nop", AM_AX , 0}, {"AND", AM_AX , R_}, {"ROL", AM_AX , RW}, {"rla", AM_AX , RW}, // 3C .. 3F - {"RTI", 0 , 0}, {"EOR", AM_IZX, R_}, {"NOP", AM_2 , 0}, {"NOP", AM_1 , 0 }, // 40 .. 43 - {"NOP", AM_2 , 0}, {"EOR", AM_Z , R_}, {"LSR", AM_Z , _W}, {"NOP", AM_1 , 0 }, // 44 .. 47 - {"PHA", 0 , SW}, {"EOR", AM_M , im}, {"LSR", 0 , 0}, {"NOP", AM_1 , 0 }, // 48 .. 4B - {"JMP", AM_A , 0}, {"EOR", AM_A , R_}, {"LSR", AM_A , _W}, {"NOP", AM_1 , 0 }, // 4C .. 4F - {"BVC", AM_R , 0}, {"EOR", AM_NZY, R_}, {"EOR", AM_NZ , R_}, {"NOP", AM_1 , 0 }, // 50 .. 53 - {"NOP", AM_2 , 0}, {"EOR", AM_ZX , R_}, {"LSR", AM_ZX , _W}, {"NOP", AM_1 , 0 }, // 54 .. 57 - {"CLI", 0 , 0}, {"EOR", AM_AY , R_}, {"PHY", 0 , SW}, {"NOP", AM_1 , 0 }, // 58 .. 5B - {"NOP", AM_3 , 0}, {"EOR", AM_AX , R_}, {"LSR", AM_AX , RW}, {"NOP", AM_1 , 0 }, // 5C .. 5F + {"RTI", 0 , 0}, {"EOR", AM_IZX, R_}, {"hlt", 0 , 0}, {"lse", AM_IZX, RW}, // 40 .. 43 + {"nop", AM_Z , 0}, {"EOR", AM_Z , R_}, {"LSR", AM_Z , RW}, {"lse", AM_Z , RW}, // 44 .. 47 + {"PHA", 0 , SW}, {"EOR", AM_M , im}, {"LSR", 0 , 0}, {"alr", AM_M , im}, // 48 .. 4B + {"JMP", AM_A , 0}, {"EOR", AM_A , R_}, {"LSR", AM_A , RW}, {"lse", AM_A , RW}, // 4C .. 4F + {"BVC", AM_R , 0}, {"EOR", AM_NZY, R_}, {"hlt", 0 , 0}, {"lse", AM_NZY, RW}, // 50 .. 53 + {"nop", AM_ZX , 0}, {"EOR", AM_ZX , R_}, {"LSR", AM_ZX , RW}, {"lse", AM_ZX , RW}, // 54 .. 57 + {"CLI", 0 , 0}, {"EOR", AM_AY , R_}, {"nop", 0 , 0}, {"lse", AM_AY , RW}, // 58 .. 5B + {"nop", AM_AX , 0}, {"EOR", AM_AX , R_}, {"LSR", AM_AX , RW}, {"lse", AM_AX , RW}, // 5C .. 5F - {"RTS", 0 , SR}, {"ADC", AM_IZX, R_}, {"NOP", AM_2 , 0}, {"NOP", AM_1 , 0 }, // 60 .. 63 - {"STZ", AM_Z , _W}, {"ADC", AM_Z , R_}, {"ROR", AM_Z , RW}, {"NOP", AM_1 , 0 }, // 64 .. 67 - {"PLA", 0 , SR}, {"ADC", AM_M , im}, {"ROR", 0 , 0}, {"NOP", AM_1 , 0 }, // 68 .. 6B - {"JMP", AM_NA , 0}, {"ADC", AM_A , R_}, {"ROR", AM_A , RW}, {"NOP", AM_1 , 0 }, // 6C .. 6F - {"BVS", AM_R , 0}, {"ADC", AM_NZY, R_}, {"ADC", AM_NZ , R_}, {"NOP", AM_1 , 0 }, // 70 .. 73 - {"STZ", AM_ZX , _W}, {"ADC", AM_ZX , R_}, {"ROR", AM_ZX , RW}, {"NOP", AM_1 , 0 }, // 74 .. 77 - {"SEI", 0 , 0}, {"ADC", AM_AY , R_}, {"PLY", 0 , SR}, {"NOP", AM_1 , 0 }, // 78 .. 7B - {"JMP", AM_IAX, 0}, {"ADC", AM_AX , R_}, {"ROR", AM_AX , RW}, {"NOP", AM_1 , 0 }, // 7C .. 7F + {"RTS", 0 , SR}, {"ADC", AM_IZX, R_}, {"hlt", 0 , 0}, {"rra", AM_IZX, RW}, // 60 .. 63 + {"nop", AM_Z , 0}, {"ADC", AM_Z , R_}, {"ROR", AM_Z , RW}, {"rra", AM_Z , RW}, // 64 .. 67 + {"PLA", 0 , SR}, {"ADC", AM_M , im}, {"ROR", 0 , 0}, {"arr", AM_M , im}, // 68 .. 6B + {"JMP", AM_NA , 0}, {"ADC", AM_A , R_}, {"ROR", AM_A , RW}, {"rra", AM_A , RW}, // 6C .. 6F + {"BVS", AM_R , 0}, {"ADC", AM_NZY, R_}, {"hlt", 0 , 0}, {"rra", AM_NZY, RW}, // 70 .. 73 + {"nop", AM_ZX , 0}, {"ADC", AM_ZX , R_}, {"ROR", AM_ZX , RW}, {"rra", AM_ZX , RW}, // 74 .. 77 + {"SEI", 0 , 0}, {"ADC", AM_AY , R_}, {"nop", 0 , 0}, {"rra", AM_AY , RW}, // 78 .. 7B + {"nop", AM_AX , 0}, {"ADC", AM_AX , R_}, {"ROR", AM_AX , RW}, {"rra", AM_AX , RW}, // 7C .. 7F - {"BRA", AM_R , 0}, {"STA", AM_IZX, _W}, {"NOP", AM_2 , 0}, {"NOP", AM_1 , 0 }, // 80 .. 83 - {"STY", AM_Z , _W}, {"STA", AM_Z , _W}, {"STX", AM_Z , _W}, {"NOP", AM_1 , 0 }, // 84 .. 87 - {"DEY", 0 , 0}, {"BIT", AM_M , im}, {"TXA", 0 , 0}, {"NOP", AM_1 , 0 }, // 88 .. 8B - {"STY", AM_A , _W}, {"STA", AM_A , _W}, {"STX", AM_A , _W}, {"NOP", AM_1 , 0 }, // 8C .. 8F - {"BCC", AM_R , 0}, {"STA", AM_NZY, _W}, {"STA", AM_NZ , _W}, {"NOP", AM_1 , 0 }, // 90 .. 93 - {"STY", AM_ZX , _W}, {"STA", AM_ZX , _W}, {"STX", AM_ZY , _W}, {"NOP", AM_1 , 0 }, // 94 .. 97 - {"TYA", 0 , 0}, {"STA", AM_AY , _W}, {"TXS", 0 , 0}, {"NOP", AM_1 , 0 }, // 98 .. 9B - {"STZ", AM_A , _W}, {"STA", AM_AX , _W}, {"STZ", AM_AX , _W}, {"NOP", AM_1 , 0 }, // 9C .. 9F + {"nop", AM_M , im}, {"STA", AM_IZX, _W}, {"nop", AM_M , im}, {"axs", AM_IZX, _W}, // 80 .. 83 + {"STY", AM_Z , _W}, {"STA", AM_Z , _W}, {"STX", AM_Z , _W}, {"axs", AM_Z , _W}, // 84 .. 87 + {"DEY", 0 , 0}, {"nop", AM_M , im}, {"TXA", 0 , 0}, {"xaa", AM_M , im}, // 88 .. 8B + {"STY", AM_A , _W}, {"STA", AM_A , _W}, {"STX", AM_A , _W}, {"axs", AM_A , _W}, // 8C .. 8F + {"BCC", AM_R , 0}, {"STA", AM_NZY, _W}, {"hlt", 0 , 0}, {"axa", AM_NZY, _W}, // 90 .. 93 + {"STY", AM_ZX , _W}, {"STA", AM_ZX , _W}, {"STX", AM_ZY , _W}, {"axs", AM_ZY , _W}, // 94 .. 97 + {"TYA", 0 , 0}, {"STA", AM_AY , _W}, {"TXS", 0 , 0}, {"tas", AM_AY , _W}, // 98 .. 9B + {"say", AM_AX , _W}, {"STA", AM_AX , _W}, {"xas", AM_AX , _W}, {"axa", AM_AY , _W}, // 9C .. 9F - {"LDY", AM_M , im}, {"LDA", AM_IZX, R_}, {"LDX", AM_M , im}, {"NOP", AM_1 , 0 }, // A0 .. A3 - {"LDY", AM_Z , R_}, {"LDA", AM_Z , R_}, {"LDX", AM_Z , R_}, {"NOP", AM_1 , 0 }, // A4 .. A7 - {"TAY", 0 , 0}, {"LDA", AM_M , im}, {"TAX", 0 , 0 }, {"NOP", AM_1 , 0 }, // A8 .. AB - {"LDY", AM_A , R_}, {"LDA", AM_A , R_}, {"LDX", AM_A , R_}, {"NOP", AM_1 , 0 }, // AC .. AF - {"BCS", AM_R , 0}, {"LDA", AM_NZY, R_}, {"LDA", AM_NZ , R_}, {"NOP", AM_1 , 0 }, // B0 .. B3 - {"LDY", AM_ZX , R_}, {"LDA", AM_ZX , R_}, {"LDX", AM_ZY , R_}, {"NOP", AM_1 , 0 }, // B4 .. B7 - {"CLV", 0 , 0}, {"LDA", AM_AY , R_}, {"TSX", 0 , 0 }, {"NOP", AM_1 , 0 }, // B8 .. BB - {"LDY", AM_AX , R_}, {"LDA", AM_AX , R_}, {"LDX", AM_AY , R_}, {"NOP", AM_1 , 0 }, // BC .. BF + {"LDY", AM_M , im}, {"LDA", AM_IZX, R_}, {"LDX", AM_M , im}, {"lax", AM_IZX, R_}, // A0 .. A3 + {"LDY", AM_Z , R_}, {"LDA", AM_Z , R_}, {"LDX", AM_Z , R_}, {"lax", AM_Z , R_}, // A4 .. A7 + {"TAY", 0 , 0}, {"LDA", AM_M , im}, {"TAX", 0 , 0 }, {"oal", AM_M , im}, // A8 .. AB + {"LDY", AM_A , R_}, {"LDA", AM_A , R_}, {"LDX", AM_A , R_}, {"lax", AM_A , R_}, // AC .. AF + {"BCS", AM_R , 0}, {"LDA", AM_NZY, R_}, {"hlt", 0 , 0 }, {"lax", AM_NZY, R_}, // B0 .. B3 + {"LDY", AM_ZX , R_}, {"LDA", AM_ZX , R_}, {"LDX", AM_ZY , R_}, {"lax", AM_ZY , 0 }, // B4 .. B7 + {"CLV", 0 , 0}, {"LDA", AM_AY , R_}, {"TSX", 0 , 0 }, {"las", AM_AY , R_}, // B8 .. BB + {"LDY", AM_AX , R_}, {"LDA", AM_AX , R_}, {"LDX", AM_AY , R_}, {"lax", AM_AY , R_}, // BC .. BF - {"CPY", AM_M , im}, {"CMP", AM_IZX, R_}, {"NOP", AM_2 , 0}, {"NOP", AM_1 , 0 }, // C0 .. C3 - {"CPY", AM_Z , R_}, {"CMP", AM_Z , R_}, {"DEC", AM_Z , RW}, {"NOP", AM_1 , 0 }, // C4 .. C7 - {"INY", 0 , 0}, {"CMP", AM_M , im}, {"DEX", 0 , 0}, {"NOP", AM_1 , 0 }, // C8 .. CB - {"CPY", AM_A , R_}, {"CMP", AM_A , R_}, {"DEC", AM_A , RW}, {"NOP", AM_1 , 0 }, // CC .. CF - {"BNE", AM_R , 0}, {"CMP", AM_NZY, R_}, {"CMP", AM_NZ , 0}, {"NOP", AM_1 , 0 }, // D0 .. D3 - {"NOP", AM_2 , 0}, {"CMP", AM_ZX , R_}, {"DEC", AM_ZX , RW}, {"NOP", AM_1 , 0 }, // D4 .. D7 - {"CLD", 0 , 0}, {"CMP", AM_AY , R_}, {"PHX", 0 , 0}, {"NOP", AM_1 , 0 }, // D8 .. DB - {"NOP", AM_3 , 0}, {"CMP", AM_AX , R_}, {"DEC", AM_AX , RW}, {"NOP", AM_1 , 0 }, // DC .. DF + {"CPY", AM_M , im}, {"CMP", AM_IZX, R_}, {"nop", AM_M , im}, {"dcm", AM_IZX, RW}, // C0 .. C3 + {"CPY", AM_Z , R_}, {"CMP", AM_Z , R_}, {"DEC", AM_Z , RW}, {"dcm", AM_Z , RW}, // C4 .. C7 + {"INY", 0 , 0}, {"CMP", AM_M , im}, {"DEX", 0 , 0}, {"sax", AM_M , im}, // C8 .. CB + {"CPY", AM_A , R_}, {"CMP", AM_A , R_}, {"DEC", AM_A , RW}, {"dcm", AM_A , RW}, // CC .. CF + {"BNE", AM_R , 0}, {"CMP", AM_NZY, R_}, {"hlt", 0 , 0}, {"dcm", AM_NZY, RW}, // D0 .. D3 + {"nop", AM_ZX , 0}, {"CMP", AM_ZX , R_}, {"DEC", AM_ZX , RW}, {"dcm", AM_ZX , RW}, // D4 .. D7 + {"CLD", 0 , 0}, {"CMP", AM_AY , R_}, {"nop", 0 , 0}, {"dcm", AM_AY , RW}, // D8 .. DB + {"nop", AM_AX , 0}, {"CMP", AM_AX , R_}, {"DEC", AM_AX , RW}, {"dcm", AM_AX , RW}, // DC .. DF - {"CPX", AM_M , im}, {"SBC", AM_IZX, R_}, {"NOP", AM_2 , 0}, {"NOP", AM_1 , 0 }, // E0 .. E3 - {"CPX", AM_Z , R_}, {"SBC", AM_Z , R_}, {"INC", AM_Z , RW}, {"NOP", AM_1 , 0 }, // E4 .. E7 - {"INX", 0 , 0}, {"SBC", AM_M , R_}, {"NOP", 0 , 0}, {"NOP", AM_1 , 0 }, // E8 .. EB - {"CPX", AM_A , R_}, {"SBC", AM_A , R_}, {"INC", AM_A , RW}, {"NOP", AM_1 , 0 }, // EC .. EF - {"BEQ", AM_R , 0}, {"SBC", AM_NZY, R_}, {"SBC", AM_NZ , 0}, {"NOP", AM_1 , 0 }, // F0 .. F3 - {"NOP", AM_2 , 0}, {"SBC", AM_ZX , R_}, {"INC", AM_ZX , RW}, {"???", AM_ZX , 0 }, // F4 .. F7 - {"SED", 0 , 0}, {"SBC", AM_AY , R_}, {"PLX", 0 , 0}, {"NOP", AM_1 , 0 }, // F8 .. FB - {"NOP", AM_3 , 0}, {"SBC", AM_AX , R_}, {"INC", AM_AX , RW}, {"NOP", AM_1 , 0 } // FF .. FF + {"CPX", AM_M , im}, {"SBC", AM_IZX, R_}, {"nop", AM_M , im}, {"ins", AM_IZX, RW}, // E0 .. E3 + {"CPX", AM_Z , R_}, {"SBC", AM_Z , R_}, {"INC", AM_Z , RW}, {"ins", AM_Z , RW}, // E4 .. E7 + {"INX", 0 , 0}, {"SBC", AM_M , im}, {"NOP", 0 , 0}, {"sbc", AM_M , im}, // E8 .. EB + {"CPX", AM_A , R_}, {"SBC", AM_A , R_}, {"INC", AM_A , RW}, {"ins", AM_A , RW}, // EC .. EF + {"BEQ", AM_R , 0}, {"SBC", AM_NZY, R_}, {"hlt", 0 , 0}, {"ins", AM_NZY, RW}, // F0 .. F3 + {"nop", AM_ZX , 0}, {"SBC", AM_ZX , R_}, {"INC", AM_ZX , RW}, {"ins", AM_ZX , RW}, // F4 .. F7 + {"SED", 0 , 0}, {"SBC", AM_AY , R_}, {"nop", 0 , 0}, {"ins", AM_AY , RW}, // F8 .. FB + {"nop", AM_AX , 0}, {"SBC", AM_AX , R_}, {"INC", AM_AX , RW}, {"ins", AM_AX , RW} // FF .. FF }; #undef R_ diff --git a/AppleWin/source/Debugger_Help.cpp b/AppleWin/source/Debugger_Help.cpp index 57970754..c262bc6b 100644 --- a/AppleWin/source/Debugger_Help.cpp +++ b/AppleWin/source/Debugger_Help.cpp @@ -132,7 +132,7 @@ Update_t CmdMOTD( int nArgs ) { TCHAR sText[ CONSOLE_WIDTH ]; - ConsoleBufferPush( TEXT(" Apple ][+ //e Emulator for Windows") ); + ConsoleBufferPush( TEXT(" Apple ][ ][+ //e Emulator for Windows") ); CmdVersion(0); CmdSymbols(0); wsprintf( sText, " '~' console, '%s' (specific), '%s' (all)" diff --git a/AppleWin/source/Frame.cpp b/AppleWin/source/Frame.cpp index 6634749f..1003d9b5 100644 --- a/AppleWin/source/Frame.cpp +++ b/AppleWin/source/Frame.cpp @@ -384,7 +384,8 @@ void DrawStatusArea (HDC passdc, int drawflags) { } if (drawflags & DRAW_TITLE) { TCHAR title[40]; - _tcscpy(title,apple2e ? TITLE : TEXT("Apple ][+ Emulator")); + _tcscpy(title,apple2e ? TITLE : (apple2plus ? TEXT("Apple ][+ Emulator") + : TEXT("Apple ][ Emulator"))); switch (mode) { case MODE_PAUSED: _tcscat(title,TEXT(" [Paused]")); break; case MODE_STEPPING: _tcscat(title,TEXT(" [Stepping]")); break; @@ -1116,12 +1117,14 @@ void FrameCreateWindow () { int ypos; if (!RegLoadValue(TEXT("Preferences"),TEXT("Window Y-Position"),1,(DWORD *)&ypos)) ypos = (GetSystemMetrics(SM_CYSCREEN)-height) >> 1; - g_hFrameWindow = CreateWindow(TEXT("APPLE2FRAME"),apple2e ? TITLE - : TEXT("Apple ][+ Emulator"), - WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | - WS_VISIBLE, - xpos,ypos,width,height, - HWND_DESKTOP,(HMENU)0,instance,NULL); + g_hFrameWindow = CreateWindow(TEXT("APPLE2FRAME"), + apple2e ? TITLE + : (apple2plus ? TEXT("Apple ][+ Emulator") + : TEXT("Apple ][ Emulator")), + WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | + WS_MINIMIZEBOX | WS_VISIBLE, + xpos,ypos,width,height, + HWND_DESKTOP,(HMENU)0,instance,NULL); InitCommonControls(); tooltipwindow = CreateWindow(TOOLTIPS_CLASS,NULL,TTS_ALWAYSTIP, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, diff --git a/AppleWin/source/Keyboard.cpp b/AppleWin/source/Keyboard.cpp index bfc5716c..7c54669d 100644 --- a/AppleWin/source/Keyboard.cpp +++ b/AppleWin/source/Keyboard.cpp @@ -32,13 +32,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA static bool g_bKeybBufferEnable = false; #define KEY_OLD -#define OLIVER_SCHMIDT_FIX2 // PC's delete key maps to Apple's DEL key -#ifdef OLIVER_SCHMIDT_FIX2 -static BYTE asciicode[10] = {0x08,0x0B,0x15,0x0A,0x00,0x00,0x00,0x00,0x00,0x7F}; // Convert PC arrow keys to Apple keycodes -#else -static BYTE asciicode[4] = {0x08,0x0B,0x15,0x0A}; // Convert PC arrow keys to Apple keycodes -#endif +static BYTE asciicode[2][10] = {{0x08,0x0D,0x15,0x2F,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x08,0x0B,0x15,0x0A,0x00,0x00,0x00,0x00,0x00,0x7F}}; // Convert PC arrow keys to Apple keycodes static bool gbShiftKey = false; // +PATCH MJP static bool gbCtrlKey = false; // +PATCH MJP @@ -148,21 +144,34 @@ DWORD KeybGetNumQueries () // Used in determining 'idleness' of Apple system //=========================================================================== void KeybQueueKeypress (int key, BOOL bASCII) { + static bool bFreshReset; + if (bASCII == ASCII) - { + { + if (bFreshReset && key == 0x03) { + bFreshReset = 0; + return; // Swallow spurious CTRL-C caused by CTRL-BREAK + } + bFreshReset = 0; if (key > 0x7F) return; - if ((key >= 'a') && (key <= 'z') && (capslock || !apple2e)) - keycode = key - ('a'-'A'); + if (apple2e) + if (capslock && (key >= 'a') && (key <='z')) + keycode = key - 32; + else + keycode = key; else - keycode = key; + if (key >= '`') + keycode = key - 32; + else + keycode = key; lastvirtkey = LOBYTE(VkKeyScan(key)); } else { - if ((key == VK_CANCEL) && ((!apple2e) || (GetKeyState(VK_CONTROL) < 0)) ) + if ((key == VK_CANCEL) && (GetKeyState(VK_CONTROL) < 0)) { // Ctrl+Reset if (apple2e) @@ -170,14 +179,16 @@ void KeybQueueKeypress (int key, BOOL bASCII) DiskReset(); KeybReset(); - VideoResetState(); // Switch Alternate char set off + if (apple2e) + VideoResetState(); // Switch Alternate char set off MB_Reset(); #ifndef KEY_OLD g_nNextInIdx = g_nNextOutIdx = g_nKeyBufferCnt = 0; #endif - CpuInitialize(); + CpuReset(); + bFreshReset = 1; return; } @@ -188,19 +199,11 @@ void KeybQueueKeypress (int key, BOOL bASCII) return; } -#ifdef OLIVER_SCHMIDT_FIX2 - if (!((key >= VK_LEFT) && (key <= VK_DELETE) && asciicode[key - VK_LEFT])) + if (!((key >= VK_LEFT) && (key <= VK_DELETE) && asciicode[apple2e][key - VK_LEFT])) return; - keycode = asciicode[key - VK_LEFT]; // Convert to Apple arrow keycode + keycode = asciicode[apple2e][key - VK_LEFT]; // Convert to Apple arrow keycode lastvirtkey = key; -#else - if (!((key >= VK_LEFT) && (key <= VK_DOWN))) - return; - - keycode = asciicode[key - VK_LEFT]; // Convert to Apple arrow keycode - lastvirtkey = key; -#endif } #ifdef KEY_OLD keywaiting = 1; diff --git a/AppleWin/source/Memory.cpp b/AppleWin/source/Memory.cpp index 0f1d3c8c..b8da5609 100644 --- a/AppleWin/source/Memory.cpp +++ b/AppleWin/source/Memory.cpp @@ -898,11 +898,14 @@ void MemInitialize () { const UINT ROM_SIZE = 0x5000; // HACK: Magic # HRSRC hResInfo = apple2e ? FindResource(NULL, MAKEINTRESOURCE(IDR_APPLE2E_ROM), "ROM") - : FindResource(NULL, MAKEINTRESOURCE(IDR_APPLE2_ROM), "ROM"); + : (apple2plus ? FindResource(NULL, MAKEINTRESOURCE(IDR_APPLE2PLUS_ROM), "ROM") + : FindResource(NULL, MAKEINTRESOURCE(IDR_APPLE2ORIG_ROM), "ROM")); if(hResInfo == NULL) { TCHAR sRomFileName[ 128 ]; - _tcscpy( sRomFileName, apple2e ? TEXT("APPLE2E.ROM") : TEXT("APPLE2.ROM") ); + _tcscpy( sRomFileName, apple2e ? TEXT("APPLE2E.ROM") + : (apple2plus ? TEXT("APPLE2PLUS.ROM") + : TEXT("APPLE2ORIG.ROM"))); TCHAR sText[ 256 ]; wsprintf( sText, TEXT("Unable to open the required firmware ROM data file.\n\nFile: %s."), sRomFileName ); @@ -982,8 +985,7 @@ void MemReset () // INITIALIZE PAGING, FILLING IN THE 64K MEMORY IMAGE ResetPaging(1); - regs.pc = *(LPWORD)(mem+0xFFFC); - CpuIrqReset(); + regs.bRESET = 1; } //=========================================================================== diff --git a/AppleWin/source/Mockingboard.cpp b/AppleWin/source/Mockingboard.cpp index 819a00fe..6911454c 100644 --- a/AppleWin/source/Mockingboard.cpp +++ b/AppleWin/source/Mockingboard.cpp @@ -304,9 +304,15 @@ static void UpdateIFR(SY6522_AY8910* pMB) bIRQ |= g_MB[i].sy6522.IFR & 0x80; if (bIRQ) - CpuIrqAssert(IS_6522); + if (pMB->nAY8910Number & 1) + CpuNmiAssert(IS_6522); + else + CpuIrqAssert(IS_6522); else - CpuIrqDeassert(IS_6522); + if (pMB->nAY8910Number & 1) + CpuNmiDeassert(IS_6522); + else + CpuIrqDeassert(IS_6522); } static void SY6522_Write(BYTE nDevice, BYTE nReg, BYTE nValue) @@ -568,6 +574,9 @@ static void SSI263_Write(BYTE nDevice, BYTE nReg, BYTE nValue) // Datasheet is not clear, but a write to DURPHON must clear the IRQ if(g_bPhasorEnable) + if (pMB->nAY8910Number & 1) + CpuNmiDeassert(IS_SPEECH); + else CpuIrqDeassert(IS_SPEECH); pMB->sy6522.IFR &= ~IxR_PERIPHERAL; UpdateIFR(pMB); @@ -895,7 +904,10 @@ static DWORD WINAPI SSI263Thread(LPVOID lpParameter) pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin // Is Phasor's SSI263.IRQ wired directly to IRQ? (Bypassing the 6522) - CpuIrqAssert(IS_SPEECH); + if (pMB->nAY8910Number & 1) + CpuNmiAssert(IS_SPEECH); + else + CpuIrqAssert(IS_SPEECH); } } else diff --git a/AppleWin/source/PropertySheetPage.cpp b/AppleWin/source/PropertySheetPage.cpp index ad158fe3..7c04943c 100644 --- a/AppleWin/source/PropertySheetPage.cpp +++ b/AppleWin/source/PropertySheetPage.cpp @@ -35,7 +35,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "Tfe\Uilib.h" -TCHAR computerchoices[] = TEXT("Apple ][+\0") +TCHAR computerchoices[] = TEXT("Apple ][ (Original Model)\0") + TEXT("Apple ][+\0") TEXT("Apple //e\0"); TCHAR* szJoyChoice0 = TEXT("Disabled\0"); @@ -206,7 +207,7 @@ static void ConfigDlg_OK(HWND window, BOOL afterclose) DWORD newvidtype = (DWORD)SendDlgItemMessage(window,IDC_VIDEOTYPE,CB_GETCURSEL,0,0); DWORD newserialport = (DWORD)SendDlgItemMessage(window,IDC_SERIALPORT,CB_GETCURSEL,0,0); - if (newcomptype != apple2e) + if (newcomptype != (apple2e ? 2 : (apple2plus ? 1 : 0))) { if (MessageBox(window, TEXT("You have changed the emulated computer ") @@ -340,7 +341,7 @@ static BOOL CALLBACK ConfigDlgProc (HWND window, { g_nLastPage = PG_CONFIG; - FillComboBox(window,IDC_COMPUTER,computerchoices,apple2e); + FillComboBox(window,IDC_COMPUTER,computerchoices,apple2e ? 2 : (apple2plus ? 1 : 0)); FillComboBox(window,IDC_VIDEOTYPE,videochoices,videotype); FillComboBox(window,IDC_SERIALPORT,serialchoices,serialport); SendDlgItemMessage(window,IDC_SLIDER_CPU_SPEED,TBM_SETRANGE,1,MAKELONG(0,40)); diff --git a/AppleWin/source/Video.cpp b/AppleWin/source/Video.cpp index eb698c33..13fb4028 100644 --- a/AppleWin/source/Video.cpp +++ b/AppleWin/source/Video.cpp @@ -120,7 +120,8 @@ enum Color_Palette_Index_e #define SRCOFFS_40COL 0 -#define SRCOFFS_80COL (SRCOFFS_40COL + 256) +#define SRCOFFS_IIPLUS (SRCOFFS_40COL + 256) +#define SRCOFFS_80COL (SRCOFFS_IIPLUS + 256) #define SRCOFFS_LORES (SRCOFFS_80COL + 128) #define SRCOFFS_HIRES (SRCOFFS_LORES + 16) #define SRCOFFS_DHIRES (SRCOFFS_HIRES + 512) @@ -906,10 +907,18 @@ void DrawMonoLoResSource () { void DrawMonoTextSource (HDC dc) { HDC memdc = CreateCompatibleDC(dc); HBITMAP bitmap = LoadBitmap(instance,TEXT("CHARSET40")); - HBRUSH brush = CreateSolidBrush(monochrome); + HBRUSH brush; + switch (videotype) + { + case VT_MONO_AMBER: brush = CreateSolidBrush(RGB(0xFF,0x80,0x00)); break; + case VT_MONO_GREEN: brush = CreateSolidBrush(RGB(0x00,0xC0,0x00)); break; + case VT_MONO_WHITE: brush = CreateSolidBrush(RGB(0xFF,0xFF,0xFF)); break; + default : brush = CreateSolidBrush(monochrome); break; + } SelectObject(memdc,bitmap); SelectObject(dc,brush); BitBlt(dc,SRCOFFS_40COL,0,256,512,memdc,0,0,MERGECOPY); + BitBlt(dc,SRCOFFS_IIPLUS,0,256,256,memdc,0,512,MERGECOPY); StretchBlt(dc,SRCOFFS_80COL,0,128,512,memdc,0,0,256,512,MERGECOPY); SelectObject(dc,GetStockObject(NULL_BRUSH)); DeleteObject(brush); @@ -923,6 +932,7 @@ void DrawTextSource (HDC dc) { HBITMAP bitmap = LoadBitmap(instance,TEXT("CHARSET40")); SelectObject(memdc,bitmap); BitBlt(dc,SRCOFFS_40COL,0,256,512,memdc,0,0,SRCCOPY); + BitBlt(dc,SRCOFFS_IIPLUS,0,256,256,memdc,0,512,SRCCOPY); StretchBlt(dc,SRCOFFS_80COL,0,128,512,memdc,0,0,256,512,SRCCOPY); DeleteDC(memdc); DeleteObject(bitmap); @@ -958,15 +968,10 @@ BOOL Update40ColCell (int x, int y, int xpixel, int ypixel, int offset) { bool bInvert = bCharFlashing ? g_bTextFlashState : false; - // Apple ][ inits memory to FF,FF,00,00 - // The 7F char is same as (inverse) space - if ((! apple2e) && (ch == 0xFF)) - ch = 32; - CopySource(xpixel,ypixel, - 14,16, - SRCOFFS_40COL+((ch & 0x0F) << 4), - (ch & 0xF0)+charoffs + (bInvert?0x40:0x00)); + 14,16, + (apple2e?SRCOFFS_40COL:SRCOFFS_IIPLUS)+((ch & 0x0F) << 4), + (ch & 0xF0)+charoffs + (bInvert?0x40:0x00)); return 1; } @@ -1931,10 +1936,10 @@ BYTE __stdcall VideoSetMode (WORD, BYTE address, BYTE write, BYTE, ULONG) { switch (address) { case 0x00: vidmode &= ~VF_MASK2; break; case 0x01: vidmode |= VF_MASK2; break; - case 0x0C: vidmode &= ~VF_80COL; break; - case 0x0D: vidmode |= VF_80COL; break; - case 0x0E: charoffs = 0; break; // Alternate char set off - case 0x0F: charoffs = 256; break; // Alternate char set on + case 0x0C: if (apple2e) vidmode &= ~VF_80COL; break; + case 0x0D: if (apple2e) vidmode |= VF_80COL; break; + case 0x0E: if (apple2e) charoffs = 0; break; // Alternate char set off + case 0x0F: if (apple2e) charoffs = 256; break; // Alternate char set on case 0x50: vidmode &= ~VF_TEXT; break; case 0x51: vidmode |= VF_TEXT; break; case 0x52: vidmode &= ~VF_MIXED; break; @@ -1943,8 +1948,8 @@ BYTE __stdcall VideoSetMode (WORD, BYTE address, BYTE write, BYTE, ULONG) { case 0x55: vidmode |= VF_PAGE2; break; case 0x56: vidmode &= ~VF_HIRES; break; case 0x57: vidmode |= VF_HIRES; break; - case 0x5E: vidmode |= VF_DHIRES; break; - case 0x5F: vidmode &= ~VF_DHIRES; break; + case 0x5E: if (apple2e) vidmode |= VF_DHIRES; break; + case 0x5F: if (apple2e) vidmode &= ~VF_DHIRES; break; } if (SW_MASK2) vidmode &= ~VF_PAGE2; @@ -2000,7 +2005,7 @@ void VideoUpdateFlash() nTextFlashCnt++; - if(nTextFlashCnt == 60/4) // Flash rate = 4Hz (every 250ms) + if(nTextFlashCnt == 60/6) // Flash rate = 6Hz (every 166ms) { nTextFlashCnt = 0; g_bTextFlashState = !g_bTextFlashState;