From b4e8ef6c5282d8763d7559370c007fa4c1219a54 Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Tue, 29 May 2007 03:43:29 +0000 Subject: [PATCH] Finalizing move to trunk... --- Makefile | 8 +- src/dis6808.cpp | 27 +- src/dis6809.cpp | 40 +- src/sound.cpp | 3 +- src/stargem2.cpp | 166 ++- src/v6808.cpp | 2660 +++++++++++++++++++++++++--------------------- src/v6808.h | 13 +- src/v6809.cpp | 587 ++++++---- src/v6809.h | 8 +- src/video.cpp | 5 +- stargem2.cfg | 2 +- 11 files changed, 1998 insertions(+), 1521 deletions(-) diff --git a/Makefile b/Makefile index 40b8c56..c8e4886 100755 --- a/Makefile +++ b/Makefile @@ -44,9 +44,9 @@ TARGET = stargem2 CFLAGS = -MMD -Wall -Wno-switch -Wno-uninitialized -O2 -D$(SYSTYPE) -fomit-frame-pointer `sdl-config --cflags` CPPFLAGS = -MMD -Wall -Wno-switch -Wno-non-virtual-dtor -Wno-uninitialized -O2 -D$(SYSTYPE) \ - -fomit-frame-pointer `sdl-config --cflags` -# -fomit-frame-pointer `sdl-config --cflags` -g -# -fomit-frame-pointer `sdl-config --cflags` -DLOG_UNMAPPED_MEMORY_ACCESSES + -fomit-frame-pointer `sdl-config --cflags` \ + -g +# -DLOG_UNMAPPED_MEMORY_ACCESSES LDFLAGS = @@ -54,8 +54,6 @@ LIBS = -L/usr/local/lib `sdl-config $(SDLLIBTYPE)` -lstdc++ -lz $(GLLIB) INCS = -I. -Isrc -I/usr/local/include -#THECC = $(CC) $(CFLAGS) $(INCS) - OBJS = \ obj/dis6808.o \ obj/dis6809.o \ diff --git a/src/dis6808.cpp b/src/dis6808.cpp index 98b1bf4..17cd301 100755 --- a/src/dis6808.cpp +++ b/src/dis6808.cpp @@ -103,34 +103,43 @@ int Decode6808(uint16 pc) { char outbuf[80]; - uint16 addr = pc; + uint16 addr = pc, offset; uint8 opcode = soundCPU.RdMem(addr++); // Get the opcode switch (op_mat[opcode]) // Decode the addressing mode... { case 0: // Illegal - sprintf(outbuf, "???"); + sprintf(outbuf, "??? "); break; case 1: // Zero page - sprintf(outbuf, "%s $%02X", mnemonics[opcode], soundCPU.RdMem(addr++)); + sprintf(outbuf, "%s $%02X ", mnemonics[opcode], soundCPU.RdMem(addr++)); break; case 2: // Absolute - sprintf(outbuf, "%s $%04X", mnemonics[opcode], (soundCPU.RdMem(addr++) << 8) | soundCPU.RdMem(addr++)); +// sprintf(outbuf, "%s $%04X", mnemonics[opcode], (soundCPU.RdMem(addr++) << 8) | soundCPU.RdMem(addr++)); + offset = (soundCPU.RdMem(addr + 0) << 8) | soundCPU.RdMem(addr + 1); + addr += 2; + sprintf(outbuf, "%s $%04X ", mnemonics[opcode], offset); break; case 3: // Relative - sprintf(outbuf, "%s $%04X", mnemonics[opcode], ++addr + (int16)(int8)soundCPU.RdMem(addr)); +// sprintf(outbuf, "%s $%04X", mnemonics[opcode], ++addr + (int16)(int8)soundCPU.RdMem(addr)); + offset = addr + 1 + (int16)(int8)soundCPU.RdMem(addr); + addr++; + sprintf(outbuf, "%s $%04X ", mnemonics[opcode], offset); break; case 5: // Inherent - sprintf(outbuf, "%s ", mnemonics[opcode]); + sprintf(outbuf, "%s ", mnemonics[opcode]); break; case 7: // Indexed - sprintf(outbuf, "%s $%02X,X", mnemonics[opcode], soundCPU.RdMem(addr++)); + sprintf(outbuf, "%s $%02X,X ", mnemonics[opcode], soundCPU.RdMem(addr++)); break; case 8: // Immediate - sprintf(outbuf, "%s #$%02X", mnemonics[opcode], soundCPU.RdMem(addr++)); + sprintf(outbuf, "%s #$%02X ", mnemonics[opcode], soundCPU.RdMem(addr++)); break; case 9: // Long Immediate - sprintf(outbuf, "%s #$%04X", mnemonics[opcode], (soundCPU.RdMem(addr++) << 8) | soundCPU.RdMem(addr++)); +// sprintf(outbuf, "%s #$%04X", mnemonics[opcode], (soundCPU.RdMem(addr++) << 8) | soundCPU.RdMem(addr++)); + offset = (soundCPU.RdMem(addr + 0) << 8) | soundCPU.RdMem(addr + 1); + addr += 2; + sprintf(outbuf, "%s #$%04X ", mnemonics[opcode], offset); break; } diff --git a/src/dis6809.cpp b/src/dis6809.cpp index 320f9f2..fdb45d4 100755 --- a/src/dis6809.cpp +++ b/src/dis6809.cpp @@ -217,7 +217,7 @@ int Decode6809(uint16 pc) char outbuf[80], mnem[6], tmp[30]; uint8 opcode2, operand; - uint16 addr = pc; + uint16 addr = pc, offset; uint8 opcode = mainCPU.RdMem(addr++); // Get the opcode uint8 admode = op_mat1[opcode]; // addressing mode @@ -245,13 +245,23 @@ int Decode6809(uint16 pc) sprintf(outbuf, "%s $%02X", mnem, mainCPU.RdMem(addr++)); break; case 2: // Absolute - sprintf(outbuf, "%s $%04X", mnem, (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++)); +// sprintf(outbuf, "%s $%04X", mnem, (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++)); + offset = (mainCPU.RdMem(addr) << 8) | mainCPU.RdMem(addr + 1); + addr += 2; + sprintf(outbuf, "%s $%04X", mnem, offset); break; case 3: // Relative - sprintf(outbuf, "%s $%04X", mnem, ++addr + (int16)(int8)mainCPU.RdMem(addr)); +//DISNOWOK--FIX +// sprintf(outbuf, "%s $%04X", mnem, ++addr + (int16)((int8)mainCPU.RdMem(addr))); + offset = addr + 1 + (int16)(int8)mainCPU.RdMem(addr); + addr++; + sprintf(outbuf, "%s $%04X", mnem, offset); break; case 4: // Long Relative - sprintf(outbuf, "%s $%04X", mnem, addr + (int16)((mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++)) + 2); +// sprintf(outbuf, "%s $%04X", mnem, addr + (int16)((mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++)) + 2); + offset = addr + (int16)((mainCPU.RdMem(addr) << 8) | mainCPU.RdMem(addr + 1)) + 2; + addr += 2; + sprintf(outbuf, "%s $%04X", mnem, offset); break; case 5: // Inherent sprintf(outbuf, "%s ", mnem); @@ -301,7 +311,8 @@ int Decode6809(uint16 pc) sprintf(tmp, "($%02X,%s)", boff, iregs[reg]); break; case 9: - woff = (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++); + woff = (mainCPU.RdMem(addr) << 8) | mainCPU.RdMem(addr + 1); + addr += 2; sprintf(tmp, "($%04X,%s)", woff, iregs[reg]); break; case 11: sprintf(tmp, "(D,%s)", iregs[reg]); break; @@ -310,11 +321,13 @@ int Decode6809(uint16 pc) sprintf(tmp, "($%02X,PC)", boff); break; case 13: - woff = (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++); + woff = (mainCPU.RdMem(addr) << 8) | mainCPU.RdMem(addr + 1); + addr += 2; sprintf(tmp, "($%04X,PC)", woff); break; case 15: - woff = (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++); + woff = (mainCPU.RdMem(addr) << 8) | mainCPU.RdMem(addr + 1); + addr += 2; sprintf(tmp, "[$%04X]", woff); break; default: @@ -337,7 +350,8 @@ int Decode6809(uint16 pc) sprintf(tmp, "($%02X),%s", boff, iregs[reg]); break; case 9: - woff = (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++); + woff = (mainCPU.RdMem(addr) << 8) | mainCPU.RdMem(addr + 1); + addr += 2; sprintf(tmp, "($%04X),%s", woff, iregs[reg]); break; case 11: @@ -347,8 +361,9 @@ int Decode6809(uint16 pc) boff = mainCPU.RdMem(addr++); sprintf(tmp, "($%02X),PC", boff); break; - case 13: - woff = (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++); + case 13: + woff = (mainCPU.RdMem(addr) << 8) | mainCPU.RdMem(addr + 1); + addr += 2; sprintf(tmp, "($%04X),PC", woff); break; default: @@ -363,7 +378,10 @@ int Decode6809(uint16 pc) sprintf(outbuf, "%s #$%02X", mnem, mainCPU.RdMem(addr++)); break; case 9: // Long Immediate - sprintf(outbuf, "%s #$%04X", mnem, (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++)); +// sprintf(outbuf, "%s #$%04X", mnem, (mainCPU.RdMem(addr++) << 8) | mainCPU.RdMem(addr++)); + offset = (mainCPU.RdMem(addr) << 8) | mainCPU.RdMem(addr + 1); + addr += 2; + sprintf(outbuf, "%s #$%04X", mnem, offset); break; } diff --git a/src/sound.cpp b/src/sound.cpp index 6cc1860..b67659b 100755 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -81,7 +81,8 @@ void SoundDone(void) void SDLSoundCallback(void * userdata, Uint8 * buffer, int length) { extern V6808REGS soundCPU; - extern uint8 * sram; +// extern uint8 * sram; + extern uint8 sram[]; int cnt = 0; while (cnt != length) diff --git a/src/stargem2.cpp b/src/stargem2.cpp index ee1b814..edad8fd 100755 --- a/src/stargem2.cpp +++ b/src/stargem2.cpp @@ -31,27 +31,17 @@ #include "dis6809.h" #include "dis6808.h" +#define __DEBUG__ + using namespace std; -#define ROM1 "01" -#define ROM2 "02" -#define ROM3 "03" -#define ROM4 "04" -#define ROM5 "05" -#define ROM6 "06" -#define ROM7 "07" -#define ROM8 "08" -#define ROM9 "09" -#define ROM10 "10" -#define ROM11 "11" -#define ROM12 "12" -#define SOUNDROM "sg.snd" +#define SOUNDROM "ROMs/sg.snd" #define CMOS "cmos.ram" #define SAVESTATE "sg2.state" // Global variables -uint8 * gram, * grom, * sram, * srom; // RAM & ROM pointers +uint8 gram[0x10000], grom[0x10000], sram[0x10000], srom[0x10000]; // RAM & ROM spaces V6809REGS mainCPU; V6808REGS soundCPU; uint8 color[16]; @@ -59,17 +49,6 @@ uint32 palette[256]; // Local variables -//static uint8 lastKeyPressed = 0; -//static bool keyDown = false; - -//static FloppyDrive floppyDrive; - -//enum { LC_BANK_1, LC_BANK_2 }; - -//static uint8 visibleBank = LC_BANK_1; -//static bool readRAM = false; -//static bool writeRAM = false; - static bool running = true; // Machine running state flag... static uint32 startTicks; static uint8 * keys; // SDL raw keyboard matrix @@ -187,6 +166,11 @@ uint8 RdMem6808(uint16 addr) void WrMem6808(uint16 addr, uint8 b) { sram[addr] = b; + + // A total guess, but let's try it... +//It probably depends on how the PIA is configured, so this is most likely wrong. +// if (addr == 0x0401) +// soundCPU.cpuFlags &= ~V6808_ASSERT_LINE_IRQ; } // @@ -194,18 +178,10 @@ void WrMem6808(uint16 addr, uint8 b) // bool LoadImg(char * filename, uint8 * ram, int size) { - char pathname[4096]; - - strcpy(pathname, settings.BIOSPath); - strcat(pathname, filename); - - FILE * fp = fopen(pathname, "rb"); + FILE * fp = fopen(filename, "rb"); if (fp == NULL) - { - WriteLog("Could not open file '%s'!\n", pathname); return false; - } fread(ram, 1, size, fp); fclose(fp); @@ -281,12 +257,11 @@ void SaveMachineState(void) // int main(int /*argc*/, char * /*argv*/[]) { -// bool running; // Machine running state flag... - - LoadSettings(); InitLog("stargem2.log"); WriteLog("StarGem2 - A portable Stargate emulator by James L. Hammons\n"); + LoadSettings(); + // Initialize Williams' palette (RGB coded as: 3 bits red, 3 bits green, 2 bits blue) for(uint32 i=0; i<256; i++) palette[i] = @@ -300,32 +275,6 @@ int main(int /*argc*/, char * /*argv*/[]) | ((((i & 0x40) >> 6) * 71 + ((i & 0x80) >> 7) * 151) << 16) | 0xFF000000; #endif - gram = new uint8[0x10000]; - grom = new uint8[0x10000]; - sram = new uint8[0x10000]; - srom = new uint8[0x10000]; - - if (gram == NULL) - { - WriteLog("Could not allocate RAM space!\nAborting!\n"); - return -1; - } - else if (grom == NULL) - { - WriteLog("Could not allocate ROM space!\nAborting!\n"); - return -1; - } - else if (sram == NULL) - { - WriteLog("Could not allocate sRAM space!\nAborting!\n"); - return -1; - } - else if (srom == NULL) - { - WriteLog("Could not allocate sROM space!\nAborting!\n"); - return -1; - } - // Zero out memory for(long i=0; i<0x10000; i++) gram[i] = grom[i] = sram[i] = srom[i] = 0; @@ -342,47 +291,34 @@ int main(int /*argc*/, char * /*argv*/[]) soundCPU.WrMem = WrMem6808; soundCPU.cpuFlags |= V6808_ASSERT_LINE_RESET; - if (!LoadImg(CMOS, gram + 0xCC00, 0x400)) - WriteLog("CMOS RAM not found!\n"); + char ROMs[12][8] = { + "ROMs/01", "ROMs/02", "ROMs/03", "ROMs/04", "ROMs/05", "ROMs/06", + "ROMs/07", "ROMs/08", "ROMs/09", "ROMs/10", "ROMs/11", "ROMs/12" + }; - if (!LoadImg(ROM1, grom + 0x0000, 0x1000)) - return -1; - - if (!LoadImg(ROM2, grom + 0x1000, 0x1000)) - return -1; - - if (!LoadImg(ROM3, grom + 0x2000, 0x1000)) - return -1; - - if (!LoadImg(ROM4, grom + 0x3000, 0x1000)) - return -1; - - if (!LoadImg(ROM5, grom + 0x4000, 0x1000)) - return -1; - - if (!LoadImg(ROM6, grom + 0x5000, 0x1000)) - return -1; - - if (!LoadImg(ROM7, grom + 0x6000, 0x1000)) - return -1; - - if (!LoadImg(ROM8, grom + 0x7000, 0x1000)) - return -1; - - if (!LoadImg(ROM9, grom + 0x8000, 0x1000)) - return -1; - - if (!LoadImg(ROM10, grom + 0xD000, 0x1000)) - return -1; + for(int i=0; i<12; i++) + { + uint32 baseAddress = i * 0x1000; - if (!LoadImg(ROM11, grom + 0xE000, 0x1000)) - return -1; + if (i > 8) + baseAddress += 0x4000; - if (!LoadImg(ROM12, grom + 0xF000, 0x1000)) - return -1; +#if 0 +WriteLog("Loading ROM image '%s' at $%04X...\n", ROMs[i], baseAddress); +#endif +// if (!LoadImg(ROMs[i], grom + (i * 0x1000), 0x1000)) + if (!LoadImg(ROMs[i], grom + baseAddress, 0x1000)) + { + WriteLog("Could not open file '%s'!\n", ROMs[i]); + return -1; + } + } if (!LoadImg(SOUNDROM, srom + 0xF800, 0x800)) + { + WriteLog("Could not open file '%s'!\n", SOUNDROM); return -1; + } WriteLog("Stargate ROM images loaded...\n"); WriteLog("About to initialize video...\n"); @@ -394,8 +330,15 @@ int main(int /*argc*/, char * /*argv*/[]) } // Have to do this *after* video init but *before* sound init...! + WriteLog("About to load machine state..."); + if (!LoadMachineState()) WriteLog("Machine state file not found!\n"); + else + WriteLog("done!\n"); + + if (!LoadImg(CMOS, gram + 0xCC00, 0x400)) + WriteLog("CMOS RAM not found!\n"); WriteLog("About to intialize audio...\n"); SoundInit(); @@ -584,6 +527,28 @@ for(int i=0; i<200; i++) HandleNextEvent(); } +#ifdef __DEBUG__ +WriteLog("\n"); +WriteLog("$C900 = $%02X (0=RAM)\n", gram[0xC900]); +WriteLog("PC: %04X, X: %04X, Y: %04X, S: %04X, U: %04X, A: %02X, B: %02X, DP: %02X, CC: %02X\n", mainCPU.pc, mainCPU.x, mainCPU.y, mainCPU.s, mainCPU.u, mainCPU.a, mainCPU.b, mainCPU.dp, mainCPU.cc); +WriteLog("\n"); + +/*uint16 pc = mainCPU.pc;//0x15BA; +for(int i=0; i<200; i++) +//while (pc < 0x9000) +{ + pc += Decode6809(pc); + WriteLog("\n"); +}//*/ + +/*uint32 pc = 0; +while (pc < 0xFFFF) +{ + pc += Decode6809(pc); + WriteLog("\n"); +}//*/ +#endif + #endif SoundDone(); @@ -592,11 +557,6 @@ for(int i=0; i<200; i++) SaveMachineState(); LogDone(); - delete[] gram; // Deallocate RAM & ROM spaces - delete[] grom; - delete[] sram; - delete[] srom; - return 0; } diff --git a/src/v6808.cpp b/src/v6808.cpp index e9c4253..b26cb4a 100755 --- a/src/v6808.cpp +++ b/src/v6808.cpp @@ -1,8 +1,8 @@ // -// Virtual 6808 Emulator v1.2 +// Virtual 6808 Emulator v2.0 // // by James L. Hammons -// (c) 2006 Underground Software +// (C) 2006 Underground Software // // JLH = James L. Hammons // @@ -10,9 +10,19 @@ // --- ---------- ------------------------------------------------------------ // JLH 06/15/2006 Added changelog ;-) // JLH 06/15/2006 Scrubbed all BYTE, WORD & DWORD references from the code +// JLH 11/13/2006 Converted core to V65C02 macro style :-) +// JLH 11/13/2006 Converted flags to unpacked and separate flags // -// Mebbe someday I'll get around to fixing the core to be more like V65C02... +// NOTE: V6808_STATE_WAI is not handled in the main loop correctly. !!! FIX !!! + +// Some random thoughts: Could there be a performance gain by breaking +// out the flags in regs.cc into separate uint8 variables (or bools)? +// You'd have to convert on entering and exiting the emulation loop, but I +// think the perfomance hit would be negligible compared to the gain in not +// having to mask and shift flags all the time. Investigate after the +// conversion to macro style opcodes is completed. :-) +// [DONE--remain to be seen if there is any performance increase] //#define __DEBUG__ @@ -23,11 +33,94 @@ #include "log.h" #endif +// Various macros + +#if 0 +#define CLR_Z (regs.cc &= ~FLAG_Z) +#define CLR_ZN (regs.cc &= ~(FLAG_Z | FLAG_N)) +#define CLR_ZNC (regs.cc &= ~(FLAG_Z | FLAG_N | FLAG_C)) +#define CLR_NVC (regs.cc &= ~(FLAG_N | FLAG_V | FLAG_C)) +#define CLR_VC (regs.cc &= ~(FLAG_V | FLAG_C)) +#define CLR_V (regs.cc &= ~FLAG_V) +#define CLR_N (regs.cc &= ~FLAG_N) +#define SET_Z(r) (regs.cc = ((r) == 0 ? regs.cc | FLAG_Z : regs.cc & ~FLAG_Z)) +#define SET_N(r) (regs.cc = ((r) & 0x80 ? regs.cc | FLAG_N : regs.cc & ~FLAG_N)) +#define SET_V(a,b,r) (regs.cc = ((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x80 ? regs.cc | FLAG_V : regs.cc & ~FLAG_V) + +//Not sure that this code is computing the carry correctly... Investigate! [Seems to be] +#define SET_C_ADD(a,b) (regs.cc = ((uint8)(b) > (uint8)(~(a)) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)) +#define SET_C_CMP(a,b) (regs.cc = ((uint8)(b) < (uint8)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)) +#define SET_ZN(r) SET_N(r); SET_Z(r) +#define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b) +#define SET_ZNVC_CMP(a,b,r) SET_N(r); SET_Z(r); SET_C_CMP(a,b); SET_V(a,b,r) + +#define SET_N16(r) (regs.cc = ((r) & 0x8000 ? regs.cc | FLAG_N : regs.cc & ~FLAG_N)) +#define SET_V16(a,b,r) (regs.cc = ((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x8000 ? regs.cc | FLAG_V : regs.cc & ~FLAG_V) +#define SET_C_CMP16(a,b) (regs.cc = ((uint16)(b) < (uint16)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)) +#define SET_ZNVC_CMP16(a,b,r) SET_N16(r); SET_Z(r); SET_C_CMP16(a,b); SET_V16(a,b,r) +#else +#define CLR_Z (flagZ = 0) +#define CLR_ZN (flagZ = flagN = 0) +#define CLR_ZNC (flagZ = flagN = flagC = 0) +#define CLR_NVC (flagN = flagV = flagC = 0) +#define CLR_VC (flagV = flagC = 0) +#define CLR_V (flagV = 0) +#define CLR_N (flagN = 0) +#define SET_Z(r) (flagZ = ((r) == 0 ? 1 : 0)) +#define SET_N(r) (flagN = ((r) & 0x80) >> 7) +#define SET_V(a,b,r) (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x80) >> 7) + +#define SET_C_CMP(a,b) (flagC = ((uint8)(b) < (uint8)(a) ? 1 : 0)) +#define SET_ZN(r) SET_N(r); SET_Z(r) +#define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b) +#define SET_ZNVC_CMP(a,b,r) SET_N(r); SET_Z(r); SET_C_CMP(a,b); SET_V(a,b,r) + +#define SET_N16(r) (flagN = ((r) & 0x8000) >> 15) +#define SET_V16(a,b,r) (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x8000) >> 15) +#define SET_C_CMP16(a,b) (flagC = ((uint16)(b) < (uint16)(a) ? 1 : 0)) +#define SET_ZNVC_CMP16(a,b,r) SET_N16(r); SET_Z(r); SET_C_CMP16(a,b); SET_V16(a,b,r) +#endif + +//Small problem with the EA_ macros: ABS macros don't increment the PC!!! !!! FIX !!! [DONE, kinda] +#define EA_IMM regs.pc++ +#define EA_ZP regs.RdMem(regs.pc++) +#define EA_ZP_X (regs.RdMem(regs.pc++) + regs.x) +#define EA_ABS RdMemW(regs.pc) + +#define READ_IMM regs.RdMem(EA_IMM) +#define READ_ZP regs.RdMem(EA_ZP) +#define READ_ZP_X regs.RdMem(EA_ZP_X) +#define READ_ABS regs.RdMem(EA_ABS); regs.pc += 2 + +#define READ_IMM16 RdMemW(regs.pc); regs.pc += 2 +#define READ_ZP16 RdMemW(EA_ZP) +#define READ_ZP_X16 RdMemW(EA_ZP_X) +#define READ_ABS16 RdMemW(EA_ABS); regs.pc += 2 + +#define READ_IMM_WB(v) uint16 addr = EA_IMM; v = regs.RdMem(addr) +#define READ_ZP_WB(v) uint16 addr = EA_ZP; v = regs.RdMem(addr) +#define READ_ZP_X_WB(v) uint16 addr = EA_ZP_X; v = regs.RdMem(addr) +#define READ_ABS_WB(v) uint16 addr = EA_ABS; v = regs.RdMem(addr); regs.pc += 2 + +#define WRITE_BACK(d) regs.WrMem(addr, (d)) + +#define PULL regs.RdMem(regs.s++) +#define PUSH(r) regs.WrMem(--regs.s, (r)) +#define PULL16 RdMemW(regs.s); regs.s += 2 +#define PUSH16(r) regs.WrMem(--regs.s, (r) & 0xFF); regs.WrMem(--regs.s, (r) >> 8) + +#define PACK_FLAGS ((regs.cc & 0xC0) | (flagH << 5) | (flagI << 4) | (flagN << 3) | (flagZ << 2) | (flagV << 1) | flagC) +#define UNPACK_FLAGS flagH = (regs.cc & FLAG_H) >> 5; \ + flagI = (regs.cc & FLAG_I) >> 4; \ + flagN = (regs.cc & FLAG_N) >> 3; \ + flagZ = (regs.cc & FLAG_Z) >> 2; \ + flagV = (regs.cc & FLAG_V) >> 1; \ + flagC = (regs.cc & FLAG_C) + // Private global variables static V6808REGS regs; -static uint16 addr; -static uint8 tmp; +static uint8 flagH, flagI, flagN, flagZ, flagV, flagC; static uint8 CPUCycles[256] = { 1, 2, 1, 1, 1, 1, 2, 2, 4, 4, 2, 2, 2, 2, 2, 2, @@ -50,1756 +143,1912 @@ static uint8 CPUCycles[256] = { // Private function prototypes -static uint16 FetchW(void); static uint16 RdMemW(uint16); -static void WrMemW(uint16, uint16); - -// -// Fetch a word out of 6808 memory (little endian format) -// This is a leftover from when fetches were separated from garden variety reads... -// -static uint16 FetchW() -{ - uint16 w = RdMemW(regs.pc); - regs.pc += 2; - return w; -} // // Read a word out of 6808 memory (little endian format) // -static uint16 RdMemW(uint16 address) +static inline uint16 RdMemW(uint16 address) { return (uint16)(regs.RdMem(address) << 8) | regs.RdMem(address + 1); } // -// Write a word into 6808 memory (little endian format) -// -static void WrMemW(uint16 address, uint16 w) -{ - regs.WrMem(address + 0, w >> 8); - regs.WrMem(address + 1, w & 0xFF); -} - +// 6808 OPCODE IMPLEMENTATION // -// Function to decode IDX data +// NOTE: Lots of macros are used here to save a LOT of typing. Also +// helps speed the debugging process. :-) Because of this, combining +// certain lines may look like a good idea but would end in disaster. +// You have been warned! ;-) // -inline uint16 DecodeIDX(uint8 code) -{ - return regs.x + code; -} +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Add |ADDA |8B 2 2|9B 3 2|AB 5 2|BB 4 3| |A=A+M |T TTTT| + |ADDB |CB 2 2|DB 3 2|EB 5 2|FB 4 3| |B=B+M |T TTTT| +Add Accumulators |ABA | | | | |1B 2 1|A=A+B |T TTTT| +*/ -// -// Opcode Functions (Mostly correct... Yikes!) -// +// ADD opcodes -static void Op01(void) // NOP +//#define OP_ADD_HANDLER(m, acc) \ + uint16 sum = (uint16)(acc) + (m); \ + regs.cc = (regs.cc & ~FLAG_C) | (sum >> 8); \ + regs.cc = (regs.cc & ~FLAG_H) | ((sum << 1) & FLAG_H); \ + SET_V(m, acc, sum); \ + (acc) = sum & 0xFF; \ + SET_ZN(acc) +#define OP_ADD_HANDLER(m, acc) \ + uint16 sum = (uint16)(acc) + (m); \ + flagC = sum >> 8; \ + flagH = (sum >> 4) & 0x01; \ + SET_V(m, acc, sum); \ + (acc) = sum & 0xFF; \ + SET_ZN(acc) + +static void Op8B(void) // ADDA # { + uint16 m = READ_IMM; + OP_ADD_HANDLER(m, regs.a); } -static void Op06(void) // TAP +static void Op9B(void) // ADDA ZP { - regs.cc = regs.a; + uint16 m = READ_ZP; + OP_ADD_HANDLER(m, regs.a); } -static void Op07(void) // TPA +static void OpAB(void) // ADDA ZP, X { - regs.a = regs.cc; + uint16 m = READ_ZP_X; + OP_ADD_HANDLER(m, regs.a); } -static void Op08(void) // INX +static void OpBB(void) // ADDA ABS { - regs.x++; - - (regs.x == 0 ? regs.cc |= FLAG_Z : regs.cc &= ~FLAG_Z); + uint16 m = READ_ABS; + OP_ADD_HANDLER(m, regs.a); } -static void Op09(void) // DEX +static void OpCB(void) // ADDB # { - regs.x--; - - (regs.x == 0 ? regs.cc |= FLAG_Z : regs.cc &= ~FLAG_Z); + uint16 m = READ_IMM; + OP_ADD_HANDLER(m, regs.b); } -static void Op0A(void) // CLV +static void OpDB(void) // ADDB ZP { - regs.cc &= ~FLAG_V; + uint16 m = READ_ZP; + OP_ADD_HANDLER(m, regs.b); } -static void Op0B(void) // SEV +static void OpEB(void) // ADDB ZP, X { - regs.cc |= FLAG_V; + uint16 m = READ_ZP_X; + OP_ADD_HANDLER(m, regs.b); } -static void Op0C(void) // CLC +static void OpFB(void) // ADDB ABS { - regs.cc &= ~FLAG_C; + uint16 m = READ_ABS; + OP_ADD_HANDLER(m, regs.b); } -static void Op0D(void) // SEC +static void Op1B(void) // ABA { - regs.cc |= FLAG_C; + OP_ADD_HANDLER(regs.b, regs.a); } -static void Op0E(void) // CLI +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Add with Carry |ADCA |89 2 2|99 3 2|A9 5 2|B9 4 3| |A=A+M+C |T TTTT| + |ADCB |C9 2 2|D9 3 2|E9 5 2|F9 4 3| |B=B+M+C |T TTTT| +*/ + +// ADC opcodes + +//#define OP_ADC_HANDLER(m, acc) \ + uint16 sum = (uint16)acc + (m) + (uint16)(regs.cc & FLAG_C); \ + regs.cc = (regs.cc & ~FLAG_C) | (sum >> 8); \ + regs.cc = (regs.cc & ~FLAG_H) | ((sum << 1) & FLAG_H); \ + SET_V(m, acc, sum); \ + acc = sum & 0xFF; \ + SET_ZN(acc) +#define OP_ADC_HANDLER(m, acc) \ + uint16 sum = (uint16)acc + (m) + (uint16)flagC; \ + flagC = sum >> 8; \ + flagH = (sum >> 4) & 0x01; \ + SET_V(m, acc, sum); \ + acc = sum & 0xFF; \ + SET_ZN(acc) + +static void Op89(void) // ADCA # { - regs.cc &= ~FLAG_I; + uint16 m = READ_IMM; + OP_ADC_HANDLER(m, regs.a); } -static void Op0F(void) // SEI +static void Op99(void) // ADCA ZP { - regs.cc |= FLAG_I; + uint16 m = READ_ZP; + OP_ADC_HANDLER(m, regs.a); } -static void Op10(void) // SBA +static void OpA9(void) // ADCA ZP, X { - uint8 as = regs.a; - regs.a -= regs.b; - - regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V | FLAG_C); // Clear NZVC - - if (as < regs.b) - regs.cc |= FLAG_C; - - if ((as ^ regs.b ^ regs.a ^ (regs.cc << 7)) & 0x80) - regs.cc |= FLAG_V; - - if (regs.a == 0) - regs.cc |= FLAG_Z; - - if (regs.a & 0x80) - regs.cc |= FLAG_N; + uint16 m = READ_ZP_X; + OP_ADC_HANDLER(m, regs.a); } -static void Op11(void) // CBA (Compare B to A) +static void OpB9(void) // ADCA ABS { - tmp = regs.a - regs.b; - - regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V | FLAG_C); // Clear NZVC - - if (regs.a < regs.b) - regs.cc |= FLAG_C; - - if ((tmp ^ regs.b ^ regs.a ^ (regs.cc << 7)) & 0x80) - regs.cc |= FLAG_V; - - if (regs.a == 0) - regs.cc |= FLAG_Z; - - if (regs.a & 0x80) - regs.cc |= FLAG_N; + uint16 m = READ_ABS; + OP_ADC_HANDLER(m, regs.a); } -static void Op16(void) // TAB +static void OpC9(void) // ADCB # { - regs.b = regs.a; - - regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V); // Clear NZV + uint16 m = READ_IMM; + OP_ADC_HANDLER(m, regs.b); +} - if (regs.b == 0) - regs.cc |= FLAG_Z; +static void OpD9(void) // ADCB ZP +{ + uint16 m = READ_ZP; + OP_ADC_HANDLER(m, regs.b); +} - if (regs.b & 0x80) - regs.cc |= FLAG_N; +static void OpE9(void) // ADCB ZP, X +{ + uint16 m = READ_ZP_X; + OP_ADC_HANDLER(m, regs.b); } -static void Op17(void) // TBA +static void OpF9(void) // ADCB ABS { - regs.a = regs.b; + uint16 m = READ_ABS; + OP_ADC_HANDLER(m, regs.b); +} - regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V); // Clear NZV +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +And |ANDA |84 2 2|94 3 2|A4 5 2|B4 4 3| |A=A+M | TTR | + |ANDB |C4 2 2|D4 3 2|E4 5 2|F4 4 3| |B=B+M | TTR | +*/ - if (regs.a == 0) - regs.cc |= FLAG_Z; +// AND opcodes - if (regs.a & 0x80) - regs.cc |= FLAG_N; -} +#define OP_AND_HANDLER(m, acc) \ + acc &= m; \ + SET_ZN(acc); \ + CLR_V -static void Op19(void) // DAA +static void Op84(void) // ANDA # { - addr = regs.a; -// if (regs.cc&0x20) addr += 6; // H set? adjust - if ((addr&0x000F) > 9) addr += 6; - if (regs.cc&0x01) addr += 0x60; // C set? adjust - if ((addr&0x00F0) > 0x90) addr += 0x60; - regs.cc &= 0xFD; // CLV - (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - regs.a = addr; - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m = READ_IMM; + OP_AND_HANDLER(m, regs.a); } -static void Op1B(void) // ABA +static void Op94(void) // ANDA ZP { - addr = regs.a + regs.b; - regs.cc &= 0xF0; - if (addr > 0xFF) regs.cc |= 0x01; // Set Carry flag - if ((regs.a^regs.b^addr^(regs.cc<<7))&0x80) regs.cc |= 0x02; // Set oVerflow - regs.a = addr; // Set accumulator - if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag - if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag + uint8 m = READ_ZP; + OP_AND_HANDLER(m, regs.a); } -static void Op20(void) // BRA (BRanch Always) +static void OpA4(void) // ANDA ZP, X { - regs.pc += (int16)(int8)regs.RdMem(regs.pc++); + uint16 m = READ_ZP_X; + OP_AND_HANDLER(m, regs.a); } -static void Op22(void) // BHI +static void OpB4(void) // ANDA ABS { - tmp = regs.RdMem(regs.pc++); - - if (!(regs.cc & (FLAG_C | FLAG_Z))) - regs.pc += (signed short int)(signed char)tmp; + uint16 m = READ_ABS; + OP_AND_HANDLER(m, regs.a); } -static void Op23(void) // BLS +static void OpC4(void) // ANDB # { - tmp = regs.RdMem(regs.pc++); - - if (regs.cc & (FLAG_C | FLAG_Z)) - regs.pc += (signed short int)(signed char)tmp; + uint8 m = READ_IMM; + OP_AND_HANDLER(m, regs.b); } -static void Op24(void) // BCC (BHS) +static void OpD4(void) // ANDB ZP { - tmp = regs.RdMem(regs.pc++); - if (!(regs.cc&0x01)) regs.pc += (signed short int)(signed char)tmp; + uint8 m = READ_ZP; + OP_AND_HANDLER(m, regs.b); } -static void Op25(void) // BCS (BLO) +static void OpE4(void) // ANDB ZP, X { - tmp = regs.RdMem(regs.pc++); - if (regs.cc&0x01) regs.pc += (signed short int)(signed char)tmp; + uint16 m = READ_ZP_X; + OP_AND_HANDLER(m, regs.b); } -static void Op26(void) // BNE +static void OpF4(void) // ANDB ABS { - tmp = regs.RdMem(regs.pc++); - if (!(regs.cc&0x04)) regs.pc += (signed short int)(signed char)tmp; + uint16 m = READ_ABS; + OP_AND_HANDLER(m, regs.b); } -static void Op27(void) // BEQ +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Bit Test |BITA |85 2 2|95 3 2|A5 5 2|B5 4 3| |A+M | TTR | + |BITB |C5 2 2|D5 3 2|E5 5 2|F5 4 3| |B+M | TTR | +*/ + +// BIT opcodes + +#define OP_BIT_HANDLER(m, acc) \ + int8 result = acc & (m); \ + SET_ZN(result) + +static void Op85(void) // BITA # { - tmp = regs.RdMem(regs.pc++); - if (regs.cc&0x04) regs.pc += (signed short int)(signed char)tmp; + uint8 m = READ_IMM; + OP_BIT_HANDLER(m, regs.a); } -static void Op28(void) // BVC +static void Op95(void) // BITA ZP { - tmp = regs.RdMem(regs.pc++); - if (!(regs.cc&0x02)) regs.pc += (signed short int)(signed char)tmp; + uint8 m = READ_ZP; + OP_BIT_HANDLER(m, regs.a); } -static void Op29(void) // BVS +static void OpA5(void) // BITA ZP, X { - tmp = regs.RdMem(regs.pc++); - if (regs.cc&0x02) regs.pc += (signed short int)(signed char)tmp; + uint8 m = READ_ZP_X; + OP_BIT_HANDLER(m, regs.a); } -static void Op2A(void) // BPL +static void OpB5(void) // BITA ABS { - tmp = regs.RdMem(regs.pc++); - if (!(regs.cc&0x08)) regs.pc += (signed short int)(signed char)tmp; + uint8 m = READ_ABS; + OP_BIT_HANDLER(m, regs.a); } -static void Op2B(void) // BMI +static void OpC5(void) // BITB # { - tmp = regs.RdMem(regs.pc++); - if (regs.cc&0x08) regs.pc += (signed short int)(signed char)tmp; + uint8 m = READ_IMM; + OP_BIT_HANDLER(m, regs.b); } -static void Op2C(void) // BGE +static void OpD5(void) // BITB ZP { - tmp = regs.RdMem(regs.pc++); - if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += (signed short int)(signed char)tmp; + uint8 m = READ_ZP; + OP_BIT_HANDLER(m, regs.b); } -static void Op2D(void) // BLT +static void OpE5(void) // BITB ZP, X { - tmp = regs.RdMem(regs.pc++); - if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)) regs.pc += (signed short int)(signed char)tmp; + uint8 m = READ_ZP_X; + OP_BIT_HANDLER(m, regs.b); } -static void Op2E(void) // BGT +static void OpF5(void) // BITB ABS { - tmp = regs.RdMem(regs.pc++); - if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))) regs.pc += (signed short int)(signed char)tmp; + uint8 m = READ_ABS; + OP_BIT_HANDLER(m, regs.b); } -static void Op2F(void) // BLE +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Clear |CLR | | |6F 7 2|7F 6 3| |M=00 | RSRR| + |CLRA | | | | |4F 2 1|A=00 | RSRR| + |CLRB | | | | |5F 2 1|B=00 | RSRR| +*/ + +// CLR opcodes + +static void Op6F(void) // CLR ZP, X { - tmp = regs.RdMem(regs.pc++); - if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += (signed short int)(signed char)tmp; + regs.WrMem(EA_ZP_X, 0); + CLR_NVC; + SET_Z(0); } -static void Op30(void) // TSX +static void Op7F(void) // CLR ABS { - regs.x = regs.s; + regs.WrMem(EA_ABS, 0); + regs.pc += 2; + CLR_NVC; + SET_Z(0); } -static void Op31(void) // INS +static void Op4F(void) // CLRA { - regs.s++; + regs.a = 0; + CLR_NVC; + SET_Z(0); } -static void Op32(void) // PULA +static void Op5F(void) // CLRB { - regs.a = regs.RdMem(regs.s++); + regs.b = 0; + CLR_NVC; + SET_Z(0); } -static void Op33(void) // PULB +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Compare |CMPA |81 2 2|91 3 2|A1 5 2|B1 4 3| |A-M | TTTT| + |CMPB |C1 2 2|D1 3 2|E1 5 2|F1 4 3| |B-M | TTTT| +Compare Accumulators |CBA | | | | |11 2 1|A-B | TTTT| +*/ + +// CMP opcodes + +/* +Compare sets flags as if a subtraction had been carried out. If the value in the accumulator is equal or greater than the compared value, the Carry will be set. The equal (Z) and sign (S) flags will be set based on equality or lack thereof and the sign (i.e. A>=$80) of the accumulator. +*/ + +#define OP_CMP_HANDLER(m, acc) \ + uint16 result = acc - (m); \ + SET_ZNVC_CMP(m, acc, result) + +static void Op81(void) // CMPA # { - regs.b = regs.RdMem(regs.s++); + uint8 m = READ_IMM; + OP_CMP_HANDLER(m, regs.a); } -static void Op34(void) // DES +static void Op91(void) // CMPA ZP { - regs.s--; + uint8 m = READ_ZP; + OP_CMP_HANDLER(m, regs.a); } -static void Op35(void) // TXS +static void OpA1(void) // CMPA ZP, X { - regs.s = regs.x; + uint8 m = READ_ZP_X; + OP_CMP_HANDLER(m, regs.a); } -static void Op36(void) // PSHA +static void OpB1(void) // CMPA ABS { - regs.WrMem(--regs.s, regs.a); + uint8 m = READ_ABS; + OP_CMP_HANDLER(m, regs.a); } -static void Op37(void) // PSHB +static void OpC1(void) // CMPB # { - regs.WrMem(--regs.s, regs.b); + uint8 m = READ_IMM; + OP_CMP_HANDLER(m, regs.b); } -static void Op39(void) // RTS +static void OpD1(void) // CMPB ZP { - regs.pc = (regs.RdMem(regs.s++) << 8) | regs.RdMem(regs.s++); + uint8 m = READ_ZP; + OP_CMP_HANDLER(m, regs.b); } -static void Op3B(void) // RTI +static void OpE1(void) // CMPB ZP, X { - regs.cc = regs.RdMem(regs.s++); - regs.a = regs.RdMem(regs.s++); - regs.b = regs.RdMem(regs.s++); - regs.x = (regs.RdMem(regs.s++) << 8) | regs.RdMem(regs.s++); - regs.pc = (regs.RdMem(regs.s++) << 8) | regs.RdMem(regs.s++); + uint8 m = READ_ZP_X; + OP_CMP_HANDLER(m, regs.b); } -static void Op3E(void) // WAI (wait for interrupt) +static void OpF1(void) // CMPB ABS { - regs.cc &= regs.RdMem(regs.pc++); - regs.cc |= 0x80;//???Is this right??? + uint8 m = READ_ABS; + OP_CMP_HANDLER(m, regs.b); } -static void Op3F(void) // SWI (software interrupt) +static void Op11(void) // CBA { -//Does this respect the I flag??? - regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs... - regs.WrMem(--regs.s, regs.pc >> 8); - regs.WrMem(--regs.s, regs.x & 0xFF); - regs.WrMem(--regs.s, regs.x >> 8); - regs.WrMem(--regs.s, regs.b); - regs.WrMem(--regs.s, regs.a); - regs.WrMem(--regs.s, regs.cc); - regs.pc = RdMemW(0xFFFA); // And do it! - - regs.cc |= FLAG_I; // Also, set IRQ inhibit + OP_CMP_HANDLER(regs.b, regs.a); } -static void Op40(void) // NEGA -{ - regs.a = 256 - regs.a; regs.cc &= 0xF0; - if (regs.a > 0x7F) regs.cc |= 0x01; // Set Carry - if (regs.a == 0x80) regs.cc |= 0x02; // Set oVerflow - if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag - if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag -} +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Complement 1's |COM | | |63 7 2|73 6 3| |M=-M | TTRS| + |COMA | | | | |43 2 1|A=-A | TTRS| + |COMB | | | | |53 2 1|B=-B | TTRS| +*/ -static void Op43(void) // COMA +// COM opcodes + +//#define OP_COM_HANDLER(m) \ + m = m ^ 0xFF; \ + SET_ZN(m); \ + CLR_V; \ + regs.cc |= FLAG_C +#define OP_COM_HANDLER(m) \ + m = m ^ 0xFF; \ + SET_ZN(m); \ + CLR_V; \ + flagC = 1 + +static void Op63(void) // COM ZP, X { - regs.a ^= 0xFF; - regs.cc &= 0xF0; regs.cc |= 0x01; // CLV, SEC - if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag - if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag + uint8 m; + READ_ZP_X_WB(m); + OP_COM_HANDLER(m); + WRITE_BACK(m); } -static void Op44(void) // LSRA +static void Op73(void) // COM ABS { - (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into Carry - regs.a >>= 1; - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m; + READ_ABS_WB(m); + OP_COM_HANDLER(m); + WRITE_BACK(m); } -static void Op46(void) // RORA +static void Op43(void) // COMA { - tmp = regs.a; regs.a = (tmp>>1) + (regs.cc&0x01)*128; - (tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + OP_COM_HANDLER(regs.a); } -static void Op47(void) // ASRA +static void Op53(void) // COMB { - (regs.a&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry - regs.a >>= 1; // Do the shift - if (regs.a&0x40) regs.a |= 0x80; // Set neg if it was set - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + OP_COM_HANDLER(regs.b); } -static void Op48(void) // LSLA (ASLA) [Keep checking from here...] +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Complement 2's |NEG | | |60 7 2|70 6 3| |M=00-M | TT12| + |NEGA | | | | |40 2 1|A=00-A | TT12| + |NEGB | | | | |50 2 1|B=00-B | TT12| +*/ + +// NEG opcodes + +//#define OP_NEG_HANDLER(m) \ + m = -m; \ + SET_ZN(m); \ + regs.cc = (m == 0x80 ? regs.cc | FLAG_V : regs.cc & ~FLAG_V); \ + regs.cc = (m == 0x00 ? regs.cc | FLAG_C : regs.cc & ~FLAG_C) +#define OP_NEG_HANDLER(m) \ + m = -m; \ + SET_ZN(m); \ + flagV = (m == 0x80 ? 1 : 0); \ + flagC = (m == 0x00 ? 1 : 0) + +static void Op60(void) // NEG ZP, X { - (regs.a&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry - regs.a <<= 1; - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m; + READ_ZP_X_WB(m); + OP_NEG_HANDLER(m); + WRITE_BACK(m); } -static void Op49(void) // ROLA +static void Op70(void) // NEG ABS { - tmp = regs.a; regs.a = (tmp<<1) + (regs.cc&0x01); - (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m; + READ_ABS_WB(m); + OP_NEG_HANDLER(m); + WRITE_BACK(m); } -static void Op4A(void) // DECA +static void Op40(void) // NEGA { - regs.a--; - (regs.a == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + OP_NEG_HANDLER(regs.a); } -static void Op4C(void) // INCA +static void Op50(void) // NEGB { -regs.a++; -(regs.a == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag -(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + OP_NEG_HANDLER(regs.b); } -static void Op4D(void) // TSTA +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Decimal Adjust |DAA | | | | |19 2 1|* | TTT3| +*/ + +static void Op19(void) // DAA { -regs.cc &= 0xFD; // Clear oVerflow flag -(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +#if 0 // Just because we can optimize a little here, we will... ;-) + uint16 adjust = 0; + + if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H)) + adjust |= 0x06; + + if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09)) + adjust |= 0x60; + + uint16 result = regs.a + adjust; + regs.a = (uint8)result; + SET_ZN(result); + CLR_V; // Not sure this is correct... + regs.cc |= (result & 0x100) >> 8; // Overwrite carry if it was 0, otherwise, ignore +#else + uint16 result = (uint16)regs.a; + +// if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H)) + if ((regs.a & 0x0F) > 0x09 || flagH) + result += 0x06; + +// if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09)) + if ((regs.a & 0xF0) > 0x90 || flagC || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09)) + result += 0x60; + + regs.a = (uint8)result; + SET_ZN(result); + CLR_V; // Not sure this is correct... +// regs.cc |= (result & 0x100) >> 8; // Overwrite carry if it was 0, otherwise, ignore + flagC |= (result & 0x100) >> 8; // Overwrite carry if it was 0, otherwise, ignore +#endif } -static void Op4F(void) // CLRA +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Decrement |DEC | | |6A 7 2|7A 6 3| |M=M-1 | TT4 | + |DECA | | | | |4A 2 1|A=A-1 | TT4 | + |DECB | | | | |5A 2 1|B=B-1 | TT4 | +*/ + +// DEC opcodes + +//#define OP_DEC_HANDLER(m) \ + m--; \ + SET_ZN(m); \ + regs.cc = (m == 0x7F ? regs.cc | FLAG_V : regs.cc & ~FLAG_V) +#define OP_DEC_HANDLER(m) \ + m--; \ + SET_ZN(m); \ + flagV = (m == 0x7F ? 1 : 0) + +static void Op6A(void) // DEC ZP, X { - regs.a = 0; - regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC + uint8 m; + READ_ZP_X_WB(m); + OP_DEC_HANDLER(m); + WRITE_BACK(m); } -static void Op50(void) // NEGB -{ -regs.b = 256 - regs.b; -// ((regs.b^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H Carry -(regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag -(regs.b > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry +static void Op7A(void) // DEC ABS +{ + uint8 m; + READ_ABS_WB(m); + OP_DEC_HANDLER(m); + WRITE_BACK(m); } -static void Op53(void) // COMB +static void Op4A(void) // DECA { -regs.b ^= 0xFF; -regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + OP_DEC_HANDLER(regs.a); } -static void Op54(void) // LSRB +static void Op5A(void) // DECB { -(regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into Carry -regs.b >>= 1; -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + OP_DEC_HANDLER(regs.b); } -static void Op56(void) // RORB +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Exclusive OR |EORA |88 2 2|98 3 2|A8 5 2|B8 4 3| |A=A(+)M | TTR | + |EORB |C8 2 2|D8 3 2|E8 5 2|F8 4 3| |B=B(+)M | TTR | +*/ + +// EOR opcodes + +#define OP_EOR_HANDLER(m, acc) \ + acc ^= m; \ + SET_ZN(acc); \ + CLR_V + +static void Op88(void) // EORA # { -tmp = regs.b; regs.b = (regs.b >> 1) + (regs.cc&0x01)*128; -(tmp&0x01 ? regs.cc |=0x01 : regs.cc &= 0xFE); // Shift bit into Carry -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m = READ_IMM; + OP_EOR_HANDLER(m, regs.a); } -static void Op57(void) // ASRB +static void Op98(void) // EORA ZP { -(regs.b&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry -regs.b >>= 1; // Do the shift -if (regs.b&0x40) regs.b |= 0x80; // Set neg if it was set -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m = READ_ZP; + OP_EOR_HANDLER(m, regs.a); } -static void Op58(void) // LSLB +static void OpA8(void) // EORA ZP, X { -(regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry -regs.b <<= 1; -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m = READ_ZP_X; + OP_EOR_HANDLER(m, regs.a); } -static void Op59(void) // ROLB +static void OpB8(void) // EORA ABS { - tmp = regs.b; - regs.b = (tmp<<1) + (regs.cc&0x01); - (tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m = READ_ABS; + OP_EOR_HANDLER(m, regs.a); } -static void Op5A(void) // DECB +static void OpC8(void) // EORB # { -regs.b--; -(regs.b == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m = READ_IMM; + OP_EOR_HANDLER(m, regs.b); } -static void Op5C(void) // INCB +static void OpD8(void) // EORB ZP { -regs.b++; -(regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m = READ_ZP; + OP_EOR_HANDLER(m, regs.b); } -static void Op5D(void) // TSTB +static void OpE8(void) // EORB ZP, X { -regs.cc &= 0xFD; // Cleregs.a oVerflow flag -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m = READ_ZP_X; + OP_EOR_HANDLER(m, regs.b); } -static void Op5F(void) // CLRB +static void OpF8(void) // EORB ABS { -regs.b = 0; -regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC + uint8 m = READ_ABS; + OP_EOR_HANDLER(m, regs.b); } -static void Op60(void) // NEG IDX -{ -addr = DecodeIDX(regs.RdMem(regs.pc++)); -tmp = regs.RdMem(addr); uint8 res = 256 - tmp; -regs.WrMem(addr, res); -// ((res^tmp)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Adjust H Carry -(res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow -(res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag -(res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Increment |INC | | |6C 7 2|7C 6 3| |M=M+1 | TT5 | + |INCA | | | | |4C 2 1|A=A+1 | TT5 | + |INCB | | | | |5C 2 1|B=B+1 | TT5 | +*/ + +// INC opcodes + +//#define OP_INC_HANDLER(m) \ + m++; \ + SET_ZN(m); \ + regs.cc = (m == 0x80 ? regs.cc | FLAG_V : regs.cc & ~FLAG_V) +#define OP_INC_HANDLER(m) \ + m++; \ + SET_ZN(m); \ + flagV = (m == 0x80 ? 1 : 0) + +static void Op6C(void) // INC ZP, X +{ + uint8 m; + READ_ZP_X_WB(m); + OP_INC_HANDLER(m); + WRITE_BACK(m); } -static void Op63(void) // COM IDX +static void Op7C(void) // INC ABS { -addr = DecodeIDX(regs.RdMem(regs.pc++)); -tmp = regs.RdMem(addr) ^ 0xFF; -regs.WrMem(addr, tmp); -regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC -(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m; + READ_ABS_WB(m); + OP_INC_HANDLER(m); + WRITE_BACK(m); } -static void Op64(void) // LSR IDX +static void Op4C(void) // INCA { -addr = DecodeIDX(regs.RdMem(regs.pc++)); -tmp = regs.RdMem(addr); -(tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into Carry -tmp >>= 1; regs.WrMem(addr, tmp); -regs.cc &= 0xF7; // CLN -(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + OP_INC_HANDLER(regs.a); } -static void Op66(void) // ROR IDX +static void Op5C(void) // INCB { -addr = DecodeIDX(regs.RdMem(regs.pc++)); -tmp = regs.RdMem(addr); uint8 tmp2 = tmp; -tmp = (tmp >> 1) + (regs.cc&0x01)*128; -regs.WrMem(addr, tmp); -(tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry -(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + OP_INC_HANDLER(regs.b); } -static void Op67(void) // ASR IDX +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Load Accumulator |LDAA |86 2 2|96 3 2|A6 5 2|B6 4 3| |A=M | TTR | + |LDAB |C6 2 2|D6 3 2|E6 5 2|F6 4 3| |B=M | TTR | +*/ + +// LDA opcodes + +#define OP_LDA_HANDLER(m, acc) \ + acc = m; \ + SET_ZN(acc); \ + CLR_V + +static void Op86(void) // LDAA # { -addr = DecodeIDX(regs.RdMem(regs.pc++)); -tmp = regs.RdMem(addr); -(tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry -tmp >>= 1; -if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set -regs.WrMem(addr, tmp); -(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m = READ_IMM; + OP_LDA_HANDLER(m, regs.a); } -static void Op68(void) // LSL IDX +static void Op96(void) // LDAA ZP { -addr = DecodeIDX(regs.RdMem(regs.pc++)); -tmp = regs.RdMem(addr); -(tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry -tmp <<= 1; -regs.WrMem(addr, tmp); -(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m = READ_ZP; + OP_LDA_HANDLER(m, regs.a); } -static void Op69(void) // ROL IDX +static void OpA6(void) // LDAA ZP, X { - uint8 tmp2 = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - tmp = (tmp2<<1) + (regs.cc&0x01); - regs.WrMem(addr, tmp); - (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry - (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m = READ_ZP_X; + OP_LDA_HANDLER(m, regs.a); } -static void Op6A(void) // DEC IDX +static void OpB6(void) // LDAA ABS { -uint8 tmp; uint16 addr; -addr = DecodeIDX(regs.RdMem(regs.pc++)); -tmp = regs.RdMem(addr) - 1; -regs.WrMem(addr, tmp); -(tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag -(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m = READ_ABS; + OP_LDA_HANDLER(m, regs.a); } -static void Op6C(void) // INC IDX -{ -addr = DecodeIDX(regs.RdMem(regs.pc++)); -tmp = regs.RdMem(addr) + 1; -regs.WrMem(addr, tmp); -(tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag -(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +static void OpC6(void) // LDAB # +{ + uint8 m = READ_IMM; + OP_LDA_HANDLER(m, regs.b); } -static void Op6D(void) // TST IDX +static void OpD6(void) // LDAB ZP { -tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); -(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m = READ_ZP; + OP_LDA_HANDLER(m, regs.b); } -static void Op6E(void) // JMP IDX +static void OpE6(void) // LDAB ZP, X { - regs.pc = DecodeIDX(regs.RdMem(regs.pc++)); + uint8 m = READ_ZP_X; + OP_LDA_HANDLER(m, regs.b); } -static void Op6F(void) // CLR IDX +static void OpF6(void) // LDAB ABS { - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.WrMem(addr, 0); - regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC + uint8 m = READ_ABS; + OP_LDA_HANDLER(m, regs.b); } -static void Op70(void) // NEG ABS -{ -addr = FetchW(); -tmp = regs.RdMem(addr); uint8 res = 256 - tmp; -regs.WrMem(addr, res); -(res == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow -(res == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(res&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag -(res > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +OR, Inclusive |ORAA |8A 2 2|9A 3 2|AA 5 2|BA 4 3| |A=A+M | TTR | + |ORAB |CA 2 2|DA 3 2|EA 5 2|FA 4 3| |B=B+M | TTR | +*/ + +// ORA opcodes + +#define OP_ORA_HANDLER(m, acc) \ + acc |= m; \ + SET_ZN(acc); \ + CLR_V + +static void Op8A(void) // ORAA # +{ + uint8 m = READ_IMM; + OP_ORA_HANDLER(m, regs.a); } -static void Op73(void) // COM ABS +static void Op9A(void) // ORAA ZP { -addr = FetchW(); -tmp = regs.RdMem(addr) ^ 0xFF; -regs.WrMem(addr, tmp); -regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC -(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m = READ_ZP; + OP_ORA_HANDLER(m, regs.a); } -static void Op74(void) // LSR ABS +static void OpAA(void) // ORAA ZP, X { -addr = FetchW(); -tmp = regs.RdMem(addr); -(tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift low bit into Carry -tmp >>= 1; regs.WrMem(addr, tmp); -regs.cc &= 0xF7; // CLN -(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + uint8 m = READ_ZP_X; + OP_ORA_HANDLER(m, regs.a); } -static void Op76(void) // ROR ABS +static void OpBA(void) // ORAA ABS { -uint8 tmp; uint16 addr; -addr = FetchW(); -tmp = regs.RdMem(addr); uint8 tmp2 = tmp; -tmp = (tmp >> 1) + (regs.cc&0x01)*128; -regs.WrMem(addr, tmp); -(tmp2&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry -(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m = READ_ABS; + OP_ORA_HANDLER(m, regs.a); } -static void Op77(void) // ASR ABS +static void OpCA(void) // ORAB # { -uint8 tmp; uint16 addr; -addr = FetchW(); -tmp = regs.RdMem(addr); -(tmp&0x01 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift bit into Carry -tmp >>= 1; -if (tmp&0x40) tmp |= 0x80; // Set Neg if it was set -regs.WrMem(addr, tmp); -(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m = READ_IMM; + OP_ORA_HANDLER(m, regs.b); } -static void Op78(void) // LSL ABS +static void OpDA(void) // ORAB ZP { -uint8 tmp; uint16 addr; -addr = FetchW(); -tmp = regs.RdMem(addr); -(tmp&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry -tmp <<= 1; -regs.WrMem(addr, tmp); -(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m = READ_ZP; + OP_ORA_HANDLER(m, regs.b); } -static void Op79(void) // ROL ABS +static void OpEA(void) // ORAB ZP, X { - uint8 tmp2 = regs.RdMem(FetchW()); - tmp = (tmp2<<1) + (regs.cc&0x01); - regs.WrMem(addr, tmp); - (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into Carry - (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m = READ_ZP_X; + OP_ORA_HANDLER(m, regs.b); } -static void Op7A(void) // DEC ABS +static void OpFA(void) // ORAB ABS { -uint8 tmp; uint16 addr; -addr = FetchW(); -tmp = regs.RdMem(addr) - 1; -regs.WrMem(addr, tmp); -(tmp == 0x7F ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag -(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m = READ_ABS; + OP_ORA_HANDLER(m, regs.b); } -static void Op7C(void) // INC ABS -{ - addr = FetchW(); - tmp = regs.RdMem(addr) + 1; - regs.WrMem(addr, tmp); +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Push Data |PSHA | | | | |36 4 1|Msp=A, *- | | + |PSHB | | | | |37 4 1|Msp=B, *- | | +Pull Data |PULA | | | | |32 4 1|A=Msp, *+ | | + |PULB | | | | |33 4 1|B=Msp, *+ | | +*/ - (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag - (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +static void Op36(void) // PSHA +{ +// regs.WrMem(--regs.s, regs.a); + PUSH(regs.a); } -static void Op7D(void) // TST ABS +static void Op37(void) // PSHB { - uint8 tmp = regs.RdMem(FetchW()); - - (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (tmp & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +// regs.WrMem(--regs.s, regs.b); + PUSH(regs.b); } -static void Op7E(void) // JMP ABS +static void Op32(void) // PULA { - regs.pc = FetchW(); +// regs.a = regs.RdMem(regs.s++); + regs.a = PULL; } -static void Op7F(void) // CLR ABS +static void Op33(void) // PULB { -regs.WrMem(FetchW(), 0); -regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC +// regs.b = regs.RdMem(regs.s++); + regs.b = PULL; } -static void Op80(void) // SUBA # -{ - uint8 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a; - regs.a -= tmp; - (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Rotate Left |ROL | | |69 7 2|79 6 3| |Memory *1| TT6T| + |ROLA | | | | |49 2 1|Accum A *1| TT6T| + |ROLB | | | | |59 2 1|Accum B *1| TT6T| +*/ + +// ROL opcodes + +//#define OP_ROL_HANDLER(m) \ + uint8 newCarry = (m & 0x80) >> 7; \ + m = (m << 1) | (regs.cc & FLAG_C); \ + SET_ZN(m); \ + regs.cc = (regs.cc & ~FLAG_C) | newCarry; \ + regs.cc = (regs.cc & ~FLAG_V) | ((regs.cc & FLAG_N) >> 2) ^ ((regs.cc & FLAG_C) << 1) +#define OP_ROL_HANDLER(m) \ + uint8 newCarry = (m & 0x80) >> 7; \ + m = (m << 1) | flagC; \ + SET_ZN(m); \ + flagC = newCarry; \ + flagV = flagN ^ flagC + +static void Op69(void) // ROL ZP, X +{ + uint8 m; + READ_ZP_X_WB(m); + OP_ROL_HANDLER(m); + WRITE_BACK(m); } -static void Op81(void) // CMPA # +static void Op79(void) // ROL ABS { - tmp = regs.RdMem(regs.pc++); - uint8 db = regs.a - tmp; - (regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m; + READ_ABS_WB(m); + OP_ROL_HANDLER(m); + WRITE_BACK(m); } -static void Op82(void) // SBCA # +static void Op49(void) // ROLA { - tmp = regs.RdMem(regs.pc++); uint8 as = regs.a; - regs.a = regs.a - tmp - (regs.cc&0x01); - (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + OP_ROL_HANDLER(regs.a); } -static void Op84(void) // ANDA # +static void Op59(void) // ROLB { -regs.a &= regs.RdMem(regs.pc++); -regs.cc &= 0xFD; // Cleregs.a oVerflow flag -(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + OP_ROL_HANDLER(regs.b); } -static void Op85(void) // BITA # +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Rotate Right |ROR | | |66 7 2|76 6 3| |Memory *2| TT6T| + |RORA | | | | |46 2 1|Accum A *2| TT6T| + |RORB | | | | |56 2 1|Accum B *2| TT6T| +*/ + +// ROR opcodes + +//#define OP_ROR_HANDLER(m) \ + uint8 newCarry = m & 0x01; \ + m = (m >> 1) | ((regs.cc & FLAG_C) << 7); \ + SET_ZN(m); \ + regs.cc = (regs.cc & ~FLAG_C) | newCarry; \ + regs.cc = (regs.cc & ~FLAG_V) | ((regs.cc & FLAG_N) >> 2) ^ ((regs.cc & FLAG_C) << 1) +#define OP_ROR_HANDLER(m) \ + uint8 newCarry = m & 0x01; \ + m = (m >> 1) | (flagC << 7); \ + SET_ZN(m); \ + flagC = newCarry; \ + flagV = flagN ^ flagC + +static void Op66(void) // ROR ZP, X { -tmp = regs.a & regs.RdMem(regs.pc++); -regs.cc &= 0xFD; // Cleregs.a oVerflow flag -(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m; + READ_ZP_X_WB(m); + OP_ROR_HANDLER(m); + WRITE_BACK(m); } -static void Op86(void) // LDAA # +static void Op76(void) // ROR ABS { -regs.a = regs.RdMem(regs.pc++); -regs.cc &= 0xFD; // CLV -(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m; + READ_ABS_WB(m); + OP_ROR_HANDLER(m); + WRITE_BACK(m); } -static void Op88(void) // EORA # +static void Op46(void) // RORA { -regs.a ^= regs.RdMem(regs.pc++); -regs.cc &= 0xFD; // CLV -(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + OP_ROR_HANDLER(regs.a); } -static void Op89(void) // ADCA # +static void Op56(void) // RORB { - tmp = regs.RdMem(regs.pc++); - addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry -// ((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half Carry - ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.a = addr & 0xFF; // Set accumulator - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative + OP_ROR_HANDLER(regs.b); } -static void Op8A(void) // ORAA # +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Arithmetic Shift Left |ASL | | |68 7 2|78 6 3| |Memory *3| TT6T| + |ASLA | | | | |48 2 1|Accum A *3| TT6T| + |ASLB | | | | |58 2 1|Accum B *3| TT6T| +*/ + +// ASL opcodes + +//#define OP_ASL_HANDLER(m) \ + uint8 newCarry = (m & 0x80) >> 7; \ + m <<= 1; \ + SET_ZN(m); \ + regs.cc = (regs.cc & ~FLAG_C) | newCarry; \ + regs.cc = (regs.cc & ~FLAG_V) | ((regs.cc & FLAG_N) >> 2) ^ ((regs.cc & FLAG_C) << 1) +#define OP_ASL_HANDLER(m) \ + uint8 newCarry = (m & 0x80) >> 7; \ + m <<= 1; \ + SET_ZN(m); \ + flagC = newCarry; \ + flagV = flagN ^ flagC + +static void Op68(void) // ASL ZP, X { -regs.a |= regs.RdMem(regs.pc++); -regs.cc &= 0xFD; // CLV -(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m; + READ_ZP_X_WB(m); + OP_ASL_HANDLER(m); + WRITE_BACK(m); } -static void Op8B(void) // ADDA # -{ - tmp = regs.RdMem(regs.pc++); addr = regs.a + tmp; - (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.a = addr & 0xFF; // Set accumulator - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +static void Op78(void) // ASL ABS +{ + uint8 m; + READ_ABS_WB(m); + OP_ASL_HANDLER(m); + WRITE_BACK(m); } -static void Op8C(void) // CPX # +static void Op48(void) // ASLA { - addr = FetchW(); - uint16 dw = regs.x - addr; - (regs.x < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.x^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + OP_ASL_HANDLER(regs.a); } -static void Op8D(void) // BSR +static void Op58(void) // ASLB { - tmp = regs.RdMem(regs.pc++); + OP_ASL_HANDLER(regs.b); +} + +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Arithmetic Shift Right |ASR | | |67 7 2|77 6 3| |Memory *4| TT6T| + |ASRA | | | | |47 2 1|Accum A *4| TT6T| + |ASRB | | | | |57 2 1|Accum B *4| TT6T| +*/ + +// ASR opcodes - regs.s -= 2; - WrMemW(regs.s, regs.pc); +//#define OP_ASR_HANDLER(m) \ + uint8 newCarry = m & 0x01; \ + m = (m >> 1) | (m & 0x80); \ + SET_ZN(m); \ + regs.cc = (regs.cc & ~FLAG_C) | newCarry; \ + regs.cc = (regs.cc & ~FLAG_V) | ((regs.cc & FLAG_N) >> 2) ^ ((regs.cc & FLAG_C) << 1) +#define OP_ASR_HANDLER(m) \ + uint8 newCarry = m & 0x01; \ + m = (m >> 1) | (m & 0x80); \ + SET_ZN(m); \ + flagC = newCarry; \ + flagV = flagN ^ flagC - regs.pc += (signed short int)(signed char)tmp; +static void Op67(void) // ASR ZP, X +{ + uint8 m; + READ_ZP_X_WB(m); + OP_ASR_HANDLER(m); + WRITE_BACK(m); } -static void Op8E(void) // LDS # +static void Op77(void) // ASR ABS { -regs.s = FetchW(); -regs.cc &= 0xFD; // CLV -(regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m; + READ_ABS_WB(m); + OP_ASR_HANDLER(m); + WRITE_BACK(m); } -static void Op90(void) // SUBA ZP -{ - tmp = regs.RdMem(regs.RdMem(regs.pc++)); uint8 as = regs.a; - regs.a -= tmp; - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +static void Op47(void) // ASRA +{ + OP_ASR_HANDLER(regs.a); } -static void Op91(void) // CMPA ZP +static void Op57(void) // ASRB { -tmp = regs.RdMem(regs.RdMem(regs.pc++)); -uint8 db = regs.a - tmp; -(db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag -(regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag -((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + OP_ASR_HANDLER(regs.b); } -static void Op92(void) // SBCA ZP +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Logic Shift Right |LSR | | |64 7 2|74 6 3| |Memory *5| TT6T| + |LSRA | | | | |44 2 1|Accum A *5| TT6T| + |LSRB | | | | |54 2 1|Accum B *5| TT6T| +*/ + +// LSR opcodes + +//#define OP_LSR_HANDLER(m) \ + uint8 newCarry = m & 0x01; \ + m >>= 1; \ + SET_ZN(m); \ + regs.cc = (regs.cc & ~FLAG_C) | newCarry; \ + regs.cc = (regs.cc & ~FLAG_V) | ((regs.cc & FLAG_N) >> 2) ^ ((regs.cc & FLAG_C) << 1) +#define OP_LSR_HANDLER(m) \ + uint8 newCarry = m & 0x01; \ + m >>= 1; \ + SET_ZN(m); \ + flagC = newCarry; \ + flagV = flagN ^ flagC + +static void Op64(void) // LSR ZP, X { - tmp = regs.RdMem(regs.RdMem(regs.pc++)); uint8 as = regs.a; - regs.a = regs.a - tmp - (regs.cc&0x01); - (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m; + READ_ZP_X_WB(m); + OP_LSR_HANDLER(m); + WRITE_BACK(m); } -static void Op94(void) // ANDA ZP +static void Op74(void) // LSR ABS { - regs.a &= regs.RdMem(regs.RdMem(regs.pc++)); - regs.cc &= 0xF1; // CLV CLZ CLN - if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag - if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag + uint8 m; + READ_ABS_WB(m); + OP_LSR_HANDLER(m); + WRITE_BACK(m); } -static void Op95(void) // BITA ZP +static void Op44(void) // LSRA { -tmp = regs.a & regs.RdMem(regs.RdMem(regs.pc++)); -regs.cc &= 0xFD; // Cleregs.a oVerflow flag -(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + OP_LSR_HANDLER(regs.a); } -static void Op96(void) // LDAA ZP +static void Op54(void) // LSRB { - regs.a = regs.RdMem(regs.RdMem(regs.pc++)); - regs.cc &= 0xF1; // CLN CLZ CLV - if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag - if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag + OP_LSR_HANDLER(regs.b); } -static void Op97(void) // STAA ZP +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Store Accumulator |STAA | |97 4 2|A7 6 2|B7 5 3| |M=A | TTR | + |STAB | |D7 4 2|E7 6 2|F7 5 3| |M=B | TTR | +*/ + +static void Op97(void) // STAA ZP { -regs.WrMem(regs.RdMem(regs.pc++), regs.a); -regs.cc &= 0xFD; // CLV -(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.WrMem(EA_ZP, regs.a); } -static void Op98(void) // EORA ZP +static void OpA7(void) // STAA ZP, X { -regs.a ^= regs.RdMem(regs.RdMem(regs.pc++)); -regs.cc &= 0xFD; // CLV -(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.WrMem(EA_ZP_X, regs.a); } -static void Op99(void) // ADCA ZP +static void OpB7(void) // STAA ABS { - tmp = regs.RdMem(regs.RdMem(regs.pc++)); - addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry - ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.a = addr & 0xFF; // Set accumulator - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative + regs.WrMem(EA_ABS, regs.a); + regs.pc += 2; } -static void Op9A(void) // ORAA ZP +static void OpD7(void) // STAB ZP { -regs.a |= regs.RdMem(regs.RdMem(regs.pc++)); -regs.cc &= 0xFD; // CLV -(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.WrMem(EA_ZP, regs.b); } -static void Op9B(void) // ADDA ZP -{ - tmp = regs.RdMem(regs.RdMem(regs.pc++)); - addr = (uint16)regs.a + (uint16)tmp; - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo - regs.a = addr & 0xFF; // Set accumulator - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +static void OpE7(void) // STAB ZP, X +{ + regs.WrMem(EA_ZP_X, regs.b); } -static void Op9C(void) // CPX ZP +static void OpF7(void) // STAB ABS { -addr = regs.RdMem(regs.pc++); -uint16 adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); -uint16 dw = regs.x - adr2; -(dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag -(regs.x < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag -((regs.x^adr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.WrMem(EA_ABS, regs.b); + regs.pc += 2; } -static void Op9E(void) // LDS ZP +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Subtract |SUBA |80 2 2|90 3 2|A0 5 2|B0 4 3| |A=A-M | TTTT| + |SUBB |C0 2 2|D0 3 2|E0 5 2|F0 4 3| |B=B-M | TTTT| +Subtract Accumulators |SBA | | | | |10 2 1|A=A-B | TTTT| +*/ + +// SUB opcodes + +//#define OP_SUB_HANDLER(m, acc) \ + uint16 sum = (uint16)acc - (m); \ + regs.cc = (regs.cc & ~FLAG_C) | (sum >> 15); \ + SET_V(m, acc, sum); \ + acc = (uint8)sum; \ + SET_ZN(acc) +#define OP_SUB_HANDLER(m, acc) \ + uint16 sum = (uint16)acc - (m); \ + flagC = sum >> 15; \ + SET_V(m, acc, sum); \ + acc = (uint8)sum; \ + SET_ZN(acc) + +static void Op80(void) // SUBA # { - regs.s = RdMemW(regs.RdMem(regs.pc++)); + uint16 m = READ_IMM; + OP_SUB_HANDLER(m, regs.a); +} - regs.cc &= 0xFD; // CLV - (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +static void Op90(void) // SUBA ZP +{ + uint16 m = READ_ZP; + OP_SUB_HANDLER(m, regs.a); } -static void Op9F(void) // STS ZP +static void OpA0(void) // SUBA ZP, X { - WrMemW(regs.RdMem(regs.pc++), regs.s); + uint16 m = READ_ZP_X; + OP_SUB_HANDLER(m, regs.a); +} - regs.cc &= 0xFD; // CLV - (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +static void OpB0(void) // SUBA ABS +{ + uint16 m = READ_ABS; + OP_SUB_HANDLER(m, regs.a); } -static void OpA0(void) // SUBA IDX -{ -tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a; -regs.a -= tmp; -(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag -(as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag -((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +static void OpC0(void) // SUBB # +{ + uint16 m = READ_IMM; + OP_SUB_HANDLER(m, regs.b); } -static void OpA1(void) // CMPA IDX +static void OpD0(void) // SUBB ZP { -tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); -uint8 db = regs.a - tmp; -(db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag -(regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag -((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + uint16 m = READ_ZP; + OP_SUB_HANDLER(m, regs.b); } -static void OpA2(void) // SBCA IDX +static void OpE0(void) // SUBB ZP, X { - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a; - regs.a = regs.a - tmp - (regs.cc&0x01); - (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint16 m = READ_ZP_X; + OP_SUB_HANDLER(m, regs.b); } -static void OpA4(void) // ANDA IDX +static void OpF0(void) // SUBB ABS { -regs.a &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); -regs.cc &= 0xFD; // Cleregs.a oVerflow flag -(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint16 m = READ_ABS; + OP_SUB_HANDLER(m, regs.b); } -static void OpA5(void) // BITA IDX +static void Op10(void) // SBA { -tmp = regs.a & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); -regs.cc &= 0xFD; // Cleregs.a oVerflow flag -(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + OP_SUB_HANDLER(regs.b, regs.a); } -static void OpA6(void) // LDAA IDX +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Subtract with Carry |SBCA |82 2 2|92 3 2|A2 5 2|B2 4 3| |A=A-M-C | TTTT| + |SBCB |C2 2 2|D2 3 2|E2 5 2|F2 4 3| |B=B-M-C | TTTT| +*/ + +// SBC opcodes + +//#define OP_SBC_HANDLER(m, acc) \ + uint16 sum = (uint16)acc - (m) - (uint16)(regs.cc & FLAG_C); \ + regs.cc = (regs.cc & ~FLAG_C) | (sum >> 15); \ + SET_V(m, acc, sum); \ + acc = (uint8)sum; \ + SET_ZN(acc) +#define OP_SBC_HANDLER(m, acc) \ + uint16 sum = (uint16)acc - (m) - (uint16)flagC; \ + flagC = sum >> 15; \ + SET_V(m, acc, sum); \ + acc = (uint8)sum; \ + SET_ZN(acc) + +static void Op82(void) // SBCA # { - regs.a = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - regs.cc &= 0xF1; // CLV CLZ CLN - if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag - if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag + uint16 m = READ_IMM; + OP_SBC_HANDLER(m, regs.a); } -static void OpA7(void) // STAA IDX +static void Op92(void) // SBCA ZP { - regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.a); - regs.cc &= 0xF1; // CLV CLZ CLN - if (regs.a == 0) regs.cc |= 0x04; // Set Zero flag - if (regs.a&0x80) regs.cc |= 0x08; // Set Negative flag + uint16 m = READ_ZP; + OP_SBC_HANDLER(m, regs.a); } -static void OpA8(void) // EORA IDX +static void OpA2(void) // SBCA ZP, X { -regs.a ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); -regs.cc &= 0xFD; // CLV -(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint16 m = READ_ZP_X; + OP_SBC_HANDLER(m, regs.a); } -static void OpA9(void) // ADCA IDX +static void OpB2(void) // SBCA ABS { - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo - regs.a = addr & 0xFF; // Set accumulator - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + uint16 m = READ_ABS; + OP_SBC_HANDLER(m, regs.a); } -static void OpAA(void) // ORAA IDX +static void OpC2(void) // SBCB # { - regs.a |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - regs.cc &= 0xFD; // CLV - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint16 m = READ_IMM; + OP_SBC_HANDLER(m, regs.b); } -static void OpAB(void) // ADDA IDX -{ - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - addr = (uint16)regs.a + (uint16)tmp; - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo - regs.a = addr & 0xFF; // Set accumulator - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +static void OpD2(void) // SBCB ZP +{ + uint16 m = READ_ZP; + OP_SBC_HANDLER(m, regs.b); } -static void OpAC(void) // CPX IDX +static void OpE2(void) // SBCB ZP, X { - addr = DecodeIDX(regs.RdMem(regs.pc++)); - uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - uint16 dw = regs.x - addr2; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + uint16 m = READ_ZP_X; + OP_SBC_HANDLER(m, regs.b); } -static void OpAD(void) // JSR IDX +static void OpF2(void) // SBCB ABS { - addr = DecodeIDX(regs.RdMem(regs.pc++)); + uint16 m = READ_ABS; + OP_SBC_HANDLER(m, regs.b); +} - regs.s -= 2; - WrMemW(regs.s, regs.pc); +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Transfer Accumulators |TAB | | | | |16 2 1|B=A | TTR | + |TBA | | | | |17 2 1|A=B | TTR | +*/ - regs.pc = addr; // JSR directly to IDX ptr +static void Op16(void) // TAB +{ + regs.b = regs.a; + SET_ZN(regs.b); + CLR_V; } -static void OpAE(void) // LDS IDX +static void Op17(void) // TBA { - regs.s = RdMemW(DecodeIDX(regs.RdMem(regs.pc++))); - - regs.cc &= ~FLAG_V; - (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.a = regs.b; + SET_ZN(regs.a); + CLR_V; } -static void OpAF(void) // STS IDX -{ - WrMemW(DecodeIDX(regs.RdMem(regs.pc++)), regs.s); +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Test, Zero/Minus |TST | | |6D 7 2|7D 6 3| |M-00 | TTRR| + |TSTA | | | | |4D 2 1|A-00 | TTRR| + |TSTB | | | | |5D 2 1|B-00 | TTRR| +*/ - regs.cc &= ~(FLAG_N | FLAG_Z | FLAG_V); // Clear NZV - if (regs.s & 0x8000) regs.cc |= FLAG_N; // Set Negative flag - if (regs.s == 0) regs.cc |= FLAG_Z; // Set Zero flag -} +// TST opcodes -static void OpB0(void) // SUBA ABS -{ -tmp = regs.RdMem(FetchW()); uint8 as = regs.a; -regs.a -= tmp; -(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag -(as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag -((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow -} +#define OP_TST_HANDLER(m) \ + SET_ZN(m); \ + CLR_VC -static void OpB1(void) // CMPA ABS +static void Op6D(void) // TST ZP, X { -tmp = regs.RdMem(FetchW()); -uint8 db = regs.a - tmp; -(db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag -(regs.a < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag -((regs.a^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + uint8 m; + READ_ZP_X_WB(m); + OP_TST_HANDLER(m); + WRITE_BACK(m); } -static void OpB2(void) // SBCA ABS +static void Op7D(void) // TST ABS { - tmp = regs.RdMem(FetchW()); uint8 as = regs.a; - regs.a = regs.a - tmp - (regs.cc&0x01); - (as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint8 m; + READ_ABS_WB(m); + OP_TST_HANDLER(m); + WRITE_BACK(m); } -static void OpB4(void) // ANDA ABS +static void Op4D(void) // TSTA { - regs.a &= regs.RdMem(FetchW()); - regs.cc &= 0xFD; // Cleregs.a oVerflow flag - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + OP_TST_HANDLER(regs.a); } -static void OpB5(void) // BITA ABS +static void Op5D(void) // TSTB { - tmp = regs.a & regs.RdMem(FetchW()); - regs.cc &= 0xFD; // Cleregs.a oVerflow flag - (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + OP_TST_HANDLER(regs.b); } -static void OpB6(void) // LDAA ABS +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Compare Index Register |CPX |8C 3 3|9C 4 2|AC 6 2|BC 5 3| |Formula 1 | 7T8 | +*/ + +// CPX opcodes + +/* +Compare sets flags as if a subtraction had been carried out. If the value in the X register is equal or greater than the compared value, the Carry will be set. The equal (Z) and sign (S) flags will be set based on equality or lack thereof and the sign (i.e. X>=$8000) of the X register. +*/ + +#define OP_CPX_HANDLER(m) \ + uint32 result = regs.x - (m); \ + SET_ZNVC_CMP16(m, regs.x, result) + +static void Op8C(void) // CPX # { - regs.a = regs.RdMem(FetchW()); - regs.cc &= 0xFD; // CLV - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint16 m = READ_IMM16; + OP_CPX_HANDLER(m); } -static void OpB7(void) // STAA ABS +static void Op9C(void) // CPX ZP { - regs.WrMem(FetchW(), regs.a); - regs.cc &= 0xFD; // CLV - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint16 m = READ_ZP16; + OP_CPX_HANDLER(m); } -static void OpB8(void) // EORA ABS +static void OpAC(void) // CPX ZP, X { - regs.a ^= regs.RdMem(FetchW()); - regs.cc &= 0xFD; // CLV - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint16 m = READ_ZP_X16; + OP_CPX_HANDLER(m); } -static void OpB9(void) // ADCA ABS +static void OpBC(void) // CPX ABS { - tmp = regs.RdMem(FetchW()); - addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.a = addr; // Set accumulator - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + uint16 m = READ_ABS16; + OP_CPX_HANDLER(m); } -static void OpBA(void) // ORAA ABS +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Decrement Index Register|DEX | | | | |09 4 1|X=X-1 | T | +Dec Stack Pointer |DES | | | | |34 4 1|SP=SP-1 | | +Inc Index Regster |INX | | | | |08 4 1|X=X+1 | T | +Inc Stack Pointer |INS | | | | |31 4 1|SP=SP+1 | | +*/ + +static void Op09(void) // DEX { - regs.a |= regs.RdMem(FetchW()); - regs.cc &= 0xFD; // CLV - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.x--; + SET_Z(regs.x); } -static void OpBB(void) // ADDA ABS -{ - tmp = regs.RdMem(FetchW()); - addr = (uint16)regs.a + (uint16)tmp; - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo - regs.a = addr & 0xFF; // Set accumulator - (regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +static void Op34(void) // DES +{ + regs.s--; } -static void OpBC(void) // CPX ABS +static void Op08(void) // INX { - addr = FetchW(); uint16 addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - uint16 dw = regs.x - addr2; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.x < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.x^addr2^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.x++; + SET_Z(regs.x); } -static void OpBD(void) // JSR ABS +static void Op31(void) // INS { - addr = FetchW(); + regs.s++; +} - regs.s -= 2; - WrMemW(regs.s, regs.pc); +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Load Index Register |LDX |CE 3 3|DE 4 2|EE 6 2|FE 5 3| |Formula 2 | 9TR | +Load Stack Pointer |LDS |8E 3 3|9E 4 2|AE 6 2|BE 5 3| |Formula 3 | 9TR | +*/ - regs.pc = addr; // Go to absolute address (Not indir) -} +// LD* opcode handler + +#define OP_LD_HANDLER(acc) \ + SET_N16(acc); \ + SET_Z(acc); \ + CLR_V -static void OpBE(void) // LDS ABS +static void OpCE(void) // LDX # { - addr = FetchW(); - regs.s = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); - regs.cc &= 0xFD; // CLV - (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.x = READ_IMM16; + OP_LD_HANDLER(regs.x); } -static void OpBF(void) // STS ABS +static void OpDE(void) // LDX ZP { -addr = FetchW(); -regs.WrMem(addr, regs.s>>8); regs.WrMem(addr+1, regs.s&0xFF); -regs.cc &= 0xFD; // CLV -(regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.s&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.x = READ_ZP16; + OP_LD_HANDLER(regs.x); } -static void OpC0(void) // SUBB # -{ -tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b; -regs.b -= tmp; -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag -(bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag -((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +static void OpEE(void) // LDX ZP, X +{ + regs.x = READ_ZP_X16; + OP_LD_HANDLER(regs.x); } -static void OpC1(void) // CMPB # +static void OpFE(void) // LDX ABS { -tmp = regs.RdMem(regs.pc++); -uint8 db = regs.b - tmp; -(regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag -((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow -(db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.x = READ_ABS16; + OP_LD_HANDLER(regs.x); } -static void OpC2(void) // SBCB # +static void Op8E(void) // LDS # { - tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b; - regs.b = regs.b - tmp - (regs.cc&0x01); - (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.s = READ_IMM16; + OP_LD_HANDLER(regs.s); } -static void OpC4(void) // ANDB # +static void Op9E(void) // LDS ZP { -regs.b &= regs.RdMem(regs.pc++); -regs.cc &= 0xFD; // Cleregs.a oVerflow flag -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.s = READ_ZP16; + OP_LD_HANDLER(regs.s); } -static void OpC5(void) // BITB # +static void OpAE(void) // LDS ZP, X { - tmp = regs.b & regs.RdMem(regs.pc++); - regs.cc &= 0xF1; // CLV CLZ CLN - if (tmp == 0) regs.cc |= 0x04; // Set Zero flag - if (tmp&0x80) regs.cc |= 0x08; // Set Negative flag + regs.s = READ_ZP_X16; + OP_LD_HANDLER(regs.s); } -static void OpC6(void) // LDAB # +static void OpBE(void) // LDS ABS { - regs.b = regs.RdMem(regs.pc++); - regs.cc &= 0xF1; // CLV CLZ CLN - if (regs.b == 0) regs.cc |= 0x04; // Set Zero flag - if (regs.b&0x80) regs.cc |= 0x08; // Set Negative flag + regs.s = READ_ABS16; + OP_LD_HANDLER(regs.s); } -static void OpC8(void) // EORB # +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Store Index Register |STX | |DF 5 2|EF 7 2|FF 6 3| |Formula 4 | 9TR | +Store Stack Pointer |STS | |9F 5 2|AF 7 2|BF 6 3| |Formula 5 | 9TR | +*/ + +// ST* opcode handler + +#define OP_ST_HANDLER(m, acc) \ + regs.WrMem(m + 0, acc >> 8); \ + regs.WrMem(m + 1, acc & 0xFF); \ + SET_N16(acc); \ + SET_Z(acc); \ + CLR_V + +static void OpDF(void) // STX ZP { -regs.b ^= regs.RdMem(regs.pc++); -regs.cc &= 0xFD; // CLV -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint16 m = EA_ZP; + OP_ST_HANDLER(m, regs.x); } -static void OpC9(void) // ADCB # +static void OpEF(void) // STX ZP, X { - tmp = regs.RdMem(regs.pc++); - addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo - regs.b = addr & 0xFF; // Set accumulator - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + uint16 m = EA_ZP_X; + OP_ST_HANDLER(m, regs.x); } -static void OpCA(void) // ORAB # +static void OpFF(void) // STX ABS { -regs.b |= regs.RdMem(regs.pc++); -regs.cc &= 0xFD; // CLV -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint16 m = EA_ABS; + regs.pc += 2; + OP_ST_HANDLER(m, regs.x); } -static void OpCB(void) // ADDB # -{ - tmp = regs.RdMem(regs.pc++); addr = regs.b + tmp; - (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo - regs.b = addr & 0xFF; // Set accumulator - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +static void Op9F(void) // STS ZP +{ + uint16 m = EA_ZP; + OP_ST_HANDLER(m, regs.s); } -static void OpCE(void) // LDX # +static void OpAF(void) // STS ZP, X { - regs.x = FetchW(); - regs.cc &= 0xFD; // CLV - (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + uint16 m = EA_ZP_X; + OP_ST_HANDLER(m, regs.s); } -static void OpD0(void) // SUBB ZP -{ - tmp = regs.RdMem(regs.RdMem(regs.pc++)); uint8 bs = regs.b; - regs.b -= tmp; - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +static void OpBF(void) // STS ABS +{ + uint16 m = EA_ABS; + regs.pc += 2; + OP_ST_HANDLER(m, regs.s); } -static void OpD1(void) // CMPB ZP +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Index Reg > Stack Pnter |TXS | | | | |35 4 1|SP=X-1 | | +Stack Ptr > Index Regtr |TSX | | | | |30 4 1|X=SP+1 | | +*/ + +static void Op35(void) // TXS { - tmp = regs.RdMem(regs.RdMem(regs.pc++)); - uint8 db = regs.b - tmp; - (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.s = regs.x - 1; } -static void OpD2(void) // SBCB ZP +static void Op30(void) // TSX { - tmp = regs.RdMem(regs.RdMem(regs.pc++)); uint8 bs = regs.b; - regs.b = regs.b - tmp - (regs.cc&0x01); - (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.x = regs.s + 1; } -static void OpD4(void) // ANDB ZP +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Always |BRA | |20 4 2| | | |none | | +Carry is Clear |BCC | |24 4 2| | | |C=0 | | +Carry is Set |BCS | |25 4 2| | | |C=1 | | +Equals Zero |BEQ | |27 4 2| | | |Z=1 | | +Greater or Equal to Zero|BGE | |2C 4 2| | | |N(+)V=0 | | +Greater than Zero |BGT | |2E 4 2| | | |Z+N(+)V=0 | | +Higher |BHI | |22 4 2| | | |C+Z=0 | | +Less or Equal than Zero |BLE | |2F 4 2| | | |Z+N(+)V=1 | | +Lower or Same |BLS | |23 4 2| | | |C+Z=1 | | +Less Than Zero |BLT | |2D 4 2| | | |N(+)V=1 | | +Minus |BMI | |2B 4 2| | | |N=1 | | +Not Zero |BNE | |26 4 2| | | |Z=0 | | +Overflow Clear |BVC | |28 4 2| | | |V=0 | | +Overflow Set |BVS | |29 4 2| | | |V=1 | | +Plus |BPL | |2A 4 2| | | |N=0 | | +*/ + +static void Op20(void) // BRA { -regs.b &= regs.RdMem(regs.RdMem(regs.pc++)); -regs.cc &= 0xFD; // Clear oVerflow flag -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + int16 m = (int16)(int8)READ_IMM; + regs.pc += m; } -static void OpD5(void) // BITB ZP +static void Op24(void) // BCC { -tmp = regs.b & regs.RdMem(regs.RdMem(regs.pc++)); -regs.cc &= 0xFD; // Clear oVerflow flag -(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + int16 m = (int16)(int8)READ_IMM; + +// if (!(regs.cc & FLAG_C)) + if (!flagC) + regs.pc += m; } -static void OpD6(void) // LDAB ZP +static void Op25(void) // BCS { - regs.b = regs.RdMem(regs.RdMem(regs.pc++)); - regs.cc &= 0xFD; // CLV - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + int16 m = (int16)(int8)READ_IMM; + +// if (regs.cc & FLAG_C) + if (flagC) + regs.pc += m; } -static void OpD7(void) // STAB ZP +static void Op27(void) // BEQ { -regs.WrMem(regs.RdMem(regs.pc++), regs.b); -regs.cc &= 0xFD; // CLV -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + int16 m = (int16)(int8)READ_IMM; + +// if (regs.cc & FLAG_Z) + if (flagZ) + regs.pc += m; } -static void OpD8(void) // EORB ZP +static void Op2C(void) // BGE { -regs.b ^= regs.RdMem(regs.RdMem(regs.pc++)); -regs.cc &= 0xFD; // CLV -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + int16 m = (int16)(int8)READ_IMM; + +// if (!(((regs.cc & FLAG_N) >> 2) ^ (regs.cc & FLAG_V))) + if (!(flagN ^ flagV)) + regs.pc += m; } -static void OpD9(void) // ADCB ZP +static void Op2E(void) // BGT { - tmp = regs.RdMem(regs.RdMem(regs.pc++)); - addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.b = addr; // Set accumulator - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + int16 m = (int16)(int8)READ_IMM; + +// if (!(((regs.cc & FLAG_Z) >> 1) | (((regs.cc & FLAG_N) >> 2) ^ (regs.cc & FLAG_V)))) + if (!(flagZ | (flagN ^ flagV))) + regs.pc += m; } -static void OpDA(void) // ORAB ZP +static void Op22(void) // BHI { -regs.b |= regs.RdMem(regs.RdMem(regs.pc++)); -regs.cc &= 0xFD; // CLV -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag -} + int16 m = (int16)(int8)READ_IMM; -static void OpDB(void) // ADDB ZP -{ - tmp = regs.RdMem(regs.RdMem(regs.pc++)); - addr = (uint16)regs.b + (uint16)tmp; - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.b = addr & 0xFF; // Set accumulator - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +// if (!(((regs.cc & FLAG_Z) >> 2) | (regs.cc & FLAG_C))) + if (!(flagZ | flagC)) + regs.pc += m; } -static void OpDE(void) // LDX ZP +static void Op2F(void) // BLE { - addr = regs.RdMem(regs.pc++); - regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); - regs.cc &= 0xFD; // CLV - (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + int16 m = (int16)(int8)READ_IMM; + +// if (((regs.cc & FLAG_Z) >> 1) | (((regs.cc & FLAG_N) >> 2) ^ (regs.cc & FLAG_V))) + if (flagZ | (flagN ^ flagV)) + regs.pc += m; } -static void OpDF(void) // STX ZP +static void Op23(void) // BLS { - addr = regs.RdMem(regs.pc++); - regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF); - regs.cc &= 0xFD; // CLV - (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag -} + int16 m = (int16)(int8)READ_IMM; -static void OpE0(void) // SUBB IDX -{ - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b; - regs.b -= tmp; - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +// if (((regs.cc & FLAG_Z) >> 2) | (regs.cc & FLAG_C)) + if (flagZ | flagC) + regs.pc += m; } -static void OpE1(void) // CMPB IDX +static void Op2D(void) // BLT { - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - uint8 db = regs.b - tmp; - (db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + int16 m = (int16)(int8)READ_IMM; + +// if (((regs.cc & FLAG_N) >> 2) ^ (regs.cc & FLAG_V)) + if (flagN ^ flagV) + regs.pc += m; } -static void OpE2(void) // SBCB IDX +static void Op2B(void) // BMI { - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b; - regs.b = regs.b - tmp - (regs.cc&0x01); - (bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + int16 m = (int16)(int8)READ_IMM; + +// if (regs.cc & FLAG_N) + if (flagN) + regs.pc += m; } -static void OpE4(void) // ANDB IDX +static void Op26(void) // BNE { -regs.b &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); -regs.cc &= 0xFD; // Clear oVerflow flag -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + int16 m = (int16)(int8)READ_IMM; + +// if (!(regs.cc & FLAG_Z)) + if (!flagZ) + regs.pc += m; } -static void OpE5(void) // BITB IDX +static void Op28(void) // BVC { -tmp = regs.b & regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); -regs.cc &= 0xFD; // Clear oVerflow flag -(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + int16 m = (int16)(int8)READ_IMM; + +// if (!(regs.cc & FLAG_V)) + if (!flagV) + regs.pc += m; } -static void OpE6(void) // LDB IDX +static void Op29(void) // BVS { -regs.b = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); -regs.cc &= 0xFD; // CLV -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + int16 m = (int16)(int8)READ_IMM; + +// if (regs.cc & FLAG_V) + if (flagV) + regs.pc += m; } -static void OpE7(void) // STB IDX +static void Op2A(void) // BPL { - regs.WrMem(DecodeIDX(regs.RdMem(regs.pc++)), regs.b); - regs.cc &= 0xF1; // CLV CLZ CLN - if (regs.b == 0) regs.cc |= 0x04; // Adjust Zero flag - if (regs.b&0x80) regs.cc |= 0x08; // Adjust Negative flag + int16 m = (int16)(int8)READ_IMM; + +// if (!(regs.cc & FLAG_N)) + if (!flagN) + regs.pc += m; } -static void OpE8(void) // EORB IDX +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Branch to Subroutine |BSR | |8D 8 2| | | | | | +Jump |JMP | | |6E 4 2|7E 3 3| | | | +Jump to Subroutine |JSR | | |AD 8 2|BD 9 3| | | | +*/ + +static void Op8D(void) // BSR { -regs.b ^= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); -regs.cc &= 0xFD; // CLV -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + int16 m = (int16)(int8)READ_IMM; + PUSH16(regs.pc); + regs.pc += m; } -static void OpE9(void) // ADCB IDX +static void Op6E(void) // JMP ZP, X { - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.b = addr; // Set accumulator - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + regs.pc = EA_ZP_X; } -static void OpEA(void) // ORB IDX +static void Op7E(void) // JMP ABS { -regs.b |= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); -regs.cc &= 0xFD; // CLV -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.pc = EA_ABS; } -static void OpEB(void) // ADDB IDX -{ - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - addr = (uint16)regs.b + (uint16)tmp; - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.b = addr; // Set accumulator - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +static void OpAD(void) // JSR ZP, X +{ + uint16 m = EA_ZP_X; + PUSH16(regs.pc); + regs.pc = m; } -static void OpEE(void) // LDX IDX +static void OpBD(void) // JSR ABS { - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); - regs.cc &= 0xF1; // CLV CLZ CLN - if (regs.x == 0) regs.cc |= 0x04; // Set Zero flag - if (regs.x&0x8000) regs.cc |= 0x08; // Set Negative flag + uint16 m = EA_ABS; + regs.pc += 2; + PUSH16(regs.pc); + regs.pc = m; } -static void OpEF(void) // STX IDX +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +No Operation |NOP | | | | |01 2 1| | | +Return from Interrupt |RTI | | | | |3B A 1| |AAAAAA| +Return from Subroutine |RTS | | | | |39 5 1| | | +Software Interrupt |SWI | | | | |3F C 1| | S | +Wait For Interrupt |WAI | | | | |3E 9 1| | B | +*/ + +static void Op01(void) // NOP { - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF); - regs.cc &= 0xF1; // CLV CLZ CLN - if (regs.x == 0) regs.cc |= 0x04; // Set Zero flag - if (regs.x&0x8000) regs.cc |= 0x08; // Set Negative flag } -static void OpF0(void) // SUBB ABS -{ -tmp = regs.RdMem(FetchW()); uint8 bs = regs.b; -regs.b -= tmp; -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag -(bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag -((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow +static void Op3B(void) // RTI +{ + regs.cc = PULL; + regs.a = PULL; + regs.b = PULL; + regs.x = PULL16; + regs.pc = PULL16; + UNPACK_FLAGS; } -static void OpF1(void) // CMPB ABS +static void Op39(void) // RTS { -tmp = regs.RdMem(FetchW()); -uint8 db = regs.b - tmp; -(db == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(db&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag -(regs.b < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag -((regs.b^tmp^db^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + regs.pc = PULL16; } -static void OpF2(void) // SBCB ABS +static void Op3F(void) // SWI { - tmp = regs.RdMem(FetchW()); uint8 bs = regs.b; - regs.b = regs.b - tmp - (regs.cc&0x01); - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (bs < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow + // It seems that the SWI is non-maskable, unlike the IRQ... + regs.cc = PACK_FLAGS; // Mash flags back into the CC register + PUSH16(regs.pc); // Save all regs... + PUSH16(regs.x); + PUSH(regs.b); + PUSH(regs.a); + PUSH(regs.cc); + regs.pc = RdMemW(0xFFFA); // And do it! +// regs.cc |= FLAG_I; // Also, set IRQ inhibit + flagI = 1; // Also, set IRQ inhibit } -static void OpF4(void) // ANDB ABS +static void Op3E(void) // WAI { -regs.b &= regs.RdMem(FetchW()); -regs.cc &= 0xFD; // Clear oVerflow flag -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag -} +#ifdef __DEBUG__ +WriteLog("*** WAI STATE ASSERTED ***\n"); +#endif + regs.cc = PACK_FLAGS; // Mash flags back into the CC register + PUSH16(regs.pc); // Save all regs... + PUSH16(regs.x); + PUSH(regs.b); + PUSH(regs.a); + PUSH(regs.cc); + regs.cpuFlags |= V6808_STATE_WAI; // And signal that we're in WAI mode +} + +/* +Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg| + | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC| +Clear Carry |CLC | | | | |0C 2 1|C=0 | R| +Clear Interrupt |CLI | | | | |0E 2 1|I=0 | R | +Clear Overflow |CLV | | | | |0A 2 1|V=0 | R | +Set Carry |SEC | | | | |0D 2 1|C=1 | S| +Set Interrupt |SEI | | | | |0F 2 1|I=1 | S | +Set Overflow |SEV | | | | |0B 2 1|V=1 | S | +CCR=Accumulator A |TAP | | | | |06 2 1|CCR=A |CCCCCC| +Accumlator A=CCR |TPA | | | | |07 2 1|A=CCR | | +*/ -static void OpF5(void) // BITB ABS +static void Op0C(void) // CLC { -tmp = regs.b & regs.RdMem(FetchW()); -regs.cc &= 0xFD; // Clear oVerflow flag -(tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +// regs.cc &= ~FLAG_C; + flagC = 0; } -static void OpF6(void) // LDB ABS +static void Op0E(void) // CLI { -regs.b = regs.RdMem(FetchW()); -regs.cc &= 0xFD; // CLV -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +// regs.cc &= ~FLAG_I; + flagI = 0; } -static void OpF7(void) // STB ABS +static void Op0A(void) // CLV { -regs.WrMem(FetchW(), regs.b); -regs.cc &= 0xFD; // CLV -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +// regs.cc &= ~FLAG_V; + flagV = 0; } -static void OpF8(void) // EORB ABS +static void Op0D(void) // SEC { -regs.b ^= regs.RdMem(FetchW()); -regs.cc &= 0xFD; // CLV -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +// regs.cc |= FLAG_C; + flagC = 1; } -static void OpF9(void) // ADCB ABS +static void Op0F(void) // SEI { - tmp = regs.RdMem(FetchW()); - addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo - regs.b = addr & 0xFF; // Set accumulator - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +// regs.cc |= FLAG_I; + flagI = 1; } -static void OpFA(void) // ORB ABS +static void Op0B(void) // SEV { -regs.b |= regs.RdMem(FetchW()); -regs.cc &= 0xFD; // CLV -(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag -} - -static void OpFB(void) // ADDB ABS -{ - tmp = regs.RdMem(FetchW()); - addr = (uint16)regs.b + (uint16)tmp; - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo - regs.b = addr & 0xFF; // Set accumulator - (regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag - (regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag +// regs.cc |= FLAG_V; + flagV = 1; } -static void OpFE(void) // LDX ABS +static void Op06(void) // TAP { -addr = FetchW(); -regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); -regs.cc &= 0xFD; // CLV -(regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + regs.cc = regs.a; + UNPACK_FLAGS; } -static void OpFF(void) // STX ABS +static void Op07(void) // TPA { -addr = FetchW(); -regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF); -regs.cc &= 0xFD; // CLV -(regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag -(regs.x&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag -} +// regs.a = regs.cc; + regs.a = PACK_FLAGS; +} + +/* + OP Operation Code, in Hexadecimal + ~ Number of MPU cycles required + # Number of program bytes required + + Arithmetic Plus + - Arithmetic Minus + + Boolean AND + Msp Contents of Memory pointed to be Stack Pointer + + Boolean Inclusive OR + (+) Boolean Exclusive OR (XOR) + * Converts Binary Addition of BCD Characters into BCD Format + *- SP=SP-1 + *+ SP=SP+1 + + Condition Code Register Legend + Not Affected + R Reset (0, Low) + S Set (1, High) + T Tests and sets if True, cleared otherise + 1 Test: Result=10000000? + 2 Test: Result=00000000? + 3 Test: Decimal value of most significant BCD character greater than nine? + (Not cleared if previously set) + 4 Test: Operand=10000000 prior to execution? + 5 Test: Operand=01111111 prior to execution? + 6 Test: Set equal to result or N(+)C after shift has occurred. + 7 Test: Sign bit of most significant byte or result=1? + 8 Test: 2's compliment overflow from subtraction of least + significant bytes? + 9 Test: Result less than zero? (Bit 15=1) + A Load Condition Code Register from Stack. + B Set when interrupt occurs. If previously set, a NMI is + required to exit the wait state. + C Set according to the contents of Accumulator A. + + *x SHIFT AND ROTATION DIAGRAMS + *1 +-----------------+ C to LSB + - C <- 76543210 <-+ + + *2 +-----------------+ + +> C -> 76543210 -+ + + *3 C <- 76543210 <- 0(Data) + +-+ + + *4 À>76543210 -> C + + *5 (Data)0 -> 76543210 -> C + + FORMULAS + 1: (Xh/Xl)-(M/M+1) + 2: Xh=M, Xl=M+1 + 3: SPh=M, SPl=M+1 + 4: M=Xh, M+1=Xl +*/ static void Op__(void) { @@ -1842,49 +2091,66 @@ static void myMemcpy(void * dst, void * src, uint32 size) d[i] = s[i]; } +#ifdef __DEBUG__ //int instCount[256]; +static bool logGo = false; +#endif // // Function to execute 6808 for "cycles" cycles // void Execute6808(V6808REGS * context, uint32 cycles) { +#warning V6808_STATE_WAI is not properly handled yet! + myMemcpy(®s, context, sizeof(V6808REGS)); + UNPACK_FLAGS; // Explode flags register into individual uint8s // Execute here... while (regs.clock < cycles) { #ifdef __DEBUG__ -Decode6808(regs.pc); +if (logGo) + Decode6808(regs.pc); #endif uint8 opcode = regs.RdMem(regs.pc++); +#ifdef __DEBUG__ //if (!(regs.cpuFlags & V6808_STATE_ILLEGAL_INST)) //instCount[opcode]++; +#endif - exec_op[opcode](); // Execute that opcode... + exec_op[opcode](); // Execute that opcode... regs.clock += CPUCycles[opcode]; #ifdef __DEBUG__ -WriteLog(" [PC=%04X, S=%04X, X=%04X, A=%02X, B=%02X, CC=%02X]\n", regs.pc, regs.s, regs.x, regs.a, regs.b, regs.cc); +if (logGo) +// WriteLog(" [PC=%04X, S=%04X, X=%04X, A=%02X, B=%02X, CC=%s%s%s%s%s%s%s%s]\n", regs.pc, regs.s, regs.x, regs.a, regs.b, (regs.cc & FLAG_E ? "E" : " "), (regs.cc & FLAG_F ? "F" : " "), (regs.cc & FLAG_H ? "H" : " "), (regs.cc & FLAG_I ? "I" : " "), (regs.cc & FLAG_N ? "N" : " "), (regs.cc & FLAG_Z ? "Z" : " "), (regs.cc & FLAG_V ? "V" : " "), (regs.cc & FLAG_C ? "C" : " ")); + WriteLog(" [PC=%04X, S=%04X, X=%04X, A=%02X, B=%02X, CC=%s%s%s%s%s%s%s%s]\n", regs.pc, regs.s, regs.x, regs.a, regs.b, (regs.cc & FLAG_E ? "E" : " "), (regs.cc & FLAG_F ? "F" : " "), (flagH ? "H" : " "), (flagI ? "I" : " "), (flagN ? "N" : " "), (flagZ ? "Z" : " "), (flagV ? "V" : " "), (flagC ? "C" : " ")); #endif if (regs.cpuFlags & V6808_ASSERT_LINE_RESET) { - regs.cc |= FLAG_I; // Set I - regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector +#ifdef __DEBUG__ +WriteLog("*** RESET LINE ASSERTED ***\n"); +#endif +// regs.cc |= FLAG_I; // Set I + flagI = 1; // Set I + regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector context->cpuFlags &= ~V6808_ASSERT_LINE_RESET; regs.cpuFlags &= ~V6808_ASSERT_LINE_RESET; } else if (regs.cpuFlags & V6808_ASSERT_LINE_NMI) { - regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs... - regs.WrMem(--regs.s, regs.pc >> 8); - regs.WrMem(--regs.s, regs.x & 0xFF); - regs.WrMem(--regs.s, regs.x >> 8); - regs.WrMem(--regs.s, regs.b); - regs.WrMem(--regs.s, regs.a); - regs.WrMem(--regs.s, regs.cc); - regs.pc = RdMemW(0xFFFC); // And do it! +#ifdef __DEBUG__ +WriteLog("*** NMI LINE ASSERTED ***\n"); +#endif + regs.cc = PACK_FLAGS; // Mash flags back into the CC register + PUSH16(regs.pc); // Save all regs... + PUSH16(regs.x); + PUSH(regs.b); + PUSH(regs.a); + PUSH(regs.cc); + regs.pc = RdMemW(0xFFFC); // And do it! regs.clock += 0; // How many??? context->cpuFlags &= ~V6808_ASSERT_LINE_NMI;// Reset the asserted line (NMI)... @@ -1892,24 +2158,32 @@ WriteLog(" [PC=%04X, S=%04X, X=%04X, A=%02X, B=%02X, CC=%02X]\n", regs.pc, regs. } else if (regs.cpuFlags & V6808_ASSERT_LINE_IRQ) { - if (!(regs.cc & FLAG_I)) // Process an interrupt (I=0)? +#ifdef __DEBUG__ +WriteLog("*** IRQ LINE ASSERTED ***\n"); +#endif +// if (!(regs.cc & FLAG_I)) // Process an interrupt (I=0)? + if (!flagI) // Process an interrupt (I=0)? { - regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs... - regs.WrMem(--regs.s, regs.pc >> 8); - regs.WrMem(--regs.s, regs.x & 0xFF); - regs.WrMem(--regs.s, regs.x >> 8); - regs.WrMem(--regs.s, regs.b); - regs.WrMem(--regs.s, regs.a); - regs.WrMem(--regs.s, regs.cc); - regs.pc = RdMemW(0xFFF8); // And do it! - - regs.clock += 0; // How many??? +#ifdef __DEBUG__ +WriteLog(" IRQ TAKEN!\n"); +logGo = true; +#endif + regs.cc = PACK_FLAGS; // Mash flags back into the CC register + PUSH16(regs.pc); // Save all regs... + PUSH16(regs.x); + PUSH(regs.b); + PUSH(regs.a); + PUSH(regs.cc); + regs.pc = RdMemW(0xFFF8); // And do it! + + regs.clock += 0; // How many??? context->cpuFlags &= ~V6808_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)... regs.cpuFlags &= ~V6808_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)... } } } + regs.cc = PACK_FLAGS; // Mash flags back into the CC register myMemcpy(context, ®s, sizeof(V6808REGS)); } diff --git a/src/v6808.h b/src/v6808.h index a3d6d90..ec19a63 100755 --- a/src/v6808.h +++ b/src/v6808.h @@ -3,7 +3,7 @@ // // by James L. Hammons // -// (c) 2004 Underground Software +// (C) 2006 Underground Software // #ifndef __V6808_H__ @@ -13,9 +13,8 @@ // Useful defines -#define FLAG_E 0x80 // ??? Entire ??? -#define FLAG_F 0x40 // ??? Fast IRQ ??? - +#define FLAG_E 0x80 // ??? Entire ??? [No.] +#define FLAG_F 0x40 // ??? Fast IRQ ??? [No.] #define FLAG_H 0x20 // Half carry #define FLAG_I 0x10 // IRQ #define FLAG_N 0x08 // Negative @@ -26,7 +25,7 @@ #define V6808_ASSERT_LINE_RESET 0x0001 // v6808 RESET line #define V6808_ASSERT_LINE_IRQ 0x0002 // v6808 IRQ line #define V6808_ASSERT_LINE_NMI 0x0004 // v6808 NMI line -#define V6808_STATE_SYNC 0x0008 // ??? v6808 SYNC line ??? +#define V6808_STATE_WAI 0x0008 // v6808 wait for IRQ line #define V6808_STATE_ILLEGAL_INST 0x0010 // Illegal instruction executed flag //#define V6809_START_DEBUG_LOG 0x0020 // Debug log go (temporary!) @@ -41,7 +40,6 @@ struct V6808REGS uint8 a; // 6808 A register uint8 b; // 6808 B register uint32 clock; // 6808 clock -//uint32 _reserved;// uint8 (* Fetch)(uint16&); // Address of uint8 fetch routine uint8 (* RdMem)(uint16); // Address of uint8 read routine void (* WrMem)(uint16, uint8); // Address of uint8 write routine uint32 cpuFlags; // v6808 IRQ/RESET flags @@ -49,7 +47,8 @@ struct V6808REGS // Function prototypes -void Execute6808(V6808REGS *, uint32); // Function to execute 6808 instructions +void Execute6808(V6808REGS *, uint32); // Function to execute 6808 instructions uint32 GetCurrentV6808Clock(void); // Get the clock of the currently executing CPU +//uint8 GetCCRegister(void); // Hmm. #endif // __V6808_H__ diff --git a/src/v6809.cpp b/src/v6809.cpp index 494b9f1..648d02b 100755 --- a/src/v6809.cpp +++ b/src/v6809.cpp @@ -10,11 +10,15 @@ // --- ---------- ------------------------------------------------------------ // JLH 06/15/2006 Added changelog ;-) // JLH 06/15/2006 Scrubbed all BYTE, WORD & DWORD references from the code +// JLH 11/11/2006 Removed all SignedX() references // // Mebbe someday I'll get around to fixing the core to be more like V65C02... +// We have a start... ;-) // +#define __DEBUG__ + #include "v6809.h" #ifdef __DEBUG__ @@ -22,16 +26,69 @@ #include "log.h" // Temporary... #endif +// Various macros + +#define CLR_Z (regs.cc &= ~FLAG_Z) +#define CLR_ZN (regs.cc &= ~(FLAG_Z | FLAG_N)) +#define CLR_ZNC (regs.cc &= ~(FLAG_Z | FLAG_N | FLAG_C)) +#define CLR_V (regs.cc &= ~FLAG_V) +#define CLR_N (regs.cc &= ~FLAG_N) +#define SET_Z(r) (regs.cc = ((r) == 0 ? regs.cc | FLAG_Z : regs.cc & ~FLAG_Z)) +#define SET_N(r) (regs.cc = ((r) & 0x80 ? regs.cc | FLAG_N : regs.cc & ~FLAG_N)) + +//Not sure that this code is computing the carry correctly... Investigate! [Seems to be] +#define SET_C_ADD(a,b) (regs.cc = ((uint8)(b) > (uint8)(~(a)) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)) +//#define SET_C_SUB(a,b) (regs.cc = ((uint8)(b) >= (uint8)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)) +#define SET_C_CMP(a,b) (regs.cc = ((uint8)(b) >= (uint8)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)) +#define SET_ZN(r) SET_N(r); SET_Z(r) +#define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b) +//#define SET_ZNC_SUB(a,b,r) SET_N(r); SET_Z(r); SET_C_SUB(a,b) +#define SET_ZNC_CMP(a,b,r) SET_N(r); SET_Z(r); SET_C_CMP(a,b) + +//Small problem with the EA_ macros: ABS macros don't increment the PC!!! !!! FIX !!! +#define EA_IMM regs.pc++ +#define EA_ZP regs.RdMem(regs.pc++) +#define EA_ZP_X (regs.RdMem(regs.pc++) + regs.x) & 0xFF +#define EA_ZP_Y (regs.RdMem(regs.pc++) + regs.y) & 0xFF +#define EA_ABS RdMemW(regs.pc) +#define EA_ABS_X RdMemW(regs.pc) + regs.x +#define EA_ABS_Y RdMemW(regs.pc) + regs.y +#define EA_IND_ZP_X RdMemW((regs.RdMem(regs.pc++) + regs.x) & 0xFF) +#define EA_IND_ZP_Y RdMemW(regs.RdMem(regs.pc++)) + regs.y +#define EA_IND_ZP RdMemW(regs.RdMem(regs.pc++)) + +#define READ_IMM regs.RdMem(EA_IMM) +#define READ_ZP regs.RdMem(EA_ZP) +#define READ_ZP_X regs.RdMem(EA_ZP_X) +#define READ_ZP_Y regs.RdMem(EA_ZP_Y) +#define READ_ABS regs.RdMem(EA_ABS); regs.pc += 2 +#define READ_ABS_X regs.RdMem(EA_ABS_X); regs.pc += 2 +#define READ_ABS_Y regs.RdMem(EA_ABS_Y); regs.pc += 2 +#define READ_IND_ZP_X regs.RdMem(EA_IND_ZP_X) +#define READ_IND_ZP_Y regs.RdMem(EA_IND_ZP_Y) +#define READ_IND_ZP regs.RdMem(EA_IND_ZP) + +#define READ_IMM_WB(v) uint16 addr = EA_IMM; v = regs.RdMem(addr) +#define READ_ZP_WB(v) uint16 addr = EA_ZP; v = regs.RdMem(addr) +#define READ_ZP_X_WB(v) uint16 addr = EA_ZP_X; v = regs.RdMem(addr) +#define READ_ABS_WB(v) uint16 addr = EA_ABS; v = regs.RdMem(addr); regs.pc += 2 +#define READ_ABS_X_WB(v) uint16 addr = EA_ABS_X; v = regs.RdMem(addr); regs.pc += 2 +#define READ_ABS_Y_WB(v) uint16 addr = EA_ABS_Y; v = regs.RdMem(addr); regs.pc += 2 +#define READ_IND_ZP_X_WB(v) uint16 addr = EA_IND_ZP_X; v = regs.RdMem(addr) +#define READ_IND_ZP_Y_WB(v) uint16 addr = EA_IND_ZP_Y; v = regs.RdMem(addr) +#define READ_IND_ZP_WB(v) uint16 addr = EA_IND_ZP; v = regs.RdMem(addr) + +#define WRITE_BACK(d) regs.WrMem(addr, (d)) + // Private global variables static V6809REGS regs; +//Let's see if we can nuke this shit. static uint16 addr; // Temporary variables common to all funcs... static uint8 tmp; // Private function prototypes -static int SignedB(uint8); // Return signed byte from unsigned -static int SignedW(uint16); // Return signed word from unsigned static uint16 FetchW(void); static uint16 RdMemW(uint16 addr); static void WrMemW(uint16 addr, uint16 w); @@ -186,22 +243,6 @@ void WrMemW(uint16 addr, uint16 w) regs.WrMem(addr + 1, w & 0xFF); } -// -// return signed byte from unsigned -// -int SignedB(uint8 b) -{ - return (b & 0x80 ? b - 256 : b); -} - -// -// return signed word from unsigned -// -int SignedW(uint16 w) -{ - return (w & 0x8000 ? w - 65536 : w); -} - // // Function to read TFR/EXG post byte // @@ -343,31 +384,38 @@ uint16 DecodeIDX(uint8 code) addr = RdMemW(woff); break; case 5: - woff = DecodeReg(reg) + SignedB(regs.b); +// woff = DecodeReg(reg) + SignedB(regs.b); + woff = DecodeReg(reg) + (int16)(int8)regs.b; addr = RdMemW(woff); break; case 6: - woff = DecodeReg(reg) + SignedB(regs.a); +// woff = DecodeReg(reg) + SignedB(regs.a); + woff = DecodeReg(reg) + (int16)(int8)regs.a; addr = RdMemW(woff); break; case 8: - woff = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++)); +// woff = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++)); + woff = DecodeReg(reg) + (int16)(int8)regs.RdMem(regs.pc++); addr = RdMemW(woff); break; case 9: - woff = DecodeReg(reg) + SignedW(FetchW()); +// woff = DecodeReg(reg) + SignedW(FetchW()); + woff = DecodeReg(reg) + FetchW(); addr = RdMemW(woff); break; case 11: - woff = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b); +// woff = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b); + woff = DecodeReg(reg) + ((regs.a << 8) | regs.b); addr = RdMemW(woff); break; case 12: - woff = regs.pc + SignedB(regs.RdMem(regs.pc++)); +// woff = regs.pc + SignedB(regs.RdMem(regs.pc++)); + woff = regs.pc + (int16)(int8)regs.RdMem(regs.pc++); addr = RdMemW(woff); break; case 13: - woff = regs.pc + SignedW(FetchW()); +// woff = regs.pc + SignedW(FetchW()); + woff = regs.pc + FetchW(); addr = RdMemW(woff); break; case 15: @@ -417,13 +465,20 @@ uint16 DecodeIDX(uint8 code) } addr = DecodeReg(reg); break; } case 4: { addr = DecodeReg(reg); break; } - case 5: { addr = DecodeReg(reg) + SignedB(regs.b); break; } - case 6: { addr = DecodeReg(reg) + SignedB(regs.a); break; } - case 8: { addr = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++)); break; } - case 9: { addr = DecodeReg(reg) + SignedW(FetchW()); break; } - case 11: { addr = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b); break; } - case 12: { addr = regs.pc + SignedB(regs.RdMem(regs.pc++)); break; } - case 13: { addr = regs.pc + SignedW(FetchW()); break; } +// case 5: { addr = DecodeReg(reg) + SignedB(regs.b); break; } + case 5: { addr = DecodeReg(reg) + (int16)(int8)regs.b; break; } +// case 6: { addr = DecodeReg(reg) + SignedB(regs.a); break; } + case 6: { addr = DecodeReg(reg) + (int16)(int8)regs.a; break; } +// case 8: { addr = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++)); break; } + case 8: { addr = DecodeReg(reg) + (int16)(int8)regs.RdMem(regs.pc++); break; } +// case 9: { addr = DecodeReg(reg) + SignedW(FetchW()); break; } + case 9: { addr = DecodeReg(reg) + FetchW(); break; } +// case 11: { addr = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b); break; } + case 11: { addr = DecodeReg(reg) + ((regs.a << 8) | regs.b); break; } +// case 12: { addr = regs.pc + SignedB(regs.RdMem(regs.pc++)); break; } + case 12: { addr = regs.pc + (int16)(int8)regs.RdMem(regs.pc++); break; } +// case 13: { addr = regs.pc + SignedW(FetchW()); break; } + case 13: { addr = regs.pc + FetchW(); break; } } } } @@ -565,32 +620,41 @@ static void Op10(void) // Page 1 opcode exec_op1[regs.RdMem(regs.pc++)](); } -static void Op11(void) // Page 2 opcode +static void Op11(void) // Page 2 opcode { exec_op2[regs.RdMem(regs.pc++)](); } -static void Op12(void) // NOP +static void Op12(void) // NOP { regs.clock += 2; } -static void Op13(void) // SYNC -{ - regs.clock += 2; +static void Op13(void) // SYNC +{ + // Fix this so it does the right thing (software interrupt!) + regs.clock += 2; } -static void Op16(void) // LBRA + +static void Op16(void) // LBRA { - regs.pc += SignedW(FetchW()); - regs.clock += 5; +// regs.pc += SignedW(FetchW()); + regs.pc += FetchW(); // No need to make signed, both are 16 bit quantities + + regs.clock += 5; } -static void Op17(void) // LBSR + +static void Op17(void) // LBSR { - addr = FetchW(); - regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); - regs.pc += SignedW(addr); - regs.clock += 9; + uint16 word = FetchW(); + regs.WrMem(--regs.s, regs.pc & 0xFF); + regs.WrMem(--regs.s, regs.pc >> 8); +// regs.pc += SignedW(addr); + regs.pc += word; // No need to make signed, both are 16 bit + + regs.clock += 9; } + static void Op19(void) // DAA { if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09)) // H set or lo nyb too big? @@ -621,7 +685,7 @@ static void Op1C(void) // ANDCC # regs.clock += 3; } -static void Op1D(void) // SEX +static void Op1D(void) // SEX { (regs.b & 0x80 ? regs.a = 0xFF : regs.a = 0x00); @@ -631,7 +695,7 @@ static void Op1D(void) // SEX regs.clock += 2; } -static void Op1E(void) // EXG +static void Op1E(void) // EXG { tmp = regs.RdMem(regs.pc++); addr = ReadEXG(tmp >> 4); @@ -647,100 +711,162 @@ static void Op1F(void) // TFR WriteEXG(tmp&0xF, ReadEXG(tmp>>4)); regs.clock += 7; } -static void Op20(void) // BRA + +static void Op20(void) // BRA { - regs.pc += SignedB(regs.RdMem(regs.pc++)); // Branch always - regs.clock += 3; +// regs.pc += SignedB(regs.RdMem(regs.pc++)); // Branch always + regs.pc += (int16)(int8)regs.RdMem(regs.pc) + 1; // Branch always + + regs.clock += 3; } -static void Op21(void) // BRN + +static void Op21(void) // BRN { - regs.RdMem(regs.pc++); - regs.clock += 3; + regs.RdMem(regs.pc++); + + regs.clock += 3; } -static void Op22(void) // BHI + +static void Op22(void) // BHI { - tmp = regs.RdMem(regs.pc++); - if (!(regs.cc&0x05)) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (!(regs.cc & 0x05)) + regs.pc += word; + + regs.clock += 3; } -static void Op23(void) // BLS + +static void Op23(void) // BLS { - tmp = regs.RdMem(regs.pc++); - if (regs.cc&0x05) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (regs.cc & 0x05) + regs.pc += word; + + regs.clock += 3; } -static void Op24(void) // BCC (BHS) + +static void Op24(void) // BCC (BHS) { - tmp = regs.RdMem(regs.pc++); - if (!(regs.cc&0x01)) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (!(regs.cc & 0x01)) + regs.pc += word; + + regs.clock += 3; } -static void Op25(void) // BCS (BLO) + +static void Op25(void) // BCS (BLO) { - tmp = regs.RdMem(regs.pc++); - if (regs.cc&0x01) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (regs.cc & 0x01) + regs.pc += word; + + regs.clock += 3; } -static void Op26(void) // BNE + +static void Op26(void) // BNE { - tmp = regs.RdMem(regs.pc++); - if (!(regs.cc&0x04)) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (!(regs.cc & 0x04)) + regs.pc += word; + + regs.clock += 3; } -static void Op27(void) // BEQ + +static void Op27(void) // BEQ { - tmp = regs.RdMem(regs.pc++); - if (regs.cc&0x04) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (regs.cc & 0x04) + regs.pc += word; + + regs.clock += 3; } -static void Op28(void) // BVC + +static void Op28(void) // BVC { - tmp = regs.RdMem(regs.pc++); - if (!(regs.cc&0x02)) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (!(regs.cc & 0x02)) + regs.pc += word; + + regs.clock += 3; } -static void Op29(void) // BVS + +static void Op29(void) // BVS { - tmp = regs.RdMem(regs.pc++); - if (regs.cc&0x02) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (regs.cc & 0x02) + regs.pc += word; + + regs.clock += 3; } -static void Op2A(void) // BPL + +static void Op2A(void) // BPL { - tmp = regs.RdMem(regs.pc++); - if (!(regs.cc&0x08)) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (!(regs.cc & 0x08)) + regs.pc += word; + + regs.clock += 3; } -static void Op2B(void) // BMI + +static void Op2B(void) // BMI { - tmp = regs.RdMem(regs.pc++); - if (regs.cc&0x08) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (regs.cc & 0x08) + regs.pc += word; + + regs.clock += 3; } -static void Op2C(void) // BGE + +static void Op2C(void) // BGE { - tmp = regs.RdMem(regs.pc++); - if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))) + regs.pc += word; + + regs.clock += 3; } -static void Op2D(void) // BLT + +static void Op2D(void) // BLT { - tmp = regs.RdMem(regs.pc++); - if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)) + regs.pc += word; + + regs.clock += 3; } -static void Op2E(void) // BGT + +static void Op2E(void) // BGT { - tmp = regs.RdMem(regs.pc++); - if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))) + regs.pc += word; + + regs.clock += 3; } -static void Op2F(void) // BLE + +static void Op2F(void) // BLE { - tmp = regs.RdMem(regs.pc++); - if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedB(tmp); - regs.clock += 3; + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + + if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))) + regs.pc += word; + + regs.clock += 3; } + static void Op30(void) // LEAX { regs.x = DecodeIDX(regs.RdMem(regs.pc++)); @@ -1394,13 +1520,17 @@ static void Op8C(void) // CMPX # (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag regs.clock += 4; } -static void Op8D(void) // Bregs.s - { - tmp = regs.RdMem(regs.pc++); - regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); - regs.pc += SignedB(tmp); - regs.clock += 7; - } + +static void Op8D(void) // Bregs.s +{ + uint16 word = (int16)(int8)regs.RdMem(regs.pc++); + regs.WrMem(--regs.s, regs.pc & 0xFF); + regs.WrMem(--regs.s, regs.pc >> 8); + regs.pc += word; + + regs.clock += 7; +} + static void Op8E(void) // LDX # { regs.x = FetchW(); @@ -2445,95 +2575,153 @@ static void OpFF(void) // STU ABS // Page one opcodes' execute code // -static void Op1021(void) // LBRN +static void Op1021(void) // LBRN { - addr = FetchW(); - regs.clock += 5; + addr = FetchW(); + + regs.clock += 5; } -static void Op1022(void) // LBHI + +static void Op1022(void) // LBHI { - addr = FetchW(); - if (!((regs.cc&0x01)|(regs.cc&0x04))) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (!((regs.cc & 0x01) | (regs.cc & 0x04))) + regs.pc += word; + + regs.clock += 5; } -static void Op1023(void) // LBLS + +static void Op1023(void) // LBLS { - addr = FetchW(); - if ((regs.cc&0x01)|(regs.cc&0x04)) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if ((regs.cc & 0x01) | (regs.cc & 0x04)) + regs.pc += word; + + regs.clock += 5; } -static void Op1024(void) // LBCC (LBHS) + +static void Op1024(void) // LBCC (LBHS) { - addr = FetchW(); - if (!(regs.cc&0x01)) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (!(regs.cc & 0x01)) + regs.pc += word; + + regs.clock += 5; } -static void Op1025(void) // LBCS (LBLO) + +static void Op1025(void) // LBCS (LBLO) { - addr = FetchW(); - if (regs.cc&0x01) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (regs.cc & 0x01) + regs.pc += word; + + regs.clock += 5; } -static void Op1026(void) // LBNE + +static void Op1026(void) // LBNE { - addr = FetchW(); - if (!(regs.cc&0x04)) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (!(regs.cc & 0x04)) + regs.pc += word; + + regs.clock += 5; } -static void Op1027(void) // LBEQ + +static void Op1027(void) // LBEQ { - addr = FetchW(); - if (regs.cc&0x04) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (regs.cc & 0x04) + regs.pc += word; + + regs.clock += 5; } -static void Op1028(void) // LBVC + +static void Op1028(void) // LBVC { - addr = FetchW(); - if (!(regs.cc&0x02)) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (!(regs.cc & 0x02)) + regs.pc += word; + + regs.clock += 5; } -static void Op1029(void) // LBVS + +static void Op1029(void) // LBVS { - addr = FetchW(); - if (regs.cc&0x02) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (regs.cc & 0x02) + regs.pc += word; + + regs.clock += 5; } -static void Op102A(void) // LBPL + +static void Op102A(void) // LBPL { - addr = FetchW(); - if (!(regs.cc&0x08)) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (!(regs.cc & 0x08)) + regs.pc += word; + + regs.clock += 5; } -static void Op102B(void) // LBMI + +static void Op102B(void) // LBMI { - addr = FetchW(); - if (regs.cc&0x08) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (regs.cc & 0x08) + regs.pc += word; + + regs.clock += 5; } -static void Op102C(void) // LBGE + +static void Op102C(void) // LBGE { - addr = FetchW(); - if (!(((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))) + regs.pc += word; + + regs.clock += 5; } -static void Op102D(void) // LBLT + +static void Op102D(void) // LBLT { - addr = FetchW(); - if (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)) + regs.pc += word; + + regs.clock += 5; } -static void Op102E(void) // LBGT + +static void Op102E(void) // LBGT { - addr = FetchW(); - if (!((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02)))) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))) + regs.pc += word; + + regs.clock += 5; } -static void Op102F(void) // LBLE + +static void Op102F(void) // LBLE { - addr = FetchW(); - if ((regs.cc&0x04) | (((regs.cc&0x08) >> 2) ^ (regs.cc&0x02))) regs.pc += SignedW(addr); - regs.clock += 5; + uint16 word = FetchW(); + + if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))) + regs.pc += word; + + regs.clock += 5; } + static void Op103F(void) // SWI2 (Not yet implemented) { regs.clock += 20; @@ -2846,20 +3034,24 @@ static void Op11BC(void) // CMPS ABS } //temp, for testing... -/*static uint8 backTrace[256]; +#ifdef __DEBUG__ +static uint8 backTrace[256]; static uint16 btPC[256]; static int btPtr = 0;//*/ +#endif static void Op__(void) // Illegal opcode { regs.clock++; // illegal = true; regs.cpuFlags |= V6809_STATE_ILLEGAL_INST; +#ifdef __DEBUG__ /*WriteLog("V6809: Executed illegal opcode %02X at PC=%04X...\n\nBacktrace:\n\n", regs.RdMem(regs.pc - 1), regs.pc - 1); for(int i=0; i<256; i++) { - dpc = btPC[(btPtr+i)&0xFF]; - Decode_6809(); + Decode6809(btPC[(btPtr + i) & 0xFF]); + WriteLog("\n"); }//*/ +#endif } @@ -2884,15 +3076,20 @@ void Execute6809(V6809REGS * context, uint32 cycles) // Execute here... while (regs.clock < cycles) { -/*static bool disasm = false; -if (regs.pc == 0x15BA) disasm = true; -if (disasm) { dpc = regs.pc; Decode_6809(); } -if (regs.pc == 0x164A) disasm = false;//*/ +#ifdef __DEBUG__ +//Decode6809(regs.pc); +static bool disasm = false; +/*//if (regs.pc == 0x15BA) disasm = true; +//if (regs.pc == 0xFE76) disasm = true; +if (regs.x == 0xFED4) disasm = true; +if (disasm) Decode6809(regs.pc); +//if (regs.pc == 0x164A) disasm = false;//*/ //temp, for testing... /*backTrace[btPtr] = regs.RdMem(regs.pc); btPC[btPtr] = regs.pc; -btPtr = (btPtr++) & 0xFF;//*/ +btPtr = (btPtr + 1) & 0xFF;//*/ +#endif exec_op0[regs.RdMem(regs.pc++)](); // Handle any pending interrupts @@ -2901,6 +3098,9 @@ btPtr = (btPtr++) & 0xFF;//*/ if (flags & V6809_ASSERT_LINE_RESET) // *** RESET handler *** { +#ifdef __DEBUG__ +if (disasm) WriteLog("\nV6809: RESET line asserted!\n"); +#endif regs.cc |= (FLAG_F | FLAG_I); // Set F, I regs.dp = 0; // Reset direct page register regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector @@ -2909,6 +3109,9 @@ btPtr = (btPtr++) & 0xFF;//*/ } else if (flags & V6809_ASSERT_LINE_NMI) // *** NMI handler *** { +#ifdef __DEBUG__ +if (disasm) WriteLog("\nV6809: NMI line asserted!\n"); +#endif regs.cc |= FLAG_E; // Set the Entire flag regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs... @@ -2932,8 +3135,14 @@ btPtr = (btPtr++) & 0xFF;//*/ } else if (flags & V6809_ASSERT_LINE_FIRQ) // *** FIRQ handler *** { +#ifdef __DEBUG__ +if (disasm) WriteLog("\nV6809: FIRQ line asserted!\n"); +#endif if (!(regs.cc & FLAG_F)) // Is the FIRQ masked (F == 1)? { +#ifdef __DEBUG__ +if (disasm) WriteLog(" FIRQ taken...\n"); +#endif regs.cc &= ~FLAG_E; // Clear the Entire flag regs.WrMem(--regs.s, regs.pc & 0xFF); // Save PC, CC regs... @@ -2949,8 +3158,14 @@ btPtr = (btPtr++) & 0xFF;//*/ } else if (flags & V6809_ASSERT_LINE_IRQ) // *** IRQ handler *** { +#ifdef __DEBUG__ +if (disasm) WriteLog("\nV6809: IRQ line asserted!\n"); +#endif if (!(regs.cc & FLAG_I)) // Is the IRQ masked (I == 1)? { +#ifdef __DEBUG__ +if (disasm) WriteLog(" IRQ taken...\n"); +#endif regs.cc |= FLAG_E; // Set the Entire flag regs.WrMem(--regs.s, regs.pc & 0xFF); // Save all regs... @@ -2973,8 +3188,12 @@ btPtr = (btPtr++) & 0xFF;//*/ regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)... } } -/*if (disasm) WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n", +#ifdef __DEBUG__ +if (disasm) WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n", + regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/ +/*WriteLog("\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n", regs.a, regs.b, regs.cc, regs.dp, regs.x, regs.y, regs.s, regs.u, regs.pc);//*/ +#endif } myMemcpy(context, ®s, sizeof(V6809REGS)); diff --git a/src/v6809.h b/src/v6809.h index 5a54fe6..a34c1d1 100755 --- a/src/v6809.h +++ b/src/v6809.h @@ -35,16 +35,16 @@ struct V6809REGS { - uint16 pc; // 6809 PC register + uint16 pc; // 6809 PC register uint16 x; // 6809 X index register uint16 y; // 6809 Y index register uint16 s; // 6809 System stack pointer uint16 u; // 6809 User stack pointer - uint8 cc; // 6809 Condition Code register + uint8 cc; // 6809 Condition Code register uint8 a; // 6809 A register uint8 b; // 6809 B register - uint8 dp; // 6809 Direct Page register - uint32 clock; // 6809 clock + uint8 dp; // 6809 Direct Page register + uint32 clock; // 6809 clock //uint32 _reserved;// uint8 (* Fetch)(uint16&); // Address of uint8 fetch routine uint8 (* RdMem)(uint16); // Address of uint8 read routine void (* WrMem)(uint16, uint8); // Address of uint8 write routine diff --git a/src/video.cpp b/src/video.cpp index fe552b9..e3ad1b7 100755 --- a/src/video.cpp +++ b/src/video.cpp @@ -61,7 +61,7 @@ bool InitVideo(void) if (settings.useOpenGL) { - mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_OPENGL; + mainSurfaceFlags = SDL_HWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF | SDL_OPENGL; SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); //We want 32BPP, so force the issue... SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); @@ -103,8 +103,7 @@ bool InitVideo(void) SDL_WM_SetCaption("StarGem2", "StarGem2"); // Create the secondary SDL display (32 BPP) that we use directly - surface = SDL_CreateRGBSurface(SDL_SWSURFACE, VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT, 32, - MASK_R, MASK_G, MASK_B, MASK_A); + surface = SDL_CreateRGBSurface(SDL_SWSURFACE, VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT, 32, MASK_R, MASK_G, MASK_B, MASK_A); /*WriteLog("Video: Created secondary surface with attributes:\n\n"); WriteLog("\tWidth, height: %u x %u\n", surface->w, surface->h); WriteLog("\t Pitch: %u\n", surface->pitch); diff --git a/stargem2.cfg b/stargem2.cfg index 76daeb4..2362adc 100755 --- a/stargem2.cfg +++ b/stargem2.cfg @@ -18,7 +18,7 @@ autoSaveState = 1 # OpenGL options: 1 - use OpenGL rendering, 0 - use old style rendering -useOpenGL = 0 +useOpenGL = 1 # OpenGL filtering type: 1 - blurry, 0 - sharp -- 2.37.2