From: Shamus Hammons Date: Thu, 17 Apr 2014 16:27:02 +0000 (-0500) Subject: Removed useless cruft, fixed off-by-one bug in screen render. X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=thunder;a=commitdiff_plain;h=a7c3ff9deab4cefbc76ac52d38b67e7033c63cf6 Removed useless cruft, fixed off-by-one bug in screen render. --- diff --git a/makefile b/makefile index 9004c58..e19b93a 100644 --- a/makefile +++ b/makefile @@ -51,21 +51,22 @@ CPPFLAGS = -MMD -Wall -Wno-switch -Wno-non-virtual-dtor -Wno-uninitialized -Wno- LDFLAGS = # Ugh, let's get rid of the ref to -lcurses -LIBS = `sdl2-config $(SDLLIBTYPE)` -lstdc++ -lz $(GLLIB) -lcurses +LIBS = `sdl2-config $(SDLLIBTYPE)` -lstdc++ -lz -lm $(GLLIB) INCS = -I. -Isrc OBJS = \ - obj/dis6808.o \ + obj/dis63701.o \ obj/dis6809.o \ obj/gui.o \ obj/icon-64x64.o \ obj/log.o \ obj/resource.o \ obj/screen.o \ - obj/v6808.o \ + obj/v63701.o \ obj/v6809.o \ obj/video.o \ + obj/ym2151.o \ obj/thunder.o \ $(ICON) diff --git a/src/dis6808.cpp b/src/dis6808.cpp deleted file mode 100644 index 97f20c4..0000000 --- a/src/dis6808.cpp +++ /dev/null @@ -1,151 +0,0 @@ -// -// 6808 disassembler -// -// by James Hammons -// -// (c) 2004, 2014 Underground Software -// - -#include "dis6808.h" - -#include -#include -#include "v6808.h" -#include "log.h" - -using namespace std; - -// External shit - -#warning "THIS ISN'T GENERIC ENOUGH... !!! FIX !!!" -/*extern*/ V6808REGS soundCPU;//Hm. - -// Private globals variables - -static char op_mat[256] = { - 0, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 5, 5, 0, 5, 0, 5, 0, 0, 0, 0, - 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 0, 5, 0, 0, 5, 5, - 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5, - 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5, - 7, 0, 0, 7, 7, 0, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, - 2, 0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, - 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 8, 9, 3, 9, 0, - 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, - 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8, 8, 0, 0, 9, 0, - 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, - 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, - 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2 -}; - -static char mnemonics[256][6] = { - "??? ","NOP ","??? ","??? ","??? ","??? ","TAP ","TPA ", - "INX ","DEX ","CLV ","SEV ","CLC ","SEC ","CLI ","SEI ", - "SBA ","CBA ","??? ","??? ","??? ","??? ","TAB ","TBA ", - "??? ","DAA ","??? ","ABA ","??? ","??? ","??? ","??? ", - "BRA ","??? ","BHI ","BLS ","BCC ","BCS ","BNE ","BEQ ", - "BVC ","BVS ","BPL ","BMI ","BGE ","BLT ","BGT ","BLE ", - "TSX ","INS ","PULA ","PULB ","DES ","TXS ","PSHA ","PSHB ", - "??? ","RTS ","??? ","RTI ","??? ","??? ","WAI ","SWI ", - "NEGA ","??? ","??? ","COMA ","LSRA ","??? ","RORA ","ASRA ", - "ASLA ","ROLA ","DECA ","??? ","INCA ","TSTA ","??? ","CLRA ", - "NEGB ","??? ","??? ","COMB ","LSRB ","??? ","RORB ","ASRB ", - "ASLB ","ROLB ","DECB ","??? ","INCB ","TSTB ","??? ","CLRB ", - "NEG ","??? ","??? ","COM ","LSR ","??? ","ROR ","ASR ", - "ASL ","ROL ","DEC ","??? ","INC ","TST ","JMP ","CLR ", - "NEG ","??? ","??? ","COM ","LSR ","??? ","ROR ","ASR ", - "ASL ","ROL ","DEC ","??? ","INC ","TST ","JMP ","CLR ", - "SUBA ","CMPA ","SBCA ","??? ","ANDA ","BITA ","LDAA ","??? ", - "EORA ","ADCA ","ORAA ","ADDA ","CPX ","BSR ","LDS ","??? ", - "SUBA ","CMPA ","SBCA ","??? ","ANDA ","BITA ","LDAA ","STAA ", - "EORA ","ADCA ","ORAA ","ADDA ","CPX ","??? ","LDS ","STS ", - "SUBA ","CMPA ","SBCA ","??? ","ANDA ","BITA ","LDAA ","STAA ", - "EORA ","ADCA ","ORAA ","ADDA ","CPX ","JSR ","LDS ","STS ", - "SUBA ","CMPA ","SBCA ","??? ","ANDA ","BITA ","LDAA ","STAA ", - "EORA ","ADCA ","ORAA ","ADDA ","CPX ","JSR ","LDS ","STS ", - "SUBB ","CMPB ","SBCB ","??? ","ANDB ","BITB ","LDAB ","??? ", - "EORB ","ADCB ","ORAB ","ADDB ","??? ","??? ","LDX ","??? ", - "SUBB ","CMPB ","SBCB ","??? ","ANDB ","BITB ","LDAB ","STAB ", - "EORB ","ADCB ","ORAB ","ADDB ","??? ","??? ","LDX ","STX ", - "SUBB ","CMPB ","SBCB ","??? ","ANDB ","BITB ","LDAB ","STAB ", - "EORB ","ADCB ","ORAB ","ADDB ","??? ","??? ","LDX ","STX ", - "SUBB ","CMPB ","SBCB ","??? ","ANDB ","BITB ","LDAB ","STAB ", - "EORB ","ADCB ","ORAB ","ADDB ","??? ","??? ","LDX ","STX " -}; - -// -// Display bytes in mem in hex -// -static void DisplayBytes(uint16_t src, uint32_t dst) -{ - WriteLog("%04X: ", src); - uint8_t cnt = 0; // Init counter... - - if (src > dst) - dst += 0x10000; // That should fix the FFFF bug... - - for(uint32_t i=src; i - -int Decode6808(uint16_t pc); - -#endif // __DIS6808_H__ diff --git a/src/gui.h b/src/gui.h index 663dd52..9a17174 100644 --- a/src/gui.h +++ b/src/gui.h @@ -9,7 +9,7 @@ #define __GUI_H__ #include -#include "SDL.h" +#include // Message macros diff --git a/src/screen.cpp b/src/screen.cpp index f72b2bf..660281f 100644 --- a/src/screen.cpp +++ b/src/screen.cpp @@ -161,9 +161,13 @@ void BlitChar(SDL_Surface * scr, uint8_t * chr, uint8_t * ram) uint32_t src = 0; for(int i=0; i #include @@ -23,10 +24,9 @@ #include #include #include -//#include // For getch() -#include // For getch() +//#include // For getch() #include -#include // Get yer SDL out...! +#include #include "v6809.h" #include "screen.h" #include "gui.h" @@ -77,17 +77,17 @@ uint8_t chr_rom[0x60000]; // Character ROM pointer V6809REGS cpu1, cpu2; -bool trace1 = false; // ditto... -bool looking_at_rom = true; // true = R1, false = R2 -uint32_t banksw1, banksw2; // Bank switch addresses -uint16_t game_over_switch; // Game over delay -uint16_t dpc; // Debug pc reg... -bool show_scr = true; // Whether or not to show background -bool enable_cpu = true; // Whether or not to enable CPUs -bool irqGoA = true; // IRQ switch for CPU #1 -bool irqGoB = true; // IRQ switch for CPU #2 - -uint16_t refresh_ = 0; // Crappy global screen stuff... +bool trace1 = false; // ditto... +bool looking_at_rom = true; // true = R1, false = R2 +uint32_t banksw1, banksw2; // Bank switch addresses +uint16_t game_over_switch; // Game over delay +uint16_t dpc; // Debug pc reg... +bool show_scr = true; // Whether or not to show background +bool enable_cpu = true; // Whether or not to enable CPUs +bool irqGoA = true; // IRQ switch for CPU #1 +bool irqGoB = true; // IRQ switch for CPU #2 + +uint16_t refresh_ = 0; // Crappy global screen stuff... bool refresh2 = true; uint32_t psg_lens[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -101,164 +101,6 @@ uint8_t * fm_adrs[14]; fstream tr; // Tracelog hook uint16_t pcx; // Where we at? -//kludge, for now -//static uint8_t keys[0x1000]; // SDL raw keyboard matrix - -static char op_mat1[256] = { - 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, - 0, 0, 5, 5, 0, 0, 4, 4, 0, 5, 8, 0, 8, 5, 6, 6, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 7, 7, 7, 7, 6, 6, 6, 6, 0, 5, 5, 5, 8, 5, 5, 5, - 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5, - 5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5, - 7, 0, 0, 7, 7, 0, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, - 2, 0, 0, 2, 2, 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, - 8, 8, 8, 9, 8, 8, 8, 0, 8, 8, 8, 8, 9, 3, 9, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 8, 8, 8, 9, 8, 8, 8, 0, 8, 8, 8, 8, 9, 0, 9, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, -op_mat2[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, - 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 7, - 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2 }, -op_mat3[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static char mnemonics[256][6] = { - "NEG ","??? ","??? ","COM ","LSR ","??? ","ROR ","ASR ", - "LSL ","ROL ","DEC ","??? ","INC ","TST ","JMP ","CLR ", - "PAGE1","PAGE2","NOP ","SYNC ","??? ","??? ","LBRA ","LBSR ", - "??? ","DAA ","ORCC ","??? ","ANDCC","SEX ","EXG ","TFR ", - "BRA ","BRN ","BHI ","BLS ","BHS ","BLO ","BNE ","BEQ ", - "BVC ","BVS ","BPL ","BMI ","BGE ","BLT ","BGT ","BLE ", - "LEAX ","LEAY ","LEAS ","LEAU ","PSHS ","PULS ","PSHU ","PULU ", - "??? ","RTS ","ABX ","RTI ","CWAI ","MUL ","RESET","SWI ", - "NEGA ","??? ","??? ","COMA ","LSRA ","??? ","RORA ","ASRA ", - "LSLA ","ROLA ","DECA ","??? ","INCA ","TSTA ","??? ","CLRA ", - "NEGB ","??? ","??? ","COMB ","LSRB ","??? ","RORB ","ASRB ", - "LSLB ","ROLB ","DECB ","??? ","INCB ","TSTB ","??? ","CLRB ", - "NEG ","??? ","??? ","COM ","LSR ","??? ","ROR ","ASR ", - "LSL ","ROL ","DEC ","??? ","INC ","TST ","JMP ","CLR ", - "NEG ","??? ","??? ","COM ","LSR ","??? ","ROR ","ASR ", - "LSL ","ROL ","DEC ","??? ","INC ","TST ","JMP ","CLR ", - "SUBA ","CMPA ","SCBA ","SUBD ","ANDA ","BITA ","LDA ","??? ", - "EORA ","ADCA ","ORA ","ADDA ","CMPX ","BSR ","LDX ","??? ", - "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDA ","STA ", - "EORA ","ADCA ","ORA ","ADDA ","CMPX ","JSR ","LDX ","STX ", - "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDA ","STA ", - "EORA ","ADCA ","ORA ","ADDA ","CMPX ","JSR ","LDX ","STX ", - "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDA ","STA ", - "EORA ","ADCA ","ORA ","ADDA ","CMPX ","JSR ","LDX ","STX ", - "SUBB ","CMPB ","SCBB ","ADDD ","ANDB ","BITB ","LDB ","??? ", - "EORB ","ADCB ","ORB ","ADDB ","LDD ","??? ","LDU ","??? ", - "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDB ","STB ", - "EORB ","ADCB ","ORB ","ADDB ","LDD ","STD ","LDU ","STU ", - "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDB ","STB ", - "EORB ","ADCB ","ORB ","ADDB ","LDD ","STD ","LDU ","STU ", - "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDB ","STB ", - "EORB ","ADCB ","ORB ","ADDB ","LDD ","STD ","LDU ","STU " }, -mnemonics2[256][6] = { - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","LBRN ","LBHI ","LBLS ","LBHS ","LBLO ","LBNE ","LBEQ ", - "LBVC ","LBVS ","LBPL ","LBMI ","LBGE ","LBLT ","LBGT ","LBLE ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","SWI2 ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","CMPD ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","CMPY ","??? ","LDY ","??? ", - "??? ","??? ","??? ","CMPD ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","CMPY ","??? ","LDY ","STY ", - "??? ","??? ","??? ","CMPD ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","CMPY ","??? ","LDY ","STY ", - "??? ","??? ","??? ","CMPD ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","CMPY ","??? ","LDY ","STY ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","LDS ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","LDS ","STS ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","LDS ","STS ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","LDS ","STS " }, -mnemonics3[256][6] = { - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","SWI3 ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","CMPU ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","CMPS ","??? ","??? ","??? ", - "??? ","??? ","??? ","CMPU ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","CMPS ","??? ","??? ","??? ", - "??? ","??? ","??? ","CMPU ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","CMPS ","??? ","??? ","??? ", - "??? ","??? ","??? ","CMPU ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","CMPS ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? ", - "??? ","??? ","??? ","??? ","??? ","??? ","??? ","??? " }, -tregs[16][3] = { - "D", "X", "Y", "U", "S", "PC", "??", "??", - "A", "B", "CC", "DP", "??", "??", "??", "??" }, -iregs[4][2] = {"X", "Y", "U", "S" }; - // // Read a byte from memory (without touching PC. Not a Fetch!) @@ -289,26 +131,14 @@ uint8_t RdMem(uint16_t addr) void WrMem(uint16_t addr, uint8_t b) { extern bool disasm; - extern bool charbase; // Needed for screen. Extern it in it?? - //extern uint16_t sr, ur, xr, yr; // Needed for tracelog - //extern uint16_t pcr; -/* if ((addr>0x40FF) && (addr<0x4390)) - { - tr << hex << addr << ":" << (int)b; - //for(int i=0; i<32; i++) - //{ - // if (gram1[0x4400+i]<0x10) tr << "0"; - // tr << hex << (uint16_t)gram1[0x4400+i] << " "; - //} - tr << endl; - }//*/ + extern bool charbase; // Needed for screen. Extern it in it?? #if 0 if (addr == 0x4182) { WriteLog("\nWriteMem: CPU #1 writing $%02X to $4182!\n\n", b); } #endif -#if 1 +#if 0 if (((addr >= 0x4180) && (addr <= 0x4191)) || (addr == 0x4380)) printf("WriteMem: CPU #1 writing $%02X to $%04X...\n", b, addr); #endif @@ -356,7 +186,6 @@ if (((addr >= 0x4180) && (addr <= 0x4191)) || (addr == 0x4380)) // uint8_t RdMemB(uint16_t addr) { -// extern uint16_t cpu2.s, cpu2.u, cpu2.x, cpu2.y; // Needed for tracelog uint8_t b; if (addr < 0x8000) @@ -371,13 +200,6 @@ uint8_t RdMemB(uint16_t addr) else b = grom2[addr]; -/* if ((addr>0x3FFF) && (addr<0x4400)) tr << "R-" << hex << pcx << ": " - << addr << "-" - << (int)looking_at_rom - << " [" << (int)b - << "] XR:" << xr << " YR:" << yr - << " SR:" << sr << " UR:" << ur - << endl; //*/ return b; } @@ -389,25 +211,14 @@ void WrMemB(uint16_t addr, uint8_t b) { extern bool disasm; extern bool charbase; - //extern uint16_t sr, ur, xr, yr; // Needed for tracelog - //extern uint16_t pcr; -/* if ((addr>0x00FF) && (addr<0x0390)) - { - tr << hex << addr << ":" << (int)b; - //for(int i=0; i<32; i++) - //{ - // if (gram1[0x4400+i]<0x10) tr << "0"; - // tr << hex << (uint16_t)gram1[0x4400+i] << " "; - //} - tr << endl; - }//*/ + #if 0 if (addr == 0x0182) { WriteLog("\nWriteMem: CPU #2 writing $%02X to $0182 ($4182)!\n\n", b); } #endif -#if 1 +#if 0 if (((addr >= 0x0180) && (addr <= 0x0191)) || (addr == 0x0380)) printf("WriteMem: CPU #2 writing $%02X to $%04X...\n", b, addr); #endif @@ -447,302 +258,25 @@ if (((addr >= 0x0180) && (addr <= 0x0191)) || (addr == 0x0380)) } -// -// Display bytes in mem in hex -// -void DisplayBytes(uint16_t src, unsigned long dst) -{ - uint8_t cnt = 0; - WriteLog("%04X: ", src); - - if (src > dst) - dst += 0x10000; // That should fix the FFFF bug... - - for(unsigned long i=src; i>4], tregs[operand&0x0F]); - } - else - { - tmp[0] = 0; - if (operand&0x01) strcat(tmp, "CC "); - if (operand&0x02) strcat(tmp, "A "); - if (operand&0x04) strcat(tmp, "B "); - if (operand&0x08) strcat(tmp, "DP "); - if (operand&0x10) strcat(tmp, "X "); - if (operand&0x20) strcat(tmp, "Y "); - if (operand&0x40) (((opcode==0x34)||(opcode==0x35)) - ? strcat(tmp, "U ") : strcat(tmp, "S ")); - if (operand&0x80) strcat(tmp, "PC"); - } - sprintf(outbuf, "%s %s", mnem, tmp); - break; - } - case 7: // Indexed (the tough one!) - { - operand = DFetch(); // Get IDX byte - uint8_t reg = ((operand & 0x60) >> 5), idxind = ((operand & 0x10) >> 4), - lo_nyb = (operand & 0x0F), boff; - uint16_t woff; - - strcpy(tmp, "??"); - - if (!(operand & 0x80)) // Hi bit set? Then decode 4 bit offset - { - sprintf(tmp, "(%d),%s", (idxind ? -(16-lo_nyb) : lo_nyb), - iregs[reg]); - } - else // Add the ($nnnn,R) code dude... - { - if (idxind) - { - switch (lo_nyb) - { - case 1: sprintf(tmp, "(,%s++)", iregs[reg]); break; - case 3: sprintf(tmp, "(,--%s)", iregs[reg]); break; - case 4: sprintf(tmp, "(,%s)", iregs[reg]); break; - case 5: sprintf(tmp, "(B,%s)", iregs[reg]); break; - case 6: sprintf(tmp, "(A,%s)", iregs[reg]); break; - case 8: - { boff = DFetch(); sprintf(tmp, "($%02X,%s)", boff, - iregs[reg]); break; } - case 9: - { woff = DFetchW(); sprintf(tmp, "($%04X,%s)", woff, - iregs[reg]); break; } - case 11: sprintf(tmp, "(D,%s)", iregs[reg]); break; - case 12: - { boff = DFetch(); sprintf(tmp, "($%02X,PC)", boff); break; } - case 13: - { woff = DFetchW(); sprintf(tmp, "($%04X,PC)", woff); break; } - case 15: - { woff = DFetchW(); sprintf(tmp, "[$%04X]", woff); break; } - default: strcpy(tmp, "??"); - } - } - else - { - switch (lo_nyb) - { - case 0: sprintf(tmp, ",%s+", iregs[reg]); break; - case 1: sprintf(tmp, ",%s++", iregs[reg]); break; - case 2: sprintf(tmp, ",-%s", iregs[reg]); break; - case 3: sprintf(tmp, ",--%s", iregs[reg]); break; - case 4: sprintf(tmp, ",%s", iregs[reg]); break; - case 5: sprintf(tmp, "(B),%s", iregs[reg]); break; - case 6: sprintf(tmp, "(A),%s", iregs[reg]); break; - case 8: - { boff = DFetch(); sprintf(tmp, "($%02X),%s", boff, - iregs[reg]); break; } - case 9: - { woff = DFetchW(); sprintf(tmp, "($%04X),%s", woff, - iregs[reg]); break; } - case 11: sprintf(tmp, "(D),%s", iregs[reg]); break; - case 12: - { boff = DFetch(); sprintf(tmp, "($%02X),PC", boff); break; } - case 13: - { woff = DFetchW(); sprintf(tmp, "($%04X),PC", woff); break; } - default: strcpy(tmp, "??"); - } - } - } - - sprintf(outbuf, "%s %s", mnem, tmp); - break; - } - case 8: // Immediate - operand = DFetch(); // Get IMM byte - sprintf(outbuf, "%s #$%02X", mnem, operand); - break; - case 9: // Long Immediate - loperand = DFetchW(); // Get IMM word - sprintf(outbuf, "%s #$%04X", mnem, loperand); - break; - } - - DisplayBytes(dpc, (looking_at_rom ? pcr : pcrB)); // Show bytes - WriteLog(outbuf); - WriteLog("\n"); // display opcode & addressing, etc - dpc = (looking_at_rom ? pcr : pcrB); // Advance debug PC - pcr = pc_save; - pcrB = pcB_save; // Restore PCs -} - - -// -// Convert hex to dec -// -uint16_t htod(char * str) -{ - uint16_t value = 0; - int len = strlen(str); - - for(int i=0; i= '0' && str[i] <= '9') - value = (value << 4) | (unsigned)(str[i] - '0'); - else if (str[i] >= 'a' && str[i] <= 'f') - value = (value << 4) | (unsigned)((str[i] - 'a') + 10); - else if (str[i] >= 'A' && str[i] <= 'F') - value = (value << 4) | (unsigned)((str[i] - 'A') + 10); - } - - return value; -} - - -// -// Load 32K file into ROM image space -// -bool Load32KImg(char * filename, uint16_t address) -{ -#if 0 - ifstream ff; - char ch; - - ff.open(filename, ios::binary | ios::in); - - if (ff) - { - // Read it in... - for(long i=0; i<32768; i++) - { - ff.get(ch); - grom[address+i] = ch; - } - - ff.close(); - } - - return ff; -#else - FILE * file = fopen(filename, "rb"); - - if (!file) - return false; - - fread(&grom[address], 1, 0x8000, file); - - return true; -#endif -} - - // // Generic Load file into image space // (No error checking performed! Responsibility of caller!) // bool LoadImg(const char * filename, uint8_t * mem, uint32_t address, uint32_t length) { - ifstream ff; - char path[80]; - char ch; + char path[128]; strcpy(path, "./ROMs/"); strcat(path, filename); -// ff.open(filename, ios::binary | ios::in); // Open 'da file... - ff.open(path, ios::binary | ios::in); // Open 'da file... + FILE * file = fopen(path, "rb"); - if (ff) - { - for(uint32_t i=0; i 24) { crh = 0; tr << endl; } - if ((voice_rom[adc] == 0xFF) && (voice_rom[adc-1] != 0x00)) - doneWitIt = true; - adc++; - }//*/ - // Set up V6809 execution contexts memset(&cpu1, 0, sizeof(V6809REGS)); @@ -1160,243 +653,141 @@ extern bool disasm; // From 'V6809.CPP' cpu2.WrMem = WrMemB; cpu2.cpuFlags |= V6809_ASSERT_LINE_RESET; - bool firstTime = true; // kludge... + uint32_t my_clock = 0; + running = true; // Set running status... + trace1 = false; + SetRefreshRate(refresh2); // Tell GUI our refresh rate -WriteLog("About to go to the main loop...\n"); - while (active) - { - cout << ">"; - if (firstTime) - { - firstTime = false; // crappy kludge... - lbuff[0] = 'r'; - lbuff[1] = 0; - } - else - cin >> lbuff; - - if (lbuff[0] == 'd') - { - if (lbuff[1] != 0) - { - lbuff[0] = 32; - dpc = htod(lbuff); - } - printf("%04X: ", dpc); - uint16_t pc_save = cpu1.pc, pcB_save = cpu2.pc; - cpu1.pc = dpc; cpu2.pc = dpc; - for(int i=0; i<16; i++) - printf("%02X ", (looking_at_rom ? Fetch() : FetchB())); - cout << " "; - cpu1.pc = dpc; cpu2.pc = dpc; - for(int i=0; i<16; i++) - { - uint8_t a = (looking_at_rom ? Fetch() : FetchB()); - if (a<10) cout << (char)(a+48); - if ((a>9) && (a<37)) cout << (char)(a+55); - if (a>36) cout << "."; - } - cout << endl; - dpc = (looking_at_rom ? cpu1.pc : cpu2.pc); - cpu1.pc = pc_save; cpu2.pc = pcB_save; - } - else if (lbuff[0] == 'e') - { - if (lbuff[1] != 0) - { - lbuff[0] = 32; - dpc = htod(lbuff); - } - printf("%04X: ", dpc); - for(int i=0; i<16; i++) printf("%02X ", (uint8_t)gram[dpc++]); - cout << endl; - } - else if (lbuff[0] == 'l') - { - if (lbuff[1] != 0) - { - lbuff[0] = 32; - dpc = htod(lbuff); - } - for(int i=0; i<23; i++) - Decode_6809(); - } - else if (lbuff[0] == 't') - { - if (lbuff[1] != 0) - { - lbuff[0] = 32; - dpc = htod(lbuff); - } - if (looking_at_rom) - { - cpu1.pc = dpc; - Decode_6809(); - Execute6809(&cpu1, 1); - dpc = cpu1.pc; - printf("A=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X", - cpu1.a, cpu1.b, cpu1.cc, cpu1.dp, cpu1.x, cpu1.y, cpu1.s, cpu1.u, cpu1.pc); - cout << " iclock=" << cpu1.clock << endl; - } - else - { - cpu2.pc = dpc; - Decode_6809(); - Execute6809(&cpu2, 1); - dpc = cpu2.pc; - printf("A=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X", - cpu2.a, cpu2.b, cpu2.cc, cpu2.dp, cpu2.x, cpu2.y, cpu2.s, cpu2.u, cpu2.pc); - cout << " iclock=" << cpu2.clock << endl; - } - } - else if ((lbuff[0] == 'r') || (lbuff[0] == 'c')) // Run/continue... - { -WriteLog("Executing 'run' command...\n"); - uint32_t my_clock = 0; - running = true; // Set running status... - trace1 = false; - SetRefreshRate(refresh2); // Tell GUI our refresh rate - //for(uint16_t i=0; i<0x8000; i++) gram2[i] = grom3[i]; //Temp - - if (lbuff[0] == 'r') // If run, then reset CPUs - { -WriteLog("Executing secondary 'run' command...\n"); #if 1 - // This is data that is supposed to come from the MCU... So that's why it hangs - gram1[0x4182] = 0xA6; // Temp kludge - gram1[0x4184] = 0xA6; - gram1[0x4183] = 0x00; // More of the same - gram1[0x4185] = 0x00; + // This is data that is supposed to come from the MCU... So that's why it hangs + gram1[0x4182] = 0xA6; // Temp kludge + gram1[0x4184] = 0xA6; + gram1[0x4183] = 0x00; // More of the same + gram1[0x4185] = 0x00; #endif - banksw1 = 0; // Will this work? - banksw2 = 0; + banksw1 = 0; // Will this work? + banksw2 = 0; // iclock = 0; // Reset instr clock #1... - InitGUI(); // Reset # of coins - -#if 0 - cpu1.pc = ((grom1[0xFFFE]<<8) | grom1[0xFFFF]); // Reset 6809 #1 - if (lbuff[1] != 0) - { - lbuff[0] = 32; cpu1.pc = htod(lbuff); - } - else cpu1.cc = 0xFF; // Set CC register - - cpu2.pc = ((grom2[0xFFFE]<<8) | grom2[0xFFFF]); // Reset 6809 #2 - cpu2.cc = 0xFF; // Set CC register - while(iclock < 8000) // was 17000, 20000, 5000 - { - Execute6809(&cpu1, 1); Execute6809(&cpu2, 1); - } -#endif -#if 0 -WriteLog("--> CPU clock #1: %u\n", cpu1.clock); - // Will *this* help video sync? NO - while (cpu1.clock < 8000) // was 17000, 20000, 5000 - { - Execute6809(&cpu1, 1); - Execute6809(&cpu2, 1); - } -#endif - } + InitGUI(); // Reset # of coins WriteLog("About to set up screen...\n"); -#if 0 - screen = SDL_SetVideoMode(VIRTUAL_SCREEN_WIDTH * 2, VIRTUAL_SCREEN_HEIGHT * 2, 8, SDL_SWSURFACE | SDL_DOUBLEBUF); - if (screen == NULL) - { - cout << "Failed to initialize screen!" << endl; - running = false; - } -#else - InitVideo(); -#endif - -#if 0 - SDL_Color colors[256]; - - for(int i=0; i<256; i++) - { - colors[i].r = palette[i*3+0]; - colors[i].g = palette[i*3+1]; - colors[i].b = palette[i*3+2]; - } - - SDL_SetPalette(screen, SDL_LOGPAL | SDL_PHYSPAL, colors, 0, 256); -#endif - -#if 0 - for(int i=0; i<256; i++) - keys[i] = 0; // Clear keyboard buffer... -#endif + InitVideo(); - oldTicks = SDL_GetTicks(); + oldTicks = SDL_GetTicks(); WriteLog("About to set up audio...\n"); #if 1 - // This crap SHOULD be in sound.cpp (not yet created)... - SDL_AudioSpec desired, obtained; - desired.freq = 22050; - desired.format = AUDIO_U8; - desired.channels = 1; - desired.samples = 600; - desired.callback = SoundFunc; - desired.userdata = NULL; - // Also, should check to see if it got the hardware it needed, correct sample size, etc. - if (SDL_OpenAudio(&desired, &obtained) < 0) - { - cout << "Couldn't open audio: " << SDL_GetError() << endl; - return -1; - } + // This crap SHOULD be in sound.cpp (not yet created)... + SDL_AudioSpec desired, obtained; + desired.freq = 22050; + desired.format = AUDIO_U8; + desired.channels = 1; + desired.samples = 600; + desired.callback = SoundFunc; + desired.userdata = NULL; + // Also, should check to see if it got the hardware it needed, correct sample size, etc. + if (SDL_OpenAudio(&desired, &obtained) < 0) + { + cout << "Couldn't open audio: " << SDL_GetError() << endl; + return -1; + } - SDL_PauseAudio(0); // Get that audio going! + SDL_PauseAudio(0); // Get that audio going! #endif memset(scrBuffer, 0xFF, VIRTUAL_SCREEN_WIDTH*VIRTUAL_SCREEN_HEIGHT*sizeof(uint32_t)); RenderScreenBuffer(); + WriteLog("About to enter main loop...\n"); - while (running) - { - HandleGUIDebounce(); // Debounce GUI keys + while (running) + { + HandleGUIDebounce(); // Debounce GUI keys - if (game_over_switch) - { - game_over_switch--; // Countdown... + if (game_over_switch) + { + game_over_switch--; // Countdown... - if (game_over_switch == 0) - gram1[0x4380] = 0; // Kill music! - } + if (game_over_switch == 0) + gram1[0x4380] = 0; // Kill music! + } //testing... (works) //gram1[0x423D] = 1; - //gram1[0x423D] = self_test; // Reset DSW1-1 - gram1[0x4268] = 0; // Reset Video test - gram1[0x427A] = 0; gram1[0x427C] = 0; - gram1[0x427B] = 0; gram1[0x427D] = 0; - gram1[0x427E] = 0; gram1[0x427F] = 0; - gram1[0x4280] = 0; gram1[0x4281] = 0; - gram1[0x4276] = 0; gram1[0x426A] = 0; - gram1[0x4278] = 0; gram1[0x426C] = 0; - gram1[0x4262] = 0; gram1[0x4260] = 0; - //gram1[0x4247] = 0; - - // SDL key handling... - -// SDL_PumpEvents(); // Force key events into the buffer. - SDL_Event event; - - while (SDL_PollEvent(&event)) + //gram1[0x423D] = self_test; // Reset DSW1-1 + gram1[0x4268] = 0; // Reset Video test + gram1[0x427A] = 0; gram1[0x427C] = 0; + //gram1[0x427B] = 0; gram1[0x427D] = 0; + gram1[0x427E] = 0;// gram1[0x427F] = 0; + gram1[0x4280] = 0;// gram1[0x4281] = 0; + //gram1[0x4276] = 0; + gram1[0x426A] = 0; + //gram1[0x4278] = 0; + gram1[0x426C] = 0; + gram1[0x4262] = 0; gram1[0x4260] = 0; + //gram1[0x4247] = 0; + + // SDL key handling... + + SDL_Event event; + + while (SDL_PollEvent(&event)) + { + switch (event.type) + { + case SDL_KEYDOWN: + if (event.key.keysym.sym == SDLK_ESCAPE) + running = false; + else if (event.key.keysym.sym == SDLK_F10) + gram1[0x41A5]++; // Coin? (F10) + else if (event.key.keysym.sym == SDLK_c) + gram1[0x418C]++; // ? (C) Start + else if (event.key.keysym.sym == SDLK_RIGHT) { - switch (event.type) - { - case SDL_KEYDOWN: - if (event.key.keysym.sym == SDLK_ESCAPE) - running = false; - else if (event.key.keysym.sym == SDLK_F10) - gram1[0x41A5]++; // Coin? (F10) - else if (event.key.keysym.sym == SDLK_c) - gram1[0x418C]++; // ? (C) Start - } + // Disallow opposite directions @ same time + if (gram1[0x4281] == 0) + gram1[0x427F] = 1; // Stick right } + else if (event.key.keysym.sym == SDLK_LEFT) + { + // Disallow opposite directions@same time + if (gram1[0x427F] == 0) + gram1[0x4281] = 1; // Stick left + } + else if (event.key.keysym.sym == SDLK_UP) + { + // Disallow opposite directions@same time + if (gram1[0x427D] == 0) + gram1[0x427B] = 1; // Stick up + } + else if (event.key.keysym.sym == SDLK_DOWN) + { + // Disallow opposite directions@same time + if (gram1[0x427B] == 0) + gram1[0x427D] = 1; // Stick down + } + else if (event.key.keysym.sym == SDLK_q) + gram1[0x4276] = 1; // (Q) Jump + else if (event.key.keysym.sym == SDLK_e) // (E) Fire + gram1[0x4278] = 1; + + break; + case SDL_KEYUP: + if (event.key.keysym.sym == SDLK_RIGHT) + gram1[0x427F] = 0; + else if (event.key.keysym.sym == SDLK_LEFT) + gram1[0x4281] = 0; + else if (event.key.keysym.sym == SDLK_UP) + gram1[0x427B] = 0; + else if (event.key.keysym.sym == SDLK_DOWN) + gram1[0x427D] = 0; + else if (event.key.keysym.sym == SDLK_q) + gram1[0x4276] = 0; // (Q) Jump + else if (event.key.keysym.sym == SDLK_e) // (E) Fire + gram1[0x4278] = 0; + + break; + } + } #if 0 if (keys[SDLK_ESCAPE]) @@ -1611,12 +1002,12 @@ WriteLog("About to enter main loop...\n"); #endif #endif - if (enable_cpu) + if (enable_cpu) // if (true) - { - // We can do this here because we're not executing the cores yet. - cpu1.cpuFlags |= V6809_ASSERT_LINE_IRQ; - cpu2.cpuFlags |= V6809_ASSERT_LINE_IRQ; + { + // We can do this here because we're not executing the cores yet. + cpu1.cpuFlags |= V6809_ASSERT_LINE_IRQ; + cpu2.cpuFlags |= V6809_ASSERT_LINE_IRQ; // while (cpu1.clock < 25000) // 1.538 MHz = 25633.333... cycles per frame (1/60 s) // 25600 cycles/frame @@ -1626,158 +1017,35 @@ WriteLog("About to enter main loop...\n"); // 640 * 40 // 800 * 32 // Interesting, putting IRQs at 30 Hz makes it run at the correct speed. Still hangs in the demo, though. - for(uint32_t i=0; i<640; i++) + for(uint32_t i=0; i<640; i++) // for(uint32_t i=0; i<1280; i++) - { - // Gay, but what are ya gonna do? - // There's better ways, such as keeping track of when slave writes to master, etc... - Execute6809(&cpu1, 40); - Execute6809(&cpu2, 40); - } - } // END: enable_cpu - -// if (refresh_++ == 1) // 30 Hz... -// { -// if (scr_type) -// BlitWilliamsScreen(gram1); // Display the screen... -// else -// BlitChar(screen, chr_rom, gram1); -// refresh_ = (refresh2 ? 1 : 0); // 60/30 Hz... -// } - -#if 0 -//temp, for testing... -BlitChar(screen, chr_rom, gram1); -#endif - // Speed throttling happens here... - while (SDL_GetTicks() - oldTicks < 16) // Actually, it's 16.66... Need to account for that somehow -// while (SDL_GetTicks() - oldTicks < 32) // Actually, it's 16.66... Need to account for that somehow - SDL_Delay(1); // Release our timeslice... - - oldTicks = SDL_GetTicks(); -//cout << "Finished frame..." << endl; - } - -// Stop_audio_output(); -// ReleaseTimer(); -// ReleaseKeyboard(); // Release the interrupt... -// RestoreOldMode(); // Restore screen - if (brk && (cpu1.pc == brkpnt)) - cout << "CPU 1: Break at " << hex << cpu1.pc << endl; - if (brk2 && (cpu2.pc == brkpnt2)) - cout << "CPU 2: Break at " << hex << cpu2.pc << endl; - - lbuff[0] = 'q'; // Temp kludge... - } - else if (lbuff[0] == 'b') // Set/clear breakpoint - { - if (lbuff[1] != 0) { - lbuff[0] = 32; - brkpnt = htod(lbuff); - brk = true; - cout << "Breakpoint #1 set at " << hex << brkpnt << dec << endl; - } - else - { - brk = false; - cout << "Breakpoint cleared" << endl; - } - } - else if (lbuff[0] == 'a') // Set/clear breakpoint #2 - { - if (lbuff[1] != 0) - { - lbuff[0] = 32; - brkpnt2 = htod(lbuff); - brk2 = true; - cout << "Breakpoint #2 set at " << hex << brkpnt2 << dec << endl; - } - else - { - brk2 = false; - cout << "Breakpoint cleared" << endl; - } - } - else if (lbuff[0] == 'i') // Inspect registers - { - printf("CPU1: A=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X", - cpu1.a, cpu1.b, cpu1.cc, cpu1.dp, cpu1.x, cpu1.y, cpu1.s, cpu1.u, cpu1.pc); - cout << " iclk=" << dec << cpu1.clock << endl; - printf("CPU2: A=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X", - cpu2.a, cpu2.b, cpu2.cc, cpu2.dp, cpu2.x, cpu2.y, cpu2.s, cpu2.u, cpu2.pc); - cout << " iclk=" << dec << cpu2.clock << endl; - - if (brk) - cout << "Breakpoint #1 set at " << hex << brkpnt << dec << endl; - - if (brk2) - cout << "Breakpoint #2 set at " << hex << brkpnt2 << dec << endl; - } - else if (strncmp(lbuff, "swap", 4) == 0) // Swap ROMs - { - looking_at_rom = !looking_at_rom; - cout << "Swapped: Looking at "; - (looking_at_rom ? cout << "ROM #1" : cout << "ROM #2"); - cout << endl; - } - else if (strncmp(lbuff, "seek", 4) == 0) // Seek non-zero bytes in RAM - { - - if (lbuff[4] != 0) - { - for(int i=0; i<4; i++) - lbuff[i] = 32; - dpc = htod(lbuff); - } - - do - { - x = gram1[dpc++]; - } - while ((x == 0) && (dpc != 0xFFFF)); // Keep going until something found - dpc--; - - printf("%04X: ", dpc); // Show data found... - - for(int i=0; i<16; i++) - printf("%02X ", gram1[(uint16_t)(dpc+i)]); - - cout << " "; - - for(int i=0; i<16; i++) - { - uint8_t a = gram1[dpc++]; - - if (a<10) - cout << (char)(a+48); - if ((a>9) && (a<37)) - cout << (char)(a+55); - if (a>36) - cout << "."; + // Gay, but what are ya gonna do? + // There's better ways, such as keeping track of when slave writes to master, etc... + Execute6809(&cpu1, 40); + Execute6809(&cpu2, 40); } + } // END: enable_cpu - cout << endl; - } - else if (lbuff[0] == 'v') // View screen - { - BlitChar(screen, chr_rom, gram1); - getch(); - } + // Speed throttling happens here... + while (SDL_GetTicks() - oldTicks < 16) // Actually, it's 16.66... Need to account for that somehow +// while (SDL_GetTicks() - oldTicks < 32) // Actually, it's 16.66... Need to account for that somehow + SDL_Delay(1); // Release our timeslice... - if (lbuff[0] == 'q') - active = false; //break; // Quit + oldTicks = SDL_GetTicks(); +//cout << "Finished frame..." << endl; } - SDL_Quit(); // Shut down SDL + SDL_Quit(); + // Deallocate sounds if they were loaded for(int i=0; i<16; i++) if (psg_adrs[i]) - delete[] psg_adrs[i]; // Deallocate if loaded + delete[] psg_adrs[i]; for(int i=0; i<14; i++) if (fm_adrs[i]) - delete[] fm_adrs[i]; // Deallocate if loaded + delete[] fm_adrs[i]; LogDone(); diff --git a/src/v63701.cpp b/src/v63701.cpp index 3f01921..b76063f 100644 --- a/src/v63701.cpp +++ b/src/v63701.cpp @@ -2285,7 +2285,8 @@ static void Op8D(void) // BSR static void Op6E(void) // JMP ZP, X { - regs.pc = EA_ZP_X; + uint16_t m = EA_ZP_X; + regs.pc = m; } @@ -2556,7 +2557,7 @@ static void Op__(void) // Ok, the exec_op[] array is globally defined here basically to save // a LOT of unnecessary typing. Sure it's ugly, but hey, it works! // -void (* exec_op[256])() = { +static void (* exec_op[256])() = { Op__, Op01, Op__, Op__, Op04, Op05, Op06, Op07, Op08, Op09, Op0A, Op0B, Op0C, Op0D, Op0E, Op0F, Op10, Op11, OpUN, OpUN, Op__, Op__, Op16, Op17, Op18, Op19, Op1A, Op1B, Op__, Op__, Op__, Op__, Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F, diff --git a/src/v6808.cpp b/src/v6808.cpp deleted file mode 100644 index 0f9860d..0000000 --- a/src/v6808.cpp +++ /dev/null @@ -1,2119 +0,0 @@ -// -// Virtual 6808 Emulator v2.0 -// -// by James Hammons -// (C) 2006 Underground Software -// -// JLH = James Hammons -// -// WHO WHEN WHAT -// --- ---------- ----------------------------------------------------------- -// 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 -// JLH 07/21/2009 Converted clock from 32-bit to 64-bit value, added possible -// "don't branch" optimization -// - -// 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_t 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__ -#define TEST_DONT_BRANCH_OPTIMIZATION - -#include "v6808.h" - -#ifdef __DEBUG__ -#include "dis6808.h" -#include "log.h" -#endif - -// Various macros - -#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_t)(b) < (uint8_t)(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_t)(b) < (uint16_t)(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) - -//Small problem with the EA_ macros: ABS macros don't increment the PC!!! !!! FIX !!! [DONE, kinda] -//Can't fix for reading... -#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_t addr = EA_IMM; v = regs.RdMem(addr) -#define READ_ZP_WB(v) uint16_t addr = EA_ZP; v = regs.RdMem(addr) -#define READ_ZP_X_WB(v) uint16_t addr = EA_ZP_X; v = regs.RdMem(addr) -#define READ_ABS_WB(v) uint16_t 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 uint8_t flagH, flagI, flagN, flagZ, flagV, flagC; - -static uint8_t CPUCycles[256] = { - 1, 2, 1, 1, 1, 1, 2, 2, 4, 4, 2, 2, 2, 2, 2, 2, - 2, 2, 1, 1, 1, 1, 2, 2, 1, 2, 1, 2, 1, 1, 1, 1, - 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 1, 5, 1, 10, 1, 1, 9, 12, - 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, - 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, - 7, 1, 1, 8, 7, 1, 7, 7, 7, 7, 7, 1, 7, 7, 4, 7, - 6, 1, 1, 7, 6, 1, 6, 6, 6, 6, 6, 1, 6, 6, 3, 6, - 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 3, 8, 3, 1, - 3, 3, 3, 1, 3, 3, 3, 4, 3, 3, 3, 3, 4, 1, 4, 5, - 5, 5, 5, 1, 5, 5, 5, 6, 5, 5, 5, 5, 6, 8, 6, 7, - 4, 4, 4, 1, 4, 4, 4, 5, 4, 4, 4, 4, 5, 9, 5, 6, - 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 3, 1, - 3, 3, 3, 1, 3, 3, 3, 4, 3, 3, 3, 3, 1, 1, 4, 5, - 5, 5, 5, 1, 5, 5, 5, 6, 5, 5, 5, 5, 1, 1, 6, 7, - 4, 4, 4, 1, 4, 4, 4, 5, 4, 4, 4, 4, 1, 1, 5, 6 -}; - -// Private function prototypes - -static uint16_t RdMemW(uint16_t); - -// -// Read a word out of 6808 memory (little endian format) -// -static inline uint16_t RdMemW(uint16_t address) -{ - return (uint16_t)(regs.RdMem(address) << 8) | regs.RdMem(address + 1); -} - -// -// 6808 OPCODE IMPLEMENTATION -// -// 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! ;-) -// - -/* -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| -*/ - -// ADD opcodes - -#define OP_ADD_HANDLER(m, acc) \ - uint16_t sum = (uint16_t)(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_t m = READ_IMM; - OP_ADD_HANDLER(m, regs.a); -} - -static void Op9B(void) // ADDA ZP -{ - uint16_t m = READ_ZP; - OP_ADD_HANDLER(m, regs.a); -} - -static void OpAB(void) // ADDA ZP, X -{ - uint16_t m = READ_ZP_X; - OP_ADD_HANDLER(m, regs.a); -} - -static void OpBB(void) // ADDA ABS -{ - uint16_t m = READ_ABS; - OP_ADD_HANDLER(m, regs.a); -} - -static void OpCB(void) // ADDB # -{ - uint16_t m = READ_IMM; - OP_ADD_HANDLER(m, regs.b); -} - -static void OpDB(void) // ADDB ZP -{ - uint16_t m = READ_ZP; - OP_ADD_HANDLER(m, regs.b); -} - -static void OpEB(void) // ADDB ZP, X -{ - uint16_t m = READ_ZP_X; - OP_ADD_HANDLER(m, regs.b); -} - -static void OpFB(void) // ADDB ABS -{ - uint16_t m = READ_ABS; - OP_ADD_HANDLER(m, regs.b); -} - -static void Op1B(void) // ABA -{ - OP_ADD_HANDLER(regs.b, regs.a); -} - -/* -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_t sum = (uint16_t)acc + (m) + (uint16_t)flagC; \ - flagC = sum >> 8; \ - flagH = (sum >> 4) & 0x01; \ - SET_V(m, acc, sum); \ - acc = sum & 0xFF; \ - SET_ZN(acc) - -static void Op89(void) // ADCA # -{ - uint16_t m = READ_IMM; - OP_ADC_HANDLER(m, regs.a); -} - -static void Op99(void) // ADCA ZP -{ - uint16_t m = READ_ZP; - OP_ADC_HANDLER(m, regs.a); -} - -static void OpA9(void) // ADCA ZP, X -{ - uint16_t m = READ_ZP_X; - OP_ADC_HANDLER(m, regs.a); -} - -static void OpB9(void) // ADCA ABS -{ - uint16_t m = READ_ABS; - OP_ADC_HANDLER(m, regs.a); -} - -static void OpC9(void) // ADCB # -{ - uint16_t m = READ_IMM; - OP_ADC_HANDLER(m, regs.b); -} - -static void OpD9(void) // ADCB ZP -{ - uint16_t m = READ_ZP; - OP_ADC_HANDLER(m, regs.b); -} - -static void OpE9(void) // ADCB ZP, X -{ - uint16_t m = READ_ZP_X; - OP_ADC_HANDLER(m, regs.b); -} - -static void OpF9(void) // ADCB ABS -{ - uint16_t m = READ_ABS; - OP_ADC_HANDLER(m, regs.b); -} - -/* -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 | -*/ - -// AND opcodes - -#define OP_AND_HANDLER(m, acc) \ - acc &= m; \ - SET_ZN(acc); \ - CLR_V - -static void Op84(void) // ANDA # -{ - uint8_t m = READ_IMM; - OP_AND_HANDLER(m, regs.a); -} - -static void Op94(void) // ANDA ZP -{ - uint8_t m = READ_ZP; - OP_AND_HANDLER(m, regs.a); -} - -static void OpA4(void) // ANDA ZP, X -{ - uint16_t m = READ_ZP_X; - OP_AND_HANDLER(m, regs.a); -} - -static void OpB4(void) // ANDA ABS -{ - uint16_t m = READ_ABS; - OP_AND_HANDLER(m, regs.a); -} - -static void OpC4(void) // ANDB # -{ - uint8_t m = READ_IMM; - OP_AND_HANDLER(m, regs.b); -} - -static void OpD4(void) // ANDB ZP -{ - uint8_t m = READ_ZP; - OP_AND_HANDLER(m, regs.b); -} - -static void OpE4(void) // ANDB ZP, X -{ - uint16_t m = READ_ZP_X; - OP_AND_HANDLER(m, regs.b); -} - -static void OpF4(void) // ANDB ABS -{ - uint16_t m = READ_ABS; - OP_AND_HANDLER(m, regs.b); -} - -/* -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_t result = acc & (m); \ - SET_ZN(result) - -static void Op85(void) // BITA # -{ - uint8_t m = READ_IMM; - OP_BIT_HANDLER(m, regs.a); -} - -static void Op95(void) // BITA ZP -{ - uint8_t m = READ_ZP; - OP_BIT_HANDLER(m, regs.a); -} - -static void OpA5(void) // BITA ZP, X -{ - uint8_t m = READ_ZP_X; - OP_BIT_HANDLER(m, regs.a); -} - -static void OpB5(void) // BITA ABS -{ - uint8_t m = READ_ABS; - OP_BIT_HANDLER(m, regs.a); -} - -static void OpC5(void) // BITB # -{ - uint8_t m = READ_IMM; - OP_BIT_HANDLER(m, regs.b); -} - -static void OpD5(void) // BITB ZP -{ - uint8_t m = READ_ZP; - OP_BIT_HANDLER(m, regs.b); -} - -static void OpE5(void) // BITB ZP, X -{ - uint8_t m = READ_ZP_X; - OP_BIT_HANDLER(m, regs.b); -} - -static void OpF5(void) // BITB ABS -{ - uint8_t m = READ_ABS; - OP_BIT_HANDLER(m, regs.b); -} - -/* -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 -{ - regs.WrMem(EA_ZP_X, 0); - CLR_NVC; - SET_Z(0); -} - -static void Op7F(void) // CLR ABS -{ - regs.WrMem(EA_ABS, 0); - regs.pc += 2; - CLR_NVC; - SET_Z(0); -} - -static void Op4F(void) // CLRA -{ - regs.a = 0; - CLR_NVC; - SET_Z(0); -} - -static void Op5F(void) // CLRB -{ - regs.b = 0; - CLR_NVC; - SET_Z(0); -} - -/* -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_t result = acc - (m); \ - SET_ZNVC_CMP(m, acc, result) - -static void Op81(void) // CMPA # -{ - uint8_t m = READ_IMM; - OP_CMP_HANDLER(m, regs.a); -} - -static void Op91(void) // CMPA ZP -{ - uint8_t m = READ_ZP; - OP_CMP_HANDLER(m, regs.a); -} - -static void OpA1(void) // CMPA ZP, X -{ - uint8_t m = READ_ZP_X; - OP_CMP_HANDLER(m, regs.a); -} - -static void OpB1(void) // CMPA ABS -{ - uint8_t m = READ_ABS; - OP_CMP_HANDLER(m, regs.a); -} - -static void OpC1(void) // CMPB # -{ - uint8_t m = READ_IMM; - OP_CMP_HANDLER(m, regs.b); -} - -static void OpD1(void) // CMPB ZP -{ - uint8_t m = READ_ZP; - OP_CMP_HANDLER(m, regs.b); -} - -static void OpE1(void) // CMPB ZP, X -{ - uint8_t m = READ_ZP_X; - OP_CMP_HANDLER(m, regs.b); -} - -static void OpF1(void) // CMPB ABS -{ - uint8_t m = READ_ABS; - OP_CMP_HANDLER(m, regs.b); -} - -static void Op11(void) // CBA -{ - OP_CMP_HANDLER(regs.b, regs.a); -} - -/* -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| -*/ - -// COM opcodes - -#define OP_COM_HANDLER(m) \ - m = m ^ 0xFF; \ - SET_ZN(m); \ - CLR_V; \ - flagC = 1 - -static void Op63(void) // COM ZP, X -{ - uint8_t m; - READ_ZP_X_WB(m); - OP_COM_HANDLER(m); - WRITE_BACK(m); -} - -static void Op73(void) // COM ABS -{ - uint8_t m; - READ_ABS_WB(m); - OP_COM_HANDLER(m); - WRITE_BACK(m); -} - -static void Op43(void) // COMA -{ - OP_COM_HANDLER(regs.a); -} - -static void Op53(void) // COMB -{ - OP_COM_HANDLER(regs.b); -} - -/* -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); \ - flagV = (m == 0x80 ? 1 : 0); \ - flagC = (m == 0x00 ? 1 : 0) - -static void Op60(void) // NEG ZP, X -{ - uint8_t m; - READ_ZP_X_WB(m); - OP_NEG_HANDLER(m); - WRITE_BACK(m); -} - -static void Op70(void) // NEG ABS -{ - uint8_t m; - READ_ABS_WB(m); - OP_NEG_HANDLER(m); - WRITE_BACK(m); -} - -static void Op40(void) // NEGA -{ - OP_NEG_HANDLER(regs.a); -} - -static void Op50(void) // NEGB -{ - OP_NEG_HANDLER(regs.b); -} - -/* -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 -{ - uint16_t result = (uint16_t)regs.a; - - if ((regs.a & 0x0F) > 0x09 || flagH) - result += 0x06; - - if ((regs.a & 0xF0) > 0x90 || flagC || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09)) - result += 0x60; - - regs.a = (uint8_t)result; - SET_ZN(result); - CLR_V; // Not sure this is correct... - flagC |= (result & 0x100) >> 8; // Overwrite carry if it was 0, otherwise, ignore -} - -/* -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); \ - flagV = (m == 0x7F ? 1 : 0) - -static void Op6A(void) // DEC ZP, X -{ - uint8_t m; - READ_ZP_X_WB(m); - OP_DEC_HANDLER(m); - WRITE_BACK(m); -} - -static void Op7A(void) // DEC ABS -{ - uint8_t m; - READ_ABS_WB(m); - OP_DEC_HANDLER(m); - WRITE_BACK(m); -} - -static void Op4A(void) // DECA -{ - OP_DEC_HANDLER(regs.a); -} - -static void Op5A(void) // DECB -{ - OP_DEC_HANDLER(regs.b); -} - -/* -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 # -{ - uint8_t m = READ_IMM; - OP_EOR_HANDLER(m, regs.a); -} - -static void Op98(void) // EORA ZP -{ - uint8_t m = READ_ZP; - OP_EOR_HANDLER(m, regs.a); -} - -static void OpA8(void) // EORA ZP, X -{ - uint8_t m = READ_ZP_X; - OP_EOR_HANDLER(m, regs.a); -} - -static void OpB8(void) // EORA ABS -{ - uint8_t m = READ_ABS; - OP_EOR_HANDLER(m, regs.a); -} - -static void OpC8(void) // EORB # -{ - uint8_t m = READ_IMM; - OP_EOR_HANDLER(m, regs.b); -} - -static void OpD8(void) // EORB ZP -{ - uint8_t m = READ_ZP; - OP_EOR_HANDLER(m, regs.b); -} - -static void OpE8(void) // EORB ZP, X -{ - uint8_t m = READ_ZP_X; - OP_EOR_HANDLER(m, regs.b); -} - -static void OpF8(void) // EORB ABS -{ - uint8_t m = READ_ABS; - OP_EOR_HANDLER(m, regs.b); -} - -/* -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); \ - flagV = (m == 0x80 ? 1 : 0) - -static void Op6C(void) // INC ZP, X -{ - uint8_t m; - READ_ZP_X_WB(m); - OP_INC_HANDLER(m); - WRITE_BACK(m); -} - -static void Op7C(void) // INC ABS -{ - uint8_t m; - READ_ABS_WB(m); - OP_INC_HANDLER(m); - WRITE_BACK(m); -} - -static void Op4C(void) // INCA -{ - OP_INC_HANDLER(regs.a); -} - -static void Op5C(void) // INCB -{ - OP_INC_HANDLER(regs.b); -} - -/* -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 # -{ - uint8_t m = READ_IMM; - OP_LDA_HANDLER(m, regs.a); -} - -static void Op96(void) // LDAA ZP -{ - uint8_t m = READ_ZP; - OP_LDA_HANDLER(m, regs.a); -} - -static void OpA6(void) // LDAA ZP, X -{ - uint8_t m = READ_ZP_X; - OP_LDA_HANDLER(m, regs.a); -} - -static void OpB6(void) // LDAA ABS -{ - uint8_t m = READ_ABS; - OP_LDA_HANDLER(m, regs.a); -} - -static void OpC6(void) // LDAB # -{ - uint8_t m = READ_IMM; - OP_LDA_HANDLER(m, regs.b); -} - -static void OpD6(void) // LDAB ZP -{ - uint8_t m = READ_ZP; - OP_LDA_HANDLER(m, regs.b); -} - -static void OpE6(void) // LDAB ZP, X -{ - uint8_t m = READ_ZP_X; - OP_LDA_HANDLER(m, regs.b); -} - -static void OpF6(void) // LDAB ABS -{ - uint8_t m = READ_ABS; - OP_LDA_HANDLER(m, regs.b); -} - -/* -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_t m = READ_IMM; - OP_ORA_HANDLER(m, regs.a); -} - -static void Op9A(void) // ORAA ZP -{ - uint8_t m = READ_ZP; - OP_ORA_HANDLER(m, regs.a); -} - -static void OpAA(void) // ORAA ZP, X -{ - uint8_t m = READ_ZP_X; - OP_ORA_HANDLER(m, regs.a); -} - -static void OpBA(void) // ORAA ABS -{ - uint8_t m = READ_ABS; - OP_ORA_HANDLER(m, regs.a); -} - -static void OpCA(void) // ORAB # -{ - uint8_t m = READ_IMM; - OP_ORA_HANDLER(m, regs.b); -} - -static void OpDA(void) // ORAB ZP -{ - uint8_t m = READ_ZP; - OP_ORA_HANDLER(m, regs.b); -} - -static void OpEA(void) // ORAB ZP, X -{ - uint8_t m = READ_ZP_X; - OP_ORA_HANDLER(m, regs.b); -} - -static void OpFA(void) // ORAB ABS -{ - uint8_t m = READ_ABS; - OP_ORA_HANDLER(m, regs.b); -} - -/* -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, *+ | | -*/ - -static void Op36(void) // PSHA -{ - PUSH(regs.a); -} - -static void Op37(void) // PSHB -{ - PUSH(regs.b); -} - -static void Op32(void) // PULA -{ - regs.a = PULL; -} - -static void Op33(void) // PULB -{ - regs.b = PULL; -} - -/* -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_t newCarry = (m & 0x80) >> 7; \ - m = (m << 1) | flagC; \ - SET_ZN(m); \ - flagC = newCarry; \ - flagV = flagN ^ flagC - -static void Op69(void) // ROL ZP, X -{ - uint8_t m; - READ_ZP_X_WB(m); - OP_ROL_HANDLER(m); - WRITE_BACK(m); -} - -static void Op79(void) // ROL ABS -{ - uint8_t m; - READ_ABS_WB(m); - OP_ROL_HANDLER(m); - WRITE_BACK(m); -} - -static void Op49(void) // ROLA -{ - OP_ROL_HANDLER(regs.a); -} - -static void Op59(void) // ROLB -{ - OP_ROL_HANDLER(regs.b); -} - -/* -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_t newCarry = m & 0x01; \ - m = (m >> 1) | (flagC << 7); \ - SET_ZN(m); \ - flagC = newCarry; \ - flagV = flagN ^ flagC - -static void Op66(void) // ROR ZP, X -{ - uint8_t m; - READ_ZP_X_WB(m); - OP_ROR_HANDLER(m); - WRITE_BACK(m); -} - -static void Op76(void) // ROR ABS -{ - uint8_t m; - READ_ABS_WB(m); - OP_ROR_HANDLER(m); - WRITE_BACK(m); -} - -static void Op46(void) // RORA -{ - OP_ROR_HANDLER(regs.a); -} - -static void Op56(void) // RORB -{ - OP_ROR_HANDLER(regs.b); -} - -/* -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_t newCarry = (m & 0x80) >> 7; \ - m <<= 1; \ - SET_ZN(m); \ - flagC = newCarry; \ - flagV = flagN ^ flagC - -static void Op68(void) // ASL ZP, X -{ - uint8_t m; - READ_ZP_X_WB(m); - OP_ASL_HANDLER(m); - WRITE_BACK(m); -} - -static void Op78(void) // ASL ABS -{ - uint8_t m; - READ_ABS_WB(m); - OP_ASL_HANDLER(m); - WRITE_BACK(m); -} - -static void Op48(void) // ASLA -{ - OP_ASL_HANDLER(regs.a); -} - -static void Op58(void) // ASLB -{ - 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 - -#define OP_ASR_HANDLER(m) \ - uint8_t newCarry = m & 0x01; \ - m = (m >> 1) | (m & 0x80); \ - SET_ZN(m); \ - flagC = newCarry; \ - flagV = flagN ^ flagC - -static void Op67(void) // ASR ZP, X -{ - uint8_t m; - READ_ZP_X_WB(m); - OP_ASR_HANDLER(m); - WRITE_BACK(m); -} - -static void Op77(void) // ASR ABS -{ - uint8_t m; - READ_ABS_WB(m); - OP_ASR_HANDLER(m); - WRITE_BACK(m); -} - -static void Op47(void) // ASRA -{ - OP_ASR_HANDLER(regs.a); -} - -static void Op57(void) // ASRB -{ - OP_ASR_HANDLER(regs.b); -} - -/* -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_t newCarry = m & 0x01; \ - m >>= 1; \ - SET_ZN(m); \ - flagC = newCarry; \ - flagV = flagN ^ flagC - -static void Op64(void) // LSR ZP, X -{ - uint8_t m; - READ_ZP_X_WB(m); - OP_LSR_HANDLER(m); - WRITE_BACK(m); -} - -static void Op74(void) // LSR ABS -{ - uint8_t m; - READ_ABS_WB(m); - OP_LSR_HANDLER(m); - WRITE_BACK(m); -} - -static void Op44(void) // LSRA -{ - OP_LSR_HANDLER(regs.a); -} - -static void Op54(void) // LSRB -{ - OP_LSR_HANDLER(regs.b); -} - -/* -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(EA_ZP, regs.a); -} - -static void OpA7(void) // STAA ZP, X -{ - regs.WrMem(EA_ZP_X, regs.a); -} - -static void OpB7(void) // STAA ABS -{ - regs.WrMem(EA_ABS, regs.a); - regs.pc += 2; -} - -static void OpD7(void) // STAB ZP -{ - regs.WrMem(EA_ZP, regs.b); -} - -static void OpE7(void) // STAB ZP, X -{ - regs.WrMem(EA_ZP_X, regs.b); -} - -static void OpF7(void) // STAB ABS -{ - regs.WrMem(EA_ABS, regs.b); - regs.pc += 2; -} - -/* -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_t sum = (uint16_t)acc - (m); \ - flagC = sum >> 15; \ - SET_V(m, acc, sum); \ - acc = (uint8_t)sum; \ - SET_ZN(acc) - -static void Op80(void) // SUBA # -{ - uint16_t m = READ_IMM; - OP_SUB_HANDLER(m, regs.a); -} - -static void Op90(void) // SUBA ZP -{ - uint16_t m = READ_ZP; - OP_SUB_HANDLER(m, regs.a); -} - -static void OpA0(void) // SUBA ZP, X -{ - uint16_t m = READ_ZP_X; - OP_SUB_HANDLER(m, regs.a); -} - -static void OpB0(void) // SUBA ABS -{ - uint16_t m = READ_ABS; - OP_SUB_HANDLER(m, regs.a); -} - -static void OpC0(void) // SUBB # -{ - uint16_t m = READ_IMM; - OP_SUB_HANDLER(m, regs.b); -} - -static void OpD0(void) // SUBB ZP -{ - uint16_t m = READ_ZP; - OP_SUB_HANDLER(m, regs.b); -} - -static void OpE0(void) // SUBB ZP, X -{ - uint16_t m = READ_ZP_X; - OP_SUB_HANDLER(m, regs.b); -} - -static void OpF0(void) // SUBB ABS -{ - uint16_t m = READ_ABS; - OP_SUB_HANDLER(m, regs.b); -} - -static void Op10(void) // SBA -{ - OP_SUB_HANDLER(regs.b, regs.a); -} - -/* -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_t sum = (uint16_t)acc - (m) - (uint16_t)flagC; \ - flagC = sum >> 15; \ - SET_V(m, acc, sum); \ - acc = (uint8_t)sum; \ - SET_ZN(acc) - -static void Op82(void) // SBCA # -{ - uint16_t m = READ_IMM; - OP_SBC_HANDLER(m, regs.a); -} - -static void Op92(void) // SBCA ZP -{ - uint16_t m = READ_ZP; - OP_SBC_HANDLER(m, regs.a); -} - -static void OpA2(void) // SBCA ZP, X -{ - uint16_t m = READ_ZP_X; - OP_SBC_HANDLER(m, regs.a); -} - -static void OpB2(void) // SBCA ABS -{ - uint16_t m = READ_ABS; - OP_SBC_HANDLER(m, regs.a); -} - -static void OpC2(void) // SBCB # -{ - uint16_t m = READ_IMM; - OP_SBC_HANDLER(m, regs.b); -} - -static void OpD2(void) // SBCB ZP -{ - uint16_t m = READ_ZP; - OP_SBC_HANDLER(m, regs.b); -} - -static void OpE2(void) // SBCB ZP, X -{ - uint16_t m = READ_ZP_X; - OP_SBC_HANDLER(m, regs.b); -} - -static void OpF2(void) // SBCB ABS -{ - uint16_t m = READ_ABS; - OP_SBC_HANDLER(m, regs.b); -} - -/* -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 | -*/ - -static void Op16(void) // TAB -{ - regs.b = regs.a; - SET_ZN(regs.b); - CLR_V; -} - -static void Op17(void) // TBA -{ - regs.a = regs.b; - SET_ZN(regs.a); - CLR_V; -} - -/* -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| -*/ - -// TST opcodes - -#define OP_TST_HANDLER(m) \ - SET_ZN(m); \ - CLR_VC - -static void Op6D(void) // TST ZP, X -{ - uint8_t m; - READ_ZP_X_WB(m); - OP_TST_HANDLER(m); - WRITE_BACK(m); -} - -static void Op7D(void) // TST ABS -{ - uint8_t m; - READ_ABS_WB(m); - OP_TST_HANDLER(m); - WRITE_BACK(m); -} - -static void Op4D(void) // TSTA -{ - OP_TST_HANDLER(regs.a); -} - -static void Op5D(void) // TSTB -{ - OP_TST_HANDLER(regs.b); -} - -/* -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_t result = regs.x - (m); \ - SET_ZNVC_CMP16(m, regs.x, result) - -static void Op8C(void) // CPX # -{ - uint16_t m = READ_IMM16; - OP_CPX_HANDLER(m); -} - -static void Op9C(void) // CPX ZP -{ - uint16_t m = READ_ZP16; - OP_CPX_HANDLER(m); -} - -static void OpAC(void) // CPX ZP, X -{ - uint16_t m = READ_ZP_X16; - OP_CPX_HANDLER(m); -} - -static void OpBC(void) // CPX ABS -{ - uint16_t m = READ_ABS16; - OP_CPX_HANDLER(m); -} - -/* -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.x--; - SET_Z(regs.x); -} - -static void Op34(void) // DES -{ - regs.s--; -} - -static void Op08(void) // INX -{ - regs.x++; - SET_Z(regs.x); -} - -static void Op31(void) // INS -{ - regs.s++; -} - -/* -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 | -*/ - -// LD* opcode handler - -#define OP_LD_HANDLER(acc) \ - SET_N16(acc); \ - SET_Z(acc); \ - CLR_V - -static void OpCE(void) // LDX # -{ - regs.x = READ_IMM16; - OP_LD_HANDLER(regs.x); -} - -static void OpDE(void) // LDX ZP -{ - regs.x = READ_ZP16; - OP_LD_HANDLER(regs.x); -} - -static void OpEE(void) // LDX ZP, X -{ - regs.x = READ_ZP_X16; - OP_LD_HANDLER(regs.x); -} - -static void OpFE(void) // LDX ABS -{ - regs.x = READ_ABS16; - OP_LD_HANDLER(regs.x); -} - -static void Op8E(void) // LDS # -{ - regs.s = READ_IMM16; - OP_LD_HANDLER(regs.s); -} - -static void Op9E(void) // LDS ZP -{ - regs.s = READ_ZP16; - OP_LD_HANDLER(regs.s); -} - -static void OpAE(void) // LDS ZP, X -{ - regs.s = READ_ZP_X16; - OP_LD_HANDLER(regs.s); -} - -static void OpBE(void) // LDS ABS -{ - regs.s = READ_ABS16; - OP_LD_HANDLER(regs.s); -} - -/* -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 -{ - uint16_t m = EA_ZP; - OP_ST_HANDLER(m, regs.x); -} - -static void OpEF(void) // STX ZP, X -{ - uint16_t m = EA_ZP_X; - OP_ST_HANDLER(m, regs.x); -} - -static void OpFF(void) // STX ABS -{ - uint16_t m = EA_ABS; - regs.pc += 2; - OP_ST_HANDLER(m, regs.x); -} - -static void Op9F(void) // STS ZP -{ - uint16_t m = EA_ZP; - OP_ST_HANDLER(m, regs.s); -} - -static void OpAF(void) // STS ZP, X -{ - uint16_t m = EA_ZP_X; - OP_ST_HANDLER(m, regs.s); -} - -static void OpBF(void) // STS ABS -{ - uint16_t m = EA_ABS; - regs.pc += 2; - OP_ST_HANDLER(m, regs.s); -} - -/* -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 -{ - regs.s = regs.x - 1; -} - -static void Op30(void) // TSX -{ - regs.x = regs.s + 1; -} - -/* -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 -{ - int16_t m = (int16_t)(int8_t)READ_IMM; - regs.pc += m; -} - -static void Op24(void) // BCC -{ -// NOTE: We can optimize this by following the maxim: "Don't branch!" by converting the boolean -// result into a multiplication. The only way to know if this is a win is to do some profiling -// both with and without the optimization. - int16_t m = (int16_t)(int8_t)READ_IMM; - -#ifdef TEST_DONT_BRANCH_OPTIMIZATION -//Note sure if the ! operator will do what we want, so we use ^ 1 - regs.pc += m * (flagC ^ 0x01); -#else - if (!flagC) - regs.pc += m; -#endif -} - -static void Op25(void) // BCS -{ - int16_t m = (int16_t)(int8_t)READ_IMM; - -#ifdef TEST_DONT_BRANCH_OPTIMIZATION - regs.pc += m * (flagC); -#else - if (flagC) - regs.pc += m; -#endif -} - -static void Op27(void) // BEQ -{ - int16_t m = (int16_t)(int8_t)READ_IMM; - -#ifdef TEST_DONT_BRANCH_OPTIMIZATION - regs.pc += m * (flagZ); -#else - if (flagZ) - regs.pc += m; -#endif -} - -static void Op2C(void) // BGE -{ - int16_t m = (int16_t)(int8_t)READ_IMM; - -#ifdef TEST_DONT_BRANCH_OPTIMIZATION - regs.pc += m * ((flagN ^ flagV) ^ 0x01); -#else - if (!(flagN ^ flagV)) - regs.pc += m; -#endif -} - -static void Op2E(void) // BGT -{ - int16_t m = (int16_t)(int8_t)READ_IMM; - -#ifdef TEST_DONT_BRANCH_OPTIMIZATION - regs.pc += m * ((flagZ | (flagN ^ flagV)) ^ 0x01); -#else - if (!(flagZ | (flagN ^ flagV))) - regs.pc += m; -#endif -} - -static void Op22(void) // BHI -{ - int16_t m = (int16_t)(int8_t)READ_IMM; - -#ifdef TEST_DONT_BRANCH_OPTIMIZATION - regs.pc += m * ((flagZ | flagC) ^ 0x01); -#else - if (!(flagZ | flagC)) - regs.pc += m; -#endif -} - -static void Op2F(void) // BLE -{ - int16_t m = (int16_t)(int8_t)READ_IMM; - -#ifdef TEST_DONT_BRANCH_OPTIMIZATION - regs.pc += m * (flagZ | (flagN ^ flagV)); -#else - if (flagZ | (flagN ^ flagV)) - regs.pc += m; -#endif -} - -static void Op23(void) // BLS -{ - int16_t m = (int16_t)(int8_t)READ_IMM; - -#ifdef TEST_DONT_BRANCH_OPTIMIZATION - regs.pc += m * (flagZ | flagC); -#else - if (flagZ | flagC) - regs.pc += m; -#endif -} - -static void Op2D(void) // BLT -{ - int16_t m = (int16_t)(int8_t)READ_IMM; - -#ifdef TEST_DONT_BRANCH_OPTIMIZATION - regs.pc += m * (flagN ^ flagV); -#else - if (flagN ^ flagV) - regs.pc += m; -#endif -} - -static void Op2B(void) // BMI -{ - int16_t m = (int16_t)(int8_t)READ_IMM; - -#ifdef TEST_DONT_BRANCH_OPTIMIZATION - regs.pc += m * (flagN); -#else - if (flagN) - regs.pc += m; -#endif -} - -static void Op26(void) // BNE -{ - int16_t m = (int16_t)(int8_t)READ_IMM; - -#ifdef TEST_DONT_BRANCH_OPTIMIZATION - regs.pc += m * (flagZ ^ 0x01); -#else - if (!flagZ) - regs.pc += m; -#endif -} - -static void Op28(void) // BVC -{ - int16_t m = (int16_t)(int8_t)READ_IMM; - -#ifdef TEST_DONT_BRANCH_OPTIMIZATION - regs.pc += m * (flagV ^ 0x01); -#else - if (!flagV) - regs.pc += m; -#endif -} - -static void Op29(void) // BVS -{ - int16_t m = (int16_t)(int8_t)READ_IMM; - -#ifdef TEST_DONT_BRANCH_OPTIMIZATION - regs.pc += m * (flagV); -#else - if (flagV) - regs.pc += m; -#endif -} - -static void Op2A(void) // BPL -{ - int16_t m = (int16_t)(int8_t)READ_IMM; - -#ifdef TEST_DONT_BRANCH_OPTIMIZATION - regs.pc += m * (flagN ^ 0x01); -#else - if (!flagN) - regs.pc += m; -#endif -} - -/* -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 -{ - int16_t m = (int16_t)(int8_t)READ_IMM; - PUSH16(regs.pc); - regs.pc += m; -} - -static void Op6E(void) // JMP ZP, X -{ - regs.pc = EA_ZP_X; -} - -static void Op7E(void) // JMP ABS -{ - regs.pc = EA_ABS; -} - -static void OpAD(void) // JSR ZP, X -{ - uint16_t m = EA_ZP_X; - PUSH16(regs.pc); - regs.pc = m; -} - -static void OpBD(void) // JSR ABS -{ - uint16_t m = EA_ABS; - regs.pc += 2; - PUSH16(regs.pc); - regs.pc = m; -} - -/* -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 -{ -} - -static void Op3B(void) // RTI -{ - regs.cc = PULL; - regs.a = PULL; - regs.b = PULL; - regs.x = PULL16; - regs.pc = PULL16; - UNPACK_FLAGS; -} - -static void Op39(void) // RTS -{ - regs.pc = PULL16; -} - -static void Op3F(void) // SWI -{ - // 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! - flagI = 1; // Also, set IRQ inhibit -} - -static void Op3E(void) // WAI -{ -#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 Op0C(void) // CLC -{ - flagC = 0; -} - -static void Op0E(void) // CLI -{ - flagI = 0; -} - -static void Op0A(void) // CLV -{ - flagV = 0; -} - -static void Op0D(void) // SEC -{ - flagC = 1; -} - -static void Op0F(void) // SEI -{ - flagI = 1; -} - -static void Op0B(void) // SEV -{ - flagV = 1; -} - -static void Op06(void) // TAP -{ - regs.cc = regs.a; - UNPACK_FLAGS; -} - -static void Op07(void) // TPA -{ - 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) -{ - regs.cpuFlags |= V6808_STATE_ILLEGAL_INST; -} - - -// -// Ok, the exec_op[] array is globally defined here basically to save -// a LOT of unnecessary typing. Sure it's ugly, but hey, it works! -// -void (* exec_op[256])() = { - Op__, Op01, Op__, Op__, Op__, Op__, Op06, Op07, Op08, Op09, Op0A, Op0B, Op0C, Op0D, Op0E, Op0F, - Op10, Op11, Op__, Op__, Op__, Op__, Op16, Op17, Op__, Op19, Op__, Op1B, Op__, Op__, Op__, Op__, - Op20, Op__, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F, - Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op__, Op3B, Op__, Op__, Op3E, Op3F, - Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F, - Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F, - Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F, - Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F, - Op80, Op81, Op82, Op__, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__, - Op90, Op91, Op92, Op__, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op__, Op9E, Op9F, - OpA0, OpA1, OpA2, Op__, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF, - OpB0, OpB1, OpB2, Op__, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF, - OpC0, OpC1, OpC2, Op__, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, Op__, Op__, OpCE, Op__, - OpD0, OpD1, OpD2, Op__, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, Op__, Op__, OpDE, OpDF, - OpE0, OpE1, OpE2, Op__, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, Op__, Op__, OpEE, OpEF, - OpF0, OpF1, OpF2, Op__, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, Op__, Op__, OpFE, OpFF -}; - - -// -// Internal "memcpy" (so we don't have to link with any external libraries!) -// -static void myMemcpy(void * dst, void * src, uint32_t size) -{ - uint8_t * d = (uint8_t *)dst, * s = (uint8_t *)src; - - for(uint32_t i=0; icpuFlags &= ~V6808_ASSERT_LINE_RESET; - regs.cpuFlags &= ~V6808_ASSERT_LINE_RESET; - } - else if (regs.cpuFlags & V6808_ASSERT_LINE_NMI) - { -#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! - -#warning "# of clock cycles for NMI unknown. !!! FIX !!!" - regs.clock += 0; // How many??? - context->cpuFlags &= ~V6808_ASSERT_LINE_NMI;// Reset the asserted line (NMI)... - regs.cpuFlags &= ~V6808_ASSERT_LINE_NMI; // Reset the asserted line (NMI)... - } - else if (regs.cpuFlags & V6808_ASSERT_LINE_IRQ) - { -#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)? - { -#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! - -#warning "# of clock cycles for IRQ unknown. !!! FIX !!!" - regs.clock += 0; // How many??? -#warning "IRQ/NMI lines should not be cleared here... !!! FIX !!!" - 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)); -} - -// -// Get the clock of the currently executing CPU -// -uint64_t GetCurrentV6808Clock(void) -{ - return regs.clock; -} diff --git a/src/v6808.h b/src/v6808.h deleted file mode 100644 index 196ce3e..0000000 --- a/src/v6808.h +++ /dev/null @@ -1,56 +0,0 @@ -// -// Virtual 6808 Header file -// -// by James Hammons -// -// (C) 2006 Underground Software -// - -#ifndef __V6808_H__ -#define __V6808_H__ - -#include - -// Useful defines - -#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 -#define FLAG_Z 0x04 // Zero -#define FLAG_V 0x02 // oVerflow -#define FLAG_C 0x01 // Carry - -#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_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!) - -// Useful structs - -struct V6808REGS -{ - uint16_t pc; // 6808 PC register - uint16_t x; // 6808 X index register - uint16_t s; // 6808 System stack pointer - uint8_t cc; // 6808 Condition Code register - uint8_t a; // 6808 A register - uint8_t b; // 6808 B register - uint64_t clock; // 6808 clock - uint8_t (* RdMem)(uint16_t); // Address of uint8_t read routine - void (* WrMem)(uint16_t, uint8_t); // Address of uint8_t write routine - uint32_t cpuFlags; // v6808 IRQ/RESET flags - uint32_t clockOverrun; // Amount of overflow between runs -}; - -// Function prototypes - -void Execute6808(V6808REGS *, uint32_t); // Function to execute 6808 instructions -uint64_t GetCurrentV6808Clock(void); // Get the clock of the currently executing CPU -//uint8_t GetCCRegister(void); // Hmm. - -#endif // __V6808_H__ - diff --git a/src/v6809.cpp b/src/v6809.cpp old mode 100644 new mode 100755 index 862f1a8..a6c07fc --- a/src/v6809.cpp +++ b/src/v6809.cpp @@ -1,246 +1,202 @@ // -// Virtual 6809 v1.3 +// Virtual 6809 v1.4.1 // -// by James Hammons -// (c) 1997, 2014 Underground Software +// by James L. Hammons +// (C) 1997, 2009, 2014 Underground Software // -// JLH = James Hammons +// JLH = James L. Hammons // // WHO WHEN WHAT // --- ---------- ----------------------------------------------------------- // 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 +// JLH 09/29/2009 Converted V6809 to macro implementation! +// JLH 04/17/2014 Misc. cleanups, fixes to missing instructions // -// Mebbe someday I'll get around to fixing the core to be more like V65C02... -// We have a start... ;-) -// +#define __DEBUG__ #include "v6809.h" -#define __DEBUG__ #ifdef __DEBUG__ #include "dis6809.h" // Temporary... #include "log.h" // Temporary... +bool disasm = false;//so we can extern this shit #endif +#define TEST_DONT_BRANCH_OPTIMIZATION + // 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)) +#define CLR_Z (flagZ = 0) +#define CLR_ZN (flagZ = flagN = 0) +#define CLR_ZNC (flagZ = flagN = 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_N16(r) (flagN = ((r) & 0x8000) >> 15) +#define SET_V(a,b,r) (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x80) >> 7) +#define SET_V16(a,b,r) (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x8000) >> 15) +#define SET_H(a,b,r) (flagH = (((a) ^ (b) ^ (r)) & 0x10) >> 4) //Not sure that this code is computing the carry correctly... Investigate! [Seems to be] -#define SET_C_ADD(a,b) (regs.cc = ((uint8_t)(b) > (uint8_t)(~(a)) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)) +//#define SET_C_ADD(a,b) (flagC = ((uint8_t)(b) > (uint8_t)(~(a)) ? 1 : 0)) //#define SET_C_SUB(a,b) (regs.cc = ((uint8_t)(b) >= (uint8_t)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)) -#define SET_C_CMP(a,b) (regs.cc = ((uint8_t)(b) >= (uint8_t)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)) +//#define SET_C_CMP(a,b) (flagC = ((uint8_t)(b) >= (uint8_t)(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_ZN16(r) SET_N16(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) +//#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 !!! -//Hmm, why not do like we did for READ_ABS*??? -//Because the EA_* macros are usually used as an argument to a function call, that's why. #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 EA_DP (regs.dp << 8) | regs.RdMem(regs.pc++) +#define EA_IDX DecodeIDX(regs.RdMem(regs.pc++)) +#define EA_ABS FetchMemW(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_IMM16 FetchMemW(regs.pc) +#define READ_DP regs.RdMem(EA_DP) +#define READ_DP16 RdMemW(EA_DP) +#define READ_IDX regs.RdMem(EA_IDX) +#define READ_IDX16 RdMemW(EA_IDX) +#define READ_ABS regs.RdMem(EA_ABS) +#define READ_ABS16 RdMemW(EA_ABS) #define READ_IMM_WB(v) uint16_t addr = EA_IMM; v = regs.RdMem(addr) -#define READ_ZP_WB(v) uint16_t addr = EA_ZP; v = regs.RdMem(addr) -#define READ_ZP_X_WB(v) uint16_t addr = EA_ZP_X; v = regs.RdMem(addr) -#define READ_ABS_WB(v) uint16_t addr = EA_ABS; v = regs.RdMem(addr); regs.pc += 2 -#define READ_ABS_X_WB(v) uint16_t addr = EA_ABS_X; v = regs.RdMem(addr); regs.pc += 2 -#define READ_ABS_Y_WB(v) uint16_t addr = EA_ABS_Y; v = regs.RdMem(addr); regs.pc += 2 -#define READ_IND_ZP_X_WB(v) uint16_t addr = EA_IND_ZP_X; v = regs.RdMem(addr) -#define READ_IND_ZP_Y_WB(v) uint16_t addr = EA_IND_ZP_Y; v = regs.RdMem(addr) -#define READ_IND_ZP_WB(v) uint16_t addr = EA_IND_ZP; v = regs.RdMem(addr) +#define READ_DP_WB(v) uint16_t addr = EA_DP; v = regs.RdMem(addr) +#define READ_IDX_WB(v) uint16_t addr = EA_IDX; v = regs.RdMem(addr) +#define READ_ABS_WB(v) uint16_t addr = EA_ABS; v = regs.RdMem(addr) #define WRITE_BACK(d) regs.WrMem(addr, (d)) +#define PULLS(r) r = regs.RdMem(regs.s++) +#define PUSHS(r) regs.WrMem(--regs.s, (r)) +#define PULLS16(r) { r = RdMemW(regs.s); regs.s += 2; } +#define PUSHS16(r) { regs.WrMem(--regs.s, (r) & 0xFF); regs.WrMem(--regs.s, (r) >> 8); } +#define PULLU(r) r = regs.RdMem(regs.u++) +#define PUSHU(r) regs.WrMem(--regs.u, (r)) +#define PULLU16(r) { r = RdMemW(regs.u); regs.u += 2; } +#define PUSHU16(r) { regs.WrMem(--regs.u, (r) & 0xFF); regs.WrMem(--regs.u, (r) >> 8); } + +#define PACK_FLAGS ((flagE << 7) | (flagF << 6) | (flagH << 5) | (flagI << 4) | (flagN << 3) | (flagZ << 2) | (flagV << 1) | flagC) +#define UNPACK_FLAGS flagE = (regs.cc & FLAG_E) >> 7; \ + flagF = (regs.cc & FLAG_F) >> 6; \ + 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 V6809REGS regs; -//Let's see if we can nuke this shit. -static uint16_t addr; // Temporary variables common to all funcs... -static uint8_t tmp; +static uint8_t flagE, flagF, flagH, flagI, flagN, flagZ, flagV, flagC; + +static const uint8_t page0Cycles[256] = { + 6, 1, 1, 6, 6, 1, 6, 6, 6, 6, 6, 1, 6, 6, 3, 6, // $0x + 1, 1, 2, 2, 1, 1, 5, 9, 1, 2, 3, 1, 3, 2, 8, 7, // $1x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // $2x + 4, 4, 4, 4, 5, 5, 5, 5, 1, 5, 3, 6, 21, 11, 0, 19, // $3x + 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, // $4x + 2, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1, // $5x + 6, 1, 1, 6, 6, 1, 6, 6, 6, 6, 6, 1, 6, 6, 3, 6, // $6x + 7, 1, 1, 7, 7, 1, 7, 7, 7, 7, 7, 1, 7, 7, 3, 7, // $7x + 2, 2, 2, 4, 2, 2, 2, 1, 2, 2, 2, 2, 4, 7, 3, 1, // $8x + 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 5, 5, // $9x + 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 5, 5, // $Ax + 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 7, 8, 6, 6, // $Bx + 2, 2, 2, 4, 2, 2, 2, 1, 2, 2, 2, 2, 3, 1, 3, 1, // $Cx + 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, // $Dx + 4, 4, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, // $Ex + 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6 // $Fx +}; + +static const uint8_t page1Cycles[256] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $0x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $1x + 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // $2x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, // $3x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $4x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $5x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $6x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $7x + 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 4, 1, // $8x + 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 6, 6, // $9x + 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 6, 6, // $Ax + 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 7, 7, // $Bx + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, // $Cx + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, // $Dx + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, // $Ex + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7 // $Fx +}; + +static const uint8_t page2Cycles[256] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $0x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $1x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $2x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, // $3x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $4x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $5x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $6x + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $7x + 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 1, 1, // $8x + 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 1, 1, // $9x + 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 1, 1, // $Ax + 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, // $Bx + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $Cx + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $Dx + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // $Ex + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // $Fx +}; // Private function prototypes -static uint16_t FetchW(void); static uint16_t RdMemW(uint16_t addr); +static uint16_t FetchMemW(uint16_t addr); static void WrMemW(uint16_t addr, uint16_t w); static uint16_t ReadEXG(uint8_t); // Read TFR/EXG post byte static void WriteEXG(uint8_t, uint16_t); // Set TFR/EXG data static uint16_t DecodeReg(uint8_t); // Decode register data static uint16_t DecodeIDX(uint8_t); // Decode IDX data -//static void (* exec_op1[256])(); -//static void (* exec_op2[256])(); -#if 1 - -// This is here because of the stupid forward declaration rule that C++ forces (the C++ compiler -// isn't smart enough to know that the identifiers in the arrays are declared later, it doesn't -// even *try* to see if they're there). - -#define FD(x) static void Op##x(); // FD -> "Forward Declaration" -#define FE(x) static void Op10##x(); -#define FF(x) static void Op11##x(); - -FD(00) FD(03) FD(04) FD(06) FD(07) FD(08) FD(09) FD(0A) FD(0C) FD(0D) FD(0E) FD(0F) FD(10) FD(11) -FD(12) FD(13) FD(16) FD(17) FD(19) FD(1A) FD(1C) FD(1D) FD(1E) FD(1F) FD(20) FD(21) FD(22) FD(23) -FD(24) FD(25) FD(26) FD(27) FD(28) FD(29) FD(2A) FD(2B) FD(2C) FD(2D) FD(2E) FD(2F) FD(30) FD(31) -FD(32) FD(33) FD(34) FD(35) FD(36) FD(37) FD(39) FD(3A) FD(3B) FD(3C) FD(3D) FD(3E) FD(3F) FD(40) -FD(43) FD(44) FD(46) FD(47) FD(48) FD(49) FD(4A) FD(4C) FD(4D) FD(4F) FD(50) FD(53) FD(54) FD(56) -FD(57) FD(58) FD(59) FD(5A) FD(5C) FD(5D) FD(5F) FD(60) FD(63) FD(64) FD(66) FD(67) FD(68) FD(69) -FD(6A) FD(6C) FD(6D) FD(6E) FD(6F) FD(70) FD(73) FD(74) FD(76) FD(77) FD(78) FD(79) FD(7A) FD(7C) -FD(7D) FD(7E) FD(7F) FD(80) FD(81) FD(82) FD(83) FD(84) FD(85) FD(86) FD(88) FD(89) FD(8A) FD(8B) -FD(8C) FD(8D) FD(8E) FD(90) FD(91) FD(92) FD(93) FD(94) FD(95) FD(96) FD(97) FD(98) FD(99) FD(9A) -FD(9B) FD(9C) FD(9D) FD(9E) FD(9F) FD(A0) FD(A1) FD(A2) FD(A3) FD(A4) FD(A5) FD(A6) FD(A7) FD(A8) -FD(A9) FD(AA) FD(AB) FD(AC) FD(AD) FD(AE) FD(AF) FD(B0) FD(B1) FD(B2) FD(B3) FD(B4) FD(B5) FD(B6) -FD(B7) FD(B8) FD(B9) FD(BA) FD(BB) FD(BC) FD(BD) FD(BE) FD(BF) FD(C0) FD(C1) FD(C2) FD(C3) FD(C4) -FD(C5) FD(C6) FD(C8) FD(C9) FD(CA) FD(CB) FD(CC) FD(CE) FD(D0) FD(D1) FD(D2) FD(D3) FD(D4) FD(D5) -FD(D6) FD(D7) FD(D8) FD(D9) FD(DA) FD(DB) FD(DC) FD(DD) FD(DE) FD(DF) FD(E0) FD(E1) FD(E2) FD(E3) -FD(E4) FD(E5) FD(E6) FD(E7) FD(E8) FD(E9) FD(EA) FD(EB) FD(EC) FD(ED) FD(EE) FD(EF) FD(F0) FD(F1) -FD(F2) FD(F3) FD(F4) FD(F5) FD(F6) FD(F7) FD(F8) FD(F9) FD(FA) FD(FB) FD(FC) FD(FD) FD(FE) FD(FF) -FD(__) FD(01) - -FE(21) FE(22) FE(23) FE(24) FE(25) FE(26) FE(27) FE(28) FE(29) FE(2A) FE(2B) FE(2C) FE(2D) FE(2E) -FE(2F) FE(3F) FE(83) FE(8C) FE(8E) FE(93) FE(9C) FE(9E) FE(9F) FE(A3) FE(AC) FE(AE) FE(AF) FE(B3) -FE(BC) FE(BE) FE(BF) FE(CE) FE(DE) FE(DF) FE(EE) FE(EF) FE(FE) FE(FF) - -FF(3F) FF(83) FF(8C) FF(93) FF(9C) FF(A3) FF(AC) FF(B3) FF(BC) - -#undef FD -#undef FE -#undef FF - -#endif - -// We can move these down and do away with the forward declarations... !!! FIX !!! -// Actually, we can't because these are used in a couple of the opcode functions. -// Have to think about how to fix that... - -// -// Function arrays -// - -// Array of page zero opcode functions... -static void (* exec_op0[256])() = { - Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F, - Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F, - Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F, - Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F, - Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F, - Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F, - Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F, - Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F, - Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__, - Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F, - OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF, - OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF, - OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__, - OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF, - OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF, - OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF -}; - -// Array of page one opcode functions... -static void (* exec_op1[256])() = { - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op103F, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op1083, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op108C, Op__, Op108E, Op__, - Op__, Op__, Op__, Op1093, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op109C, Op__, Op109E, Op109F, - Op__, Op__, Op__, Op10A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10AC, Op__, Op10AE, Op10AF, - Op__, Op__, Op__, Op10B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10BC, Op__, Op10BE, Op10BF, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10CE, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10DE, Op10DF, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10EE, Op10EF, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10FE, Op10FF -}; - -// Array of page two opcode functions... -static void (* exec_op2[256])() = { - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op113F, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op1183, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op118C, Op__, Op__, Op__, - Op__, Op__, Op__, Op1193, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op119C, Op__, Op__, Op__, - Op__, Op__, Op__, Op11A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11AC, Op__, Op__, Op__, - Op__, Op__, Op__, Op11B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11BC, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, - Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__ -}; - // -// Fetch a word out of 6809 memory (little endian format) -// This is a leftover from when fetches were separated from garden variety reads... +// Read word from memory function // -static uint16_t FetchW() +static inline uint16_t RdMemW(uint16_t addr) { - uint16_t w = RdMemW(regs.pc); - regs.pc += 2; - return w; + return (uint16_t)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1); } + // -// Read word from memory function +// Fetch a word from memory function. Increments PC // -uint16_t RdMemW(uint16_t addr) +static inline uint16_t FetchMemW(uint16_t addr) { + regs.pc += 2; return (uint16_t)(regs.RdMem(addr) << 8) | regs.RdMem(addr + 1); } + // // Write word to memory function // -void WrMemW(uint16_t addr, uint16_t w) +static inline void WrMemW(uint16_t addr, uint16_t w) { regs.WrMem(addr + 0, w >> 8); regs.WrMem(addr + 1, w & 0xFF); } + // // Function to read TFR/EXG post byte // -uint16_t ReadEXG(uint8_t code) +static uint16_t ReadEXG(uint8_t code) { uint16_t retval; @@ -271,6 +227,7 @@ uint16_t ReadEXG(uint8_t code) retval = regs.b; break; case 10: + PACK_FLAGS; retval = regs.cc; break; case 11: @@ -283,10 +240,11 @@ uint16_t ReadEXG(uint8_t code) return retval; } + // // Function to set TFR/EXG data // -void WriteEXG(uint8_t code, uint16_t data) +static void WriteEXG(uint8_t code, uint16_t data) { switch (code) { @@ -307,16 +265,17 @@ void WriteEXG(uint8_t code, uint16_t data) case 9: regs.b = data & 0xFF; break; case 10: - regs.cc = data & 0xFF; break; + regs.cc = data & 0xFF; UNPACK_FLAGS; break; case 11: regs.dp = data & 0xFF; break; } } + // // Function to decode register data // -uint16_t DecodeReg(uint8_t reg) +static uint16_t DecodeReg(uint8_t reg) { uint16_t retval; @@ -335,10 +294,11 @@ uint16_t DecodeReg(uint8_t reg) return retval; } + // // Function to decode IDX data // -uint16_t DecodeIDX(uint8_t code) +static uint16_t DecodeIDX(uint8_t code) { uint16_t addr, woff; uint8_t reg = (code & 0x60) >> 5, idxind = (code & 0x10) >> 4, lo_nyb = code & 0x0F; @@ -390,7 +350,7 @@ uint16_t DecodeIDX(uint8_t code) addr = RdMemW(woff); break; case 9: - woff = DecodeReg(reg) + FetchW(); + woff = DecodeReg(reg) + FetchMemW(regs.pc); addr = RdMemW(woff); break; case 11: @@ -398,15 +358,17 @@ uint16_t DecodeIDX(uint8_t code) addr = RdMemW(woff); break; case 12: - woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++); +// woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++); + woff = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc); + regs.pc++; addr = RdMemW(woff); break; case 13: - woff = regs.pc + FetchW(); + woff = regs.pc + FetchMemW(regs.pc); addr = RdMemW(woff); break; case 15: - woff = FetchW(); + woff = FetchMemW(regs.pc); addr = RdMemW(woff); break; } @@ -455,10 +417,11 @@ uint16_t DecodeIDX(uint8_t code) case 5: { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.b; break; } case 6: { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.a; break; } case 8: { addr = DecodeReg(reg) + (int16_t)(int8_t)regs.RdMem(regs.pc++); break; } - case 9: { addr = DecodeReg(reg) + FetchW(); break; } + case 9: { addr = DecodeReg(reg) + FetchMemW(regs.pc); break; } case 11: { addr = DecodeReg(reg) + ((regs.a << 8) | regs.b); break; } - case 12: { addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++); break; } - case 13: { addr = regs.pc + FetchW(); break; } +// case 12: { addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc++); break; } + case 12: { addr = regs.pc + (int16_t)(int8_t)regs.RdMem(regs.pc); regs.pc++; break; } + case 13: { addr = regs.pc + FetchMemW(regs.pc); break; } } } } @@ -466,2589 +429,2875 @@ uint16_t DecodeIDX(uint8_t code) return addr; } + // -// Page zero instructions... +// 6809 OPCODE IMPLEMENTATION // +// 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! ;-) +// + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 89 0137 | ADCA | IMMEDIATE | 2 | 2 | aaaaa | + | 99 0153 | ADCA | DIRECT | 4 | 2 | aaaaa | + | A9 0169 | ADCA | INDEXED | 4 | 2 | aaaaa | + | B9 0185 | ADCA | EXTENDED | 5 | 3 | aaaaa | + | C9 0201 | ADCB | IMMEDIATE | 2 | 2 | aaaaa | + | D9 0217 | ADCB | DIRECT | 4 | 2 | aaaaa | + | E9 0233 | ADCB | INDEXED | 4 | 2 | aaaaa | + | F9 0249 | ADCB | EXTENDED | 5 | 3 | aaaaa | +*/ + +// ADC opcodes + +#define OP_ADC_HANDLER(m, acc) \ + uint16_t sum = (uint16_t)acc + (m) + (uint16_t)flagC; \ + flagC = (sum >> 8) & 0x01; \ + SET_H(m, acc, sum); \ + SET_V(m, acc, sum); \ + acc = sum & 0xFF; \ + SET_ZN(acc) + +/* +Old flag handling code: + (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 +*/ + +static void Op89(void) // ADCA # +{ + uint16_t m = READ_IMM; + OP_ADC_HANDLER(m, regs.a); +} + + +static void Op99(void) // ADCA DP +{ + uint16_t m = READ_DP; + OP_ADC_HANDLER(m, regs.a); +} + -static void Op00(void) // NEG DP +static void OpA9(void) // ADCA IDX { - addr = (regs.dp << 8) | regs.RdMem(regs.pc++); - tmp = 256 - regs.RdMem(addr); - regs.WrMem(addr, tmp); + uint16_t m = READ_IDX; + OP_ADC_HANDLER(m, regs.a); +} - (tmp == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (tmp & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (tmp > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry - regs.clock += 6; +static void OpB9(void) // ADCA ABS +{ + uint16_t m = READ_ABS; + OP_ADC_HANDLER(m, regs.a); } -static void Op01(void) // NEG DP (Undocumented) + +static void OpC9(void) // ADCB # { - Op00(); + uint16_t m = READ_IMM; + OP_ADC_HANDLER(m, regs.b); } -static void Op03(void) // COM DP + +static void OpD9(void) // ADCB DP { - addr = (regs.dp << 8) | regs.RdMem(regs.pc++); - tmp = 0xFF ^ regs.RdMem(addr); - regs.WrMem(addr, tmp); + uint16_t m = READ_DP; + OP_ADC_HANDLER(m, regs.b); +} - 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 - regs.clock += 6; +static void OpE9(void) // ADCB IDX +{ + uint16_t m = READ_IDX; + OP_ADC_HANDLER(m, regs.b); } -static void Op04(void) // LSR DP + +static void OpF9(void) // ADCB ABS { - addr = (regs.dp<<8) | 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 - regs.clock += 6; + uint16_t m = READ_ABS; + OP_ADC_HANDLER(m, regs.b); } -static void Op06(void) // ROR DP + + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 3A 0058 | ABX | INHERENT | 3 | 1 | ----- | + | 8B 0139 | ADDA | IMMEDIATE | 2 | 2 | aaaaa | + | 9B 0155 | ADDA | DIRECT | 4 | 2 | aaaaa | + | AB 0171 | ADDA | INDEXED | 4 | 2 | aaaaa | + | BB 0187 | ADDA | EXTENDED | 5 | 3 | aaaaa | + | C3 0195 | ADDD | IMMEDIATE | 4 | 3 | -aaaa | + | CB 0203 | ADDB | IMMEDIATE | 2 | 2 | aaaaa | + | D3 0211 | ADDD | DIRECT | 6 | 2 | -aaaa | + | DB 0219 | ADDB | DIRECT | 4 | 2 | aaaaa | + | E3 0227 | ADDD | INDEXED | 6 | 2 | -aaaa | + | EB 0235 | ADDB | INDEXED | 4 | 2 | aaaaa | + | F3 0243 | ADDD | EXTENDED | 7 | 3 | -aaaa | + | FB 0251 | ADDB | EXTENDED | 5 | 3 | aaaaa | +*/ + +// ADD opcodes + +#define OP_ADD_HANDLER(m, acc) \ + uint16_t sum = (uint16_t)(acc) + (m); \ + flagC = (sum >> 8) & 0x01; \ + SET_H(m, acc, sum); \ + SET_V(m, acc, sum); \ + (acc) = sum & 0xFF; \ + SET_ZN(acc) + +#define OP_ADD_HANDLER16(m, hireg, loreg) \ + uint32_t acc = (uint32_t)((hireg << 8) | loreg); \ + uint32_t sum = acc + (m); \ + flagC = (sum >> 16) & 0x01; \ + SET_V16(m, acc, sum); \ + acc = sum & 0xFFFF; \ + hireg = (acc >> 8) & 0xFF; \ + loreg = acc & 0xFF; \ + SET_ZN16(acc) + +/* +Old flags: + (addr > 0xFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag + ((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); // Set Zero flag + (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag + + dr += addr; + (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag + dr &= 0xFFFF; + (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag + (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag + ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl + regs.a = dr>>8; regs.b = dr&0xFF; + regs.clock += 4; +*/ + +static void Op3A(void) // ABX { - addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8_t tmp2 = regs.RdMem(addr); - tmp = (tmp2>>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 - regs.clock += 6; + regs.x += (uint16_t)regs.b; } -static void Op07(void) // ASR DP + + +static void Op8B(void) // ADDA # { - addr = (regs.dp<<8) | 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 - regs.clock += 6; + uint16_t m = READ_IMM; + OP_ADD_HANDLER(m, regs.a); } -static void Op08(void) // LSL DP + + +static void Op9B(void) // ADDA DP { - addr = (regs.dp<<8) | regs.RdMem(regs.pc++); // NEEDS OVERFLOW ADJUSTMENT - 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 - regs.clock += 6; + uint16_t m = READ_DP; + OP_ADD_HANDLER(m, regs.a); } -static void Op09(void) // ROL DP + + +static void OpAB(void) // ADDA IDX { - addr = (regs.dp<<8) | regs.RdMem(regs.pc++); uint8_t tmp2 = regs.RdMem(addr); - tmp = (tmp2<<1) + (regs.cc&0x01); - regs.WrMem(addr, tmp); - (tmp2&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Shift hi bit into carry - ((tmp2&0x80)^((tmp2<<1)&0x80) ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; + uint16_t m = READ_IDX; + OP_ADD_HANDLER(m, regs.a); } -static void Op0A(void) // DEC DP + + +static void OpBB(void) // ADDA ABS { - addr = (regs.dp<<8) | 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 - regs.clock += 6; + uint16_t m = READ_ABS; + OP_ADD_HANDLER(m, regs.a); } -static void Op0C(void) // INC DP + + +static void OpC3(void) // ADDD # { - addr = (regs.dp<<8) | 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 - regs.clock += 6; + uint32_t m = READ_IMM16; + OP_ADD_HANDLER16(m, regs.a, regs.b); } -static void Op0D(void) // TST DP + + +static void OpCB(void) // ADDB # { - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - regs.cc &= 0xFD; // CLV - (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; + uint16_t m = READ_IMM; + OP_ADD_HANDLER(m, regs.b); } -static void Op0E(void) // JMP DP + + +static void OpD3(void) // ADDD DP { - regs.pc = (regs.dp<<8) | regs.RdMem(regs.pc++); - regs.clock += 3; + uint32_t m = READ_DP16; + OP_ADD_HANDLER16(m, regs.a, regs.b); } -static void Op0F(void) // CLR DP + + +static void OpDB(void) // ADDB DP { - regs.WrMem((regs.dp<<8)|regs.RdMem(regs.pc++), 0); - regs.cc &= 0xF0; regs.cc |= 0x04; // CLN, SEZ, CLV, CLC - regs.clock += 6; + uint16_t m = READ_DP; + OP_ADD_HANDLER(m, regs.b); } -static void Op10(void) // Page 1 opcode + +static void OpE3(void) // ADDD IDX { - exec_op1[regs.RdMem(regs.pc++)](); + uint32_t m = READ_IDX16; + OP_ADD_HANDLER16(m, regs.a, regs.b); } -static void Op11(void) // Page 2 opcode + +static void OpEB(void) // ADDB IDX { - exec_op2[regs.RdMem(regs.pc++)](); + uint16_t m = READ_IDX; + OP_ADD_HANDLER(m, regs.b); } -static void Op12(void) // NOP + +static void OpF3(void) // ADDD ABS { - regs.clock += 2; + uint32_t m = READ_ABS16; + OP_ADD_HANDLER16(m, regs.a, regs.b); } -static void Op13(void) // SYNC + +static void OpFB(void) // ADDB ABS { - // Fix this so it does the right thing (software interrupt!) - regs.clock += 2; + uint16_t m = READ_ABS; + OP_ADD_HANDLER(m, regs.b); } -static void Op16(void) // LBRA + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 84 0132 | ANDA | IMMEDIATE | 2 | 2 | -aa0- | + | 94 0148 | ANDA | DIRECT | 4 | 2 | -aa0- | + | A4 0164 | ANDA | INDEXED | 4 | 2 | -aa0- | + | B4 0180 | ANDA | EXTENDED | 5 | 3 | -aa0- | + | C4 0196 | ANDB | IMMEDIATE | 2 | 2 | -aa0- | + | D4 0212 | ANDB | DIRECT | 4 | 2 | -aa0- | + | E4 0228 | ANDB | INDEXED | 4 | 2 | -aa0- | + | F4 0244 | ANDB | EXTENDED | 5 | 3 | -aa0- | +*/ + +// AND opcodes + +#define OP_AND_HANDLER(m, acc) \ + acc &= m; \ + SET_ZN(acc); \ + CLR_V + +static void Op84(void) // ANDA # { -// regs.pc += SignedW(FetchW()); - regs.pc += FetchW(); // No need to make signed, both are 16 bit quantities + uint16_t m = READ_IMM; + OP_AND_HANDLER(m, regs.a); +} - regs.clock += 5; +static void Op94(void) // ANDA DP +{ + uint16_t m = READ_DP; + OP_AND_HANDLER(m, regs.a); } -static void Op17(void) // LBSR +static void OpA4(void) // ANDA IDX { - uint16_t 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 + uint16_t m = READ_IDX; + OP_AND_HANDLER(m, regs.a); +} - regs.clock += 9; +static void OpB4(void) // ANDA ABS +{ + uint16_t m = READ_ABS; + OP_AND_HANDLER(m, regs.a); } -static void Op19(void) // DAA +static void OpC4(void) // ANDB # { -#if 0 - uint8_t result = regs.a; + uint16_t m = READ_IMM; + OP_AND_HANDLER(m, regs.b); +} - if ((regs.cc&0x20) || ((regs.a&0x0F) > 0x09)) // H set or lo nyb too big? - { -// regs.a += 0x06; - result += 0x06; - regs.cc |= 0x20; // Then adjust & set half carry - } +static void OpD4(void) // ANDB DP +{ + uint16_t m = READ_DP; + OP_AND_HANDLER(m, regs.b); +} - if ((regs.cc&0x01) || (regs.a > 0x9F)) // C set or hi nyb too big? - { -// regs.a += 0x60; - result += 0x60; - regs.cc |= 0x01; // Then adjust & set carry - } +static void OpE4(void) // ANDB IDX +{ + uint16_t m = READ_IDX; + OP_AND_HANDLER(m, regs.b); +} - regs.a = result; +static void OpF4(void) // ANDB ABS +{ + uint16_t m = READ_ABS; + OP_AND_HANDLER(m, regs.b); +} - regs.cc &= 0xF1; // CL NZV - if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag - if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag -#else - uint16_t result = (uint16_t)regs.a; +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 08 0008 | LSL/ASL | DIRECT | 6 | 2 | naaas | + | 48 0072 | LSLA/ASLA | INHERENT | 2 | 1 | naaas | + | 58 0088 | LSLB/ASLB | INHERENT | 2 | 1 | naaas | + | 68 0104 | LSL/ASL | INDEXED | 6 | 2 | naaas | + | 78 0120 | LSL/ASL | EXTENDED | 7 | 3 | naaas | +*/ - if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H)) - result += 0x06; +// ASL opcodes - if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09)) - result += 0x60; +#define OP_ASL_HANDLER(m) \ + uint16_t res = m << 1; \ + SET_V(m, m, res); \ + flagC = (res >> 8) & 0x01; \ + m = res & 0xFF; \ + SET_ZN(m) - regs.a = (uint8_t)result; -// SET_ZN(result); -// CLR_V; // Not sure this is correct... - regs.cc &= 0xF1; // CL NZV - if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag - if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag -// flagC |= (result & 0x100) >> 8; // Overwrite carry if it was 0, otherwise, ignore - regs.cc |= (result & 0x100) > 8; -#endif - regs.clock += 2; +static void Op08(void) // ASL DP +{ + uint8_t m; + READ_DP_WB(m); + OP_ASL_HANDLER(m); + WRITE_BACK(m); } -static void Op1A(void) // ORCC # +static void Op48(void) // ASLA { - regs.cc |= regs.RdMem(regs.pc++); + OP_ASL_HANDLER(regs.a); +} - regs.clock += 3; +static void Op58(void) // ASLB +{ + OP_ASL_HANDLER(regs.b); } -static void Op1C(void) // ANDCC # +static void Op68(void) // ASL IDX { - regs.cc &= regs.RdMem(regs.pc++); + uint8_t m; + READ_IDX_WB(m); + OP_ASL_HANDLER(m); + WRITE_BACK(m); +} - regs.clock += 3; +static void Op78(void) // ASL ABS +{ + uint8_t m; + READ_ABS_WB(m); + OP_ASL_HANDLER(m); + WRITE_BACK(m); } -static void Op1D(void) // SEX +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 07 0007 | ASR | DIRECT | 6 | 2 | uaa-s | + | 47 0071 | ASRA | INHERENT | 2 | 1 | uaa-s | + | 57 0087 | ASRB | INHERENT | 2 | 1 | uaa-s | + | 67 0103 | ASR | INDEXED | 6 | 2 | uaa-s | + | 77 0119 | ASR | EXTENDED | 7 | 3 | uaa-s | +*/ + +// ASR opcodes (arithmetic, so preserves the sign) + +#define OP_ASR_HANDLER(m) \ + uint8_t res = (m & 0x80) | (m >> 1); \ + SET_ZN(res); \ + flagC = m & 0x01; \ + m = res + +static void Op07(void) // ASR DP { - (regs.b & 0x80 ? regs.a = 0xFF : regs.a = 0x00); + uint8_t m; + READ_DP_WB(m); + OP_ASR_HANDLER(m); + WRITE_BACK(m); +} - ((regs.a | regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a & 0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag +static void Op47(void) // ASRA +{ + OP_ASR_HANDLER(regs.a); +} - regs.clock += 2; +static void Op57(void) // ASRB +{ + OP_ASR_HANDLER(regs.b); } -static void Op1E(void) // EXG +static void Op67(void) // ASR IDX { - tmp = regs.RdMem(regs.pc++); - addr = ReadEXG(tmp >> 4); - WriteEXG(tmp >> 4, ReadEXG(tmp & 0xF)); - WriteEXG(tmp & 0xF, addr); + uint8_t m; + READ_IDX_WB(m); + OP_ASR_HANDLER(m); + WRITE_BACK(m); +} - regs.clock += 8; +static void Op77(void) // ASR ABS +{ + uint8_t m; + READ_ABS_WB(m); + OP_ASR_HANDLER(m); + WRITE_BACK(m); } -static void Op1F(void) // TFR +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 16 0022 | LBRA | RELATIVE | 5 | 3 | ----- | + | 20 0032 | BRA | RELATIVE | 3 | 2 | ----- | + | 21 0033 | BRN | RELATIVE | 3 | 2 | ----- | + | 22 0034 | BHI | RELATIVE | 3 | 2 | ----- | + | 23 0035 | BLS | RELATIVE | 3 | 2 | ----- | + | 24 0036 | BHS/BCC | RELATIVE | 3 | 2 | ----- | + | 25 0037 | BLO/BCS | RELATIVE | 3 | 2 | ----- | + | 26 0038 | BNE | RELATIVE | 3 | 2 | ----- | + | 27 0039 | BEQ | RELATIVE | 3 | 2 | ----- | + | 28 0040 | BVC | RELATIVE | 3 | 2 | ----- | + | 29 0041 | BVS | RELATIVE | 3 | 2 | ----- | + | 2A 0042 | BPL | RELATIVE | 3 | 2 | ----- | + | 2B 0043 | BMI | RELATIVE | 3 | 2 | ----- | + | 2C 0044 | BGE | RELATIVE | 3 | 2 | ----- | + | 2D 0045 | BLT | RELATIVE | 3 | 2 | ----- | + | 2E 0046 | BGT | RELATIVE | 3 | 2 | ----- | + | 2F 0047 | BLE | RELATIVE | 3 | 2 | ----- | + | 1021 4129 | LBRN | RELATIVE | 5(6) | 4 | ----- | + | 1022 4130 | LBHI | RELATIVE | 5(6) | 4 | ----- | + | 1023 4131 | LBLS | RELATIVE | 5(6) | 4 | ----- | + | 1024 4132 | LBHS/LBCC | RELATIVE | 5(6) | 4 | ----- | + | 1025 4133 | LBLO/LBCS | RELATIVE | 5(6) | 4 | ----- | + | 1026 4134 | LBNE | RELATIVE | 5(6) | 4 | ----- | + | 1027 4135 | LBEQ | RELATIVE | 5(6) | 4 | ----- | + | 1028 4136 | LBVC | RELATIVE | 5(6) | 4 | ----- | + | 1029 4137 | LBVS | RELATIVE | 5(6) | 4 | ----- | + | 102A 4138 | LBPL | RELATIVE | 5(6) | 4 | ----- | + | 102B 4139 | LBMI | RELATIVE | 5(6) | 4 | ----- | + | 102C 4140 | LBGE | RELATIVE | 5(6) | 4 | ----- | + | 102D 4141 | LBLT | RELATIVE | 5(6) | 4 | ----- | + | 102E 4142 | LBGT | RELATIVE | 5(6) | 4 | ----- | + | 102F 4143 | LBLE | RELATIVE | 5(6) | 4 | ----- | +*/ + +// Branch opcodes + +static void Op16(void) // LBRA { - tmp = regs.RdMem(regs.pc++); - WriteEXG(tmp&0xF, ReadEXG(tmp>>4)); - regs.clock += 7; + uint16_t offset = READ_IMM16; + regs.pc += offset; } static void Op20(void) // BRA { -// regs.pc += SignedB(regs.RdMem(regs.pc++)); // Branch always - regs.pc += (int16_t)(int8_t)regs.RdMem(regs.pc) + 1; // Branch always - - regs.clock += 3; + int16_t offset = (int16_t)(int8_t)READ_IMM; + regs.pc += offset; } static void Op21(void) // BRN { - regs.RdMem(regs.pc++); - - regs.clock += 3; + // This is basically a 2 byte NOP + int16_t offset = (int16_t)(int8_t)READ_IMM; } static void Op22(void) // BHI { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); + // !C && !Z + int16_t offset = (int16_t)(int8_t)READ_IMM; - if (!(regs.cc & 0x05)) - regs.pc += word; - - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION +//Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)... + regs.pc += offset * ((flagZ | flagC) ^ 0x01); +#else + if (!(flagZ || flagC)) + regs.pc += offset; +#endif } static void Op23(void) // BLS { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); - - if (regs.cc & 0x05) - regs.pc += word; + // C || Z + int16_t offset = (int16_t)(int8_t)READ_IMM; - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagZ | flagC); +#else + if (flagZ || flagC) + regs.pc += offset; +#endif } -static void Op24(void) // BCC (BHS) +static void Op24(void) // BHS/CC { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); + // !C + int16_t offset = (int16_t)(int8_t)READ_IMM; - if (!(regs.cc & 0x01)) - regs.pc += word; - - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagC ^ 0x01); +#else + if (!flagC) + regs.pc += offset; +#endif } -static void Op25(void) // BCS (BLO) +static void Op25(void) // BLO/CS { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); - - if (regs.cc & 0x01) - regs.pc += word; + // C + int16_t offset = (int16_t)(int8_t)READ_IMM; +//if (disasm) +// WriteLog("[offset=%04X,flagC=%08X]", offset, flagC); - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * flagC; +#else + if (flagC) + regs.pc += offset; +#endif } static void Op26(void) // BNE { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); + // !Z + int16_t offset = (int16_t)(int8_t)READ_IMM; - if (!(regs.cc & 0x04)) - regs.pc += word; - - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagZ ^ 0x01); +#else + if (!flagZ) + regs.pc += offset; +#endif } static void Op27(void) // BEQ { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); - - if (regs.cc & 0x04) - regs.pc += word; + // Z + int16_t offset = (int16_t)(int8_t)READ_IMM; - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * flagZ; +#else + if (flagZ) + regs.pc += offset; +#endif } static void Op28(void) // BVC { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); + // !V + int16_t offset = (int16_t)(int8_t)READ_IMM; - if (!(regs.cc & 0x02)) - regs.pc += word; - - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagV ^ 0x01); +#else + if (!flagV) + regs.pc += offset; +#endif } static void Op29(void) // BVS { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); - - if (regs.cc & 0x02) - regs.pc += word; + // V + int16_t offset = (int16_t)(int8_t)READ_IMM; - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * flagV; +#else + if (flagV) + regs.pc += offset; +#endif } static void Op2A(void) // BPL { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); + // !N + int16_t offset = (int16_t)(int8_t)READ_IMM; - if (!(regs.cc & 0x08)) - regs.pc += word; - - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagN ^ 0x01); +#else + if (!flagN) + regs.pc += offset; +#endif } static void Op2B(void) // BMI { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); - - if (regs.cc & 0x08) - regs.pc += word; + // N + int16_t offset = (int16_t)(int8_t)READ_IMM; - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * flagN; +#else + if (flagN) + regs.pc += offset; +#endif } static void Op2C(void) // BGE { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); + // (N && V) || (!N && !V) + int16_t offset = (int16_t)(int8_t)READ_IMM; - if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))) - regs.pc += word; - - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01))); +#else + if ((flagN && flagV) || (!flagN && !flagV)) + regs.pc += offset; +#endif } static void Op2D(void) // BLT { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); - - if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)) - regs.pc += word; + // (N && !V) || (!N && V) + int16_t offset = (int16_t)(int8_t)READ_IMM; - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV)); +#else + if ((flagN && !flagV) || (!flagN && flagV)) + regs.pc += offset; +#endif } static void Op2E(void) // BGT { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); + // (N && V && !Z) || (!N && !V && !Z) + int16_t offset = (int16_t)(int8_t)READ_IMM; - if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))) - regs.pc += word; - - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01))); +#else + if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ)) + regs.pc += offset; +#endif } static void Op2F(void) // BLE { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); - - if ((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))) - regs.pc += word; + // Z || (N && !V) || (!N && V) + int16_t offset = (int16_t)(int8_t)READ_IMM; - regs.clock += 3; +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV)); +#else + if (flagZ || (flagN && !flagV) || (!flagN && flagV)) + regs.pc += offset; +#endif } -static void Op30(void) // LEAX +static void Op1021(void) // LBRN { - regs.x = DecodeIDX(regs.RdMem(regs.pc++)); - (regs.x == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - regs.clock += 4; + // This is basically a 4 byte NOP + uint16_t offset = READ_IMM16; } -static void Op31(void) // LEAY + +static void Op1022(void) // LBHI { - regs.y = DecodeIDX(regs.RdMem(regs.pc++)); - (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - regs.clock += 4; + // !C && !Z + uint16_t offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION +//Not sure if the ! operator will do what we want, so we use ^ 1 (we need a 1 or a 0 here)... + regs.pc += offset * ((flagZ | flagC) ^ 0x01); +#else + if (!(flagZ || flagC)) + regs.pc += offset; +#endif } -static void Op32(void) // LEAS + +static void Op1023(void) // LBLS { - regs.s = DecodeIDX(regs.RdMem(regs.pc++)); - (regs.s == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - regs.clock += 4; + // C || Z + uint16_t offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagZ | flagC); +#else + if (flagZ || flagC) + regs.pc += offset; +#endif +} + +static void Op1024(void) // LBHS/CC +{ + // !C + uint16_t offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagC ^ 0x01); +#else + if (!flagC) + regs.pc += offset; +#endif +} + +static void Op1025(void) // LBLO/CS +{ + // C + uint16_t offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * flagC; +#else + if (flagC) + regs.pc += offset; +#endif +} + +static void Op1026(void) // LBNE +{ + // !Z + uint16_t offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagZ ^ 0x01); +#else + if (!flagZ) + regs.pc += offset; +#endif +} + +static void Op1027(void) // LBEQ +{ + // Z + uint16_t offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * flagZ; +#else + if (flagZ) + regs.pc += offset; +#endif +} + +static void Op1028(void) // LBVC +{ + // !V + uint16_t offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagV ^ 0x01); +#else + if (!flagV) + regs.pc += offset; +#endif +} + +static void Op1029(void) // LBVS +{ + // V + uint16_t offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * flagV; +#else + if (flagV) + regs.pc += offset; +#endif +} + +static void Op102A(void) // LBPL +{ + // !N + uint16_t offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagN ^ 0x01); +#else + if (!flagN) + regs.pc += offset; +#endif +} + +static void Op102B(void) // LBMI +{ + // N + uint16_t offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * flagN; +#else + if (flagN) + regs.pc += offset; +#endif +} + +static void Op102C(void) // LBGE +{ + // (N && V) || (!N && !V) + uint16_t offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * ((flagN & flagV) | ((flagN ^ 0x01) & (flagV ^ 0x01))); +#else + if ((flagN && flagV) || (!flagN && !flagV)) + regs.pc += offset; +#endif +} + +static void Op102D(void) // LBLT +{ + // (N && !V) || (!N && V) + uint16_t offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * ((flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV)); +#else + if ((flagN && !flagV) || (!flagN && flagV)) + regs.pc += offset; +#endif +} + +static void Op102E(void) // LBGT +{ + // (N && V && !Z) || (!N && !V && !Z) + uint16_t offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * ((flagN & flagV & (flagZ ^ 0x01)) | ((flagN ^ 0x01) & (flagV ^ 0x01) & (flagZ ^ 0x01))); +#else + if ((flagN && flagV && !flagZ) || (!flagN && !flagV && !flagZ)) + regs.pc += offset; +#endif +} + +static void Op102F(void) // LBLE +{ + // Z || (N && !V) || (!N && V) + uint16_t offset = READ_IMM16; + +#ifdef TEST_DONT_BRANCH_OPTIMIZATION + regs.pc += offset * (flagZ | (flagN & (flagV ^ 0x01)) | ((flagN ^ 0x01) & flagV)); +#else + if (flagZ || (flagN && !flagV) || (!flagN && flagV)) + regs.pc += offset; +#endif +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 85 0133 | BITA | IMMEDIATE | 2 | 2 | -aa0- | + | 95 0149 | BITA | DIRECT | 4 | 2 | -aa0- | + | A5 0165 | BITA | INDEXED | 4 | 2 | -aa0- | + | B5 0181 | BITA | EXTENDED | 5 | 3 | -aa0- | + | C5 0197 | BITB | IMMEDIATE | 2 | 2 | -aa0- | + | D5 0213 | BITB | DIRECT | 4 | 2 | -aa0- | + | E5 0229 | BITB | INDEXED | 4 | 2 | -aa0- | + | F5 0245 | BITB | EXTENDED | 5 | 3 | -aa0- | +*/ + +// BIT opcodes + +#define OP_BIT_HANDLER(m, acc) \ + uint8_t result = acc & (m); \ + SET_ZN(result); \ + CLR_V + +static void Op85(void) // BITA # +{ + uint8_t m = READ_IMM; + OP_BIT_HANDLER(m, regs.a); +} + +static void Op95(void) // BITA DP +{ + uint8_t m = READ_DP; + OP_BIT_HANDLER(m, regs.a); +} + +static void OpA5(void) // BITA IDX +{ + uint8_t m = READ_IDX; + OP_BIT_HANDLER(m, regs.a); +} + +static void OpB5(void) // BITA ABS +{ + uint8_t m = READ_ABS; + OP_BIT_HANDLER(m, regs.a); +} + +static void OpC5(void) // BITB # +{ + uint8_t m = READ_IMM; + OP_BIT_HANDLER(m, regs.b); +} + +static void OpD5(void) // BITB DP +{ + uint8_t m = READ_DP; + OP_BIT_HANDLER(m, regs.b); +} + +static void OpE5(void) // BITB IDX +{ + uint8_t m = READ_IDX; + OP_BIT_HANDLER(m, regs.b); +} + +static void OpF5(void) // BITB ABS +{ + uint8_t m = READ_ABS; + OP_BIT_HANDLER(m, regs.b); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 0F 0015 | CLR | DIRECT | 6 | 2 | -0100 | + | 4F 0079 | CLRA | INHERENT | 2 | 1 | -0100 | + | 5F 0095 | CLRB | INHERENT | 2 | 1 | -0100 | + | 6F 0111 | CLR | INDEXED | 6 | 2 | -0100 | + | 7F 0127 | CLR | EXTENDED | 7 | 3 | -0100 | +*/ + +// CLR opcodes + +#define OP_CLR_HANDLER(m) \ + flagN = flagV = flagC = 0; \ + flagZ = 1; \ + m = 0 + +static void Op0F(void) // CLR DP +{ + uint8_t m; + READ_DP_WB(m); + OP_CLR_HANDLER(m); + WRITE_BACK(m); +} + +static void Op4F(void) // CLRA +{ + OP_CLR_HANDLER(regs.a); +} + +static void Op5F(void) // CLRB +{ + OP_CLR_HANDLER(regs.b); +} + +static void Op6F(void) // CLR IDX +{ + uint8_t m; + READ_IDX_WB(m); + OP_CLR_HANDLER(m); + WRITE_BACK(m); +} + +static void Op7F(void) // CLR ABS +{ + uint8_t m; + READ_ABS_WB(m); + OP_CLR_HANDLER(m); + WRITE_BACK(m); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 81 0129 | CMPA | IMMEDIATE | 2 | 2 | uaaaa | + | 8C 0140 | CMPX | IMMEDIATE | 4 | 3 | -aaaa | + | 91 0145 | CMPA | DIRECT | 4 | 2 | uaaaa | + | 9C 0156 | CMPX | DIRECT | 6 | 2 | -aaaa | + | A1 0161 | CMPA | INDEXED | 4 | 2 | uaaaa | + | AC 0172 | CMPX | INDEXED | 6 | 2 | -aaaa | + | B1 0177 | CMPA | EXTENDED | 5 | 3 | uaaaa | + | BC 0188 | CMPX | EXTENDED | 7 | 3 | -aaaa | + | C1 0193 | CMPB | IMMEDIATE | 2 | 2 | uaaaa | + | D1 0209 | CMPB | DIRECT | 4 | 2 | uaaaa | + | E1 0225 | CMPB | INDEXED | 4 | 2 | uaaaa | + | F1 0241 | CMPB | EXTENDED | 5 | 3 | uaaaa | + | 1083 4227 | CMPD | IMMEDIATE | 5 | 4 | -aaaa | + | 108C 4236 | CMPY | IMMEDIATE | 5 | 4 | -aaaa | + | 1093 4243 | CMPD | DIRECT | 7 | 3 | -aaaa | + | 109C 4252 | CMPY | DIRECT | 7 | 3 | -aaaa | + | 10A3 4259 | CMPD | INDEXED | 7 | 3 | -aaaa | + | 10AC 4268 | CMPY | INDEXED | 7 | 3 | -aaaa | + | 10B3 4275 | CMPD | EXTENDED | 8 | 4 | -aaaa | + | 10BC 4284 | CMPY | EXTENDED | 8 | 4 | -aaaa | + | 1183 4438 | CMPU | IMMEDIATE | 5 | 4 | -aaaa | + | 118C 4492 | CMPS | IMMEDIATE | 5 | 4 | -aaaa | + | 1193 4499 | CMPU | DIRECT | 7 | 3 | -aaaa | + | 119C 4508 | CMPS | DIRECT | 7 | 3 | -aaaa | + | 11A3 4515 | CMPU | INDEXED | 7 | 3 | -aaaa | + | 11AC 4524 | CMPS | INDEXED | 7 | 3 | -aaaa | + | 11B3 4531 | CMPU | EXTENDED | 8 | 4 | -aaaa | + | 11BC 4540 | CMPS | EXTENDED | 8 | 4 | -aaaa | +*/ + +// CMP opcodes + +#define OP_CMP_HANDLER(m, acc) \ + uint16_t sum = (uint16_t)(acc) - (m); \ + flagC = (sum >> 8) & 0x01; \ + SET_V(m, acc, sum); \ + SET_ZN(sum) + +#define OP_CMP_HANDLER16(m, acc) \ + uint32_t sum = (uint32_t)(acc) - (m); \ + flagC = (sum >> 16) & 0x01; \ + SET_V16(m, acc, sum); \ + SET_ZN16(sum) + +static void Op81(void) // CMPA # +{ + uint8_t m = READ_IMM; + OP_CMP_HANDLER(m, regs.a); +} + +static void Op8C(void) // CMPX # +{ + uint16_t m = READ_IMM16; + OP_CMP_HANDLER16(m, regs.x); +} + +static void Op91(void) // CMPA DP +{ + uint8_t m = READ_DP; + OP_CMP_HANDLER(m, regs.a); +} + +static void Op9C(void) // CMPX DP +{ + uint16_t m = READ_DP16; + OP_CMP_HANDLER16(m, regs.x); +} + +static void OpA1(void) // CMPA IDX +{ + uint8_t m = READ_IDX; + OP_CMP_HANDLER(m, regs.a); +} + +static void OpAC(void) // CMPX IDX +{ + uint16_t m = READ_IDX16; + OP_CMP_HANDLER16(m, regs.x); +} + +static void OpB1(void) // CMPA ABS +{ + uint8_t m = READ_ABS; + OP_CMP_HANDLER(m, regs.a); +} + +static void OpBC(void) // CMPX ABS +{ + uint16_t m = READ_ABS16; + OP_CMP_HANDLER16(m, regs.x); +} + +static void OpC1(void) // CMPB # +{ + uint8_t m = READ_IMM; + OP_CMP_HANDLER(m, regs.b); +} + +static void OpD1(void) // CMPB DP +{ + uint8_t m = READ_DP; + OP_CMP_HANDLER(m, regs.b); +} + +static void OpE1(void) // CMPB IDX +{ + uint8_t m = READ_IDX; + OP_CMP_HANDLER(m, regs.b); +} + +static void OpF1(void) // CMPB ABS +{ + uint8_t m = READ_ABS; + OP_CMP_HANDLER(m, regs.b); +} + +static void Op1083(void) // CMPD # +{ + uint16_t m = READ_IMM16; + OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b); +} + +static void Op108C(void) // CMPY # +{ + uint16_t m = READ_IMM16; + OP_CMP_HANDLER16(m, regs.y); +} + +static void Op1093(void) // CMPD DP +{ + uint16_t m = READ_DP16; + OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b); +} + +static void Op109C(void) // CMPY DP +{ + uint16_t m = READ_DP16; + OP_CMP_HANDLER16(m, regs.y); +} + +static void Op10A3(void) // CMPD IDX +{ + uint16_t m = READ_IDX16; + OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b); +} + +static void Op10AC(void) // CMPY IDX +{ + uint16_t m = READ_IDX16; + OP_CMP_HANDLER16(m, regs.y); +} + +static void Op10B3(void) // CMPD ABS +{ + uint16_t m = READ_ABS16; + OP_CMP_HANDLER16(m, (regs.a << 8) | regs.b); +} + +static void Op10BC(void) // CMPY ABS +{ + uint16_t m = READ_ABS16; + OP_CMP_HANDLER16(m, regs.y); +} + +static void Op1183(void) // CMPU # +{ + uint16_t m = READ_IMM16; + OP_CMP_HANDLER16(m, regs.u); +} + +static void Op118C(void) // CMPS # +{ + uint16_t m = READ_IMM16; + OP_CMP_HANDLER16(m, regs.s); +} + +static void Op1193(void) // CMPU DP +{ + uint16_t m = READ_DP16; + OP_CMP_HANDLER16(m, regs.u); +} + +static void Op119C(void) // CMPS DP +{ + uint16_t m = READ_DP16; + OP_CMP_HANDLER16(m, regs.s); +} + +static void Op11A3(void) // CMPU IDX +{ + uint16_t m = READ_IDX16; + OP_CMP_HANDLER16(m, regs.u); +} + +static void Op11AC(void) // CMPS IDX +{ + uint16_t m = READ_IDX16; + OP_CMP_HANDLER16(m, regs.s); +} + +static void Op11B3(void) // CMPU ABS +{ + uint16_t m = READ_ABS16; + OP_CMP_HANDLER16(m, regs.u); +} + +static void Op11BC(void) // CMPS ABS +{ + uint16_t m = READ_ABS16; + OP_CMP_HANDLER16(m, regs.s); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 03 0003 | COM | DIRECT | 6 | 2 | -aa01 | + | 43 0067 | COMA | INHERENT | 2 | 1 | -aa01 | + | 53 0083 | COMB | INHERENT | 2 | 1 | -aa01 | + | 63 0099 | COM | INDEXED | 6 | 2 | -aa01 | + | 73 0115 | COM | EXTENDED | 7 | 3 | -aa01 | +*/ + +// COM opcodes + +#define OP_COM_HANDLER(m) \ + m = ~m; \ + SET_ZN(m); \ + flagC = 1; \ + flagV = 0 + +static void Op03(void) // COM DP +{ + uint8_t m; + READ_DP_WB(m); + OP_COM_HANDLER(m); + WRITE_BACK(m); +} + +static void Op43(void) // COMA +{ + OP_COM_HANDLER(regs.a); +} + +static void Op53(void) // COMB +{ + OP_COM_HANDLER(regs.b); +} + +static void Op63(void) // COM IDX +{ + uint8_t m; + READ_IDX_WB(m); + OP_COM_HANDLER(m); + WRITE_BACK(m); +} + +static void Op73(void) // COM ABS +{ + uint8_t m; + READ_ABS_WB(m); + OP_COM_HANDLER(m); + WRITE_BACK(m); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 13 0019 | SYNC | INHERENT | 2 | 1 | ----- | + | 3C 0060 | CWAI | INHERENT | 21 | 2 | ddddd | + | 3E 0062 | RESET* | INHERENT | * | 1 | ***** | + | 3F 0063 | SWI | INHERENT | 19 | 1 | ----- | + | 103F 4159 | SWI2 | INHERENT | 20 | 2 | ----- | + | 113F 4415 | SWI3 | INHERENT | 20 | 2 | ----- | +*/ + +static void Op13(void) // SYNC +{ +#warning "!!! SYNC not implemented !!!" +#if 0 + /* SYNC stops processing instructions until an interrupt request happens. */ + /* This doesn't require the corresponding interrupt to be enabled: if it */ + /* is disabled, execution continues with the next instruction. */ + m68_state->int_state |= M6809_SYNC; /* HJB 990227 */ + check_irq_lines(m68_state); + /* if M6809_SYNC has not been cleared by check_irq_lines(m68_state), + * stop execution until the interrupt lines change. */ + if( m68_state->int_state & M6809_SYNC ) + if (m68_state->icount > 0) m68_state->icount = 0; +#endif +} + +static void Op3C(void) // CWAI +{ +#warning "!!! CWAI not implemented !!!" +#if 0 + UINT8 t; + IMMBYTE(t); + CC &= t; + /* + * CWAI stacks the entire machine state on the hardware stack, + * then waits for an interrupt; when the interrupt is taken + * later, the state is *not* saved again after CWAI. + */ + CC |= CC_E; /* HJB 990225: save entire state */ + PUSHWORD(pPC); + PUSHWORD(pU); + PUSHWORD(pY); + PUSHWORD(pX); + PUSHBYTE(DP); + PUSHBYTE(B); + PUSHBYTE(A); + PUSHBYTE(CC); + m68_state->int_state |= M6809_CWAI; /* HJB 990228 */ + check_irq_lines(m68_state); /* HJB 990116 */ + if( m68_state->int_state & M6809_CWAI ) + if( m68_state->icount > 0 ) + m68_state->icount = 0; +#endif +} + +static void Op3E(void) // RESET +{ + regs.cpuFlags |= V6809_ASSERT_LINE_RESET; +} + +static void Op3F(void) // SWI +{ + flagE = 1; + regs.cc = PACK_FLAGS; // Mash flags into CC byte + PUSHS16(regs.pc); + PUSHS16(regs.u); + PUSHS16(regs.y); + PUSHS16(regs.x); + PUSHS(regs.dp); + PUSHS(regs.b); + PUSHS(regs.a); + PUSHS(regs.cc); + flagF = flagI = 1; + regs.pc = RdMemW(0xFFFA); +} + +static void Op103F(void) // SWI2 +{ + flagE = 1; + regs.cc = PACK_FLAGS; // Mash flags into CC byte + PUSHS16(regs.pc); + PUSHS16(regs.u); + PUSHS16(regs.y); + PUSHS16(regs.x); + PUSHS(regs.dp); + PUSHS(regs.b); + PUSHS(regs.a); + PUSHS(regs.cc); + regs.pc = RdMemW(0xFFF4); +} + +static void Op113F(void) // SWI3 +{ + flagE = 1; + regs.cc = PACK_FLAGS; // Mash flags into CC byte + PUSHS16(regs.pc); + PUSHS16(regs.u); + PUSHS16(regs.y); + PUSHS16(regs.x); + PUSHS(regs.dp); + PUSHS(regs.b); + PUSHS(regs.a); + PUSHS(regs.cc); + regs.pc = RdMemW(0xFFF2); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 12 0018 | NOP | INHERENT | 2 | 1 | ----- | + | 19 0025 | DAA | INHERENT | 2 | 1 | -aa0a | + | 1A 0026 | ORCC | IMMEDIATE | 3 | 2 | ddddd | + | 1C 0028 | ANDCC | IMMEDIATE | 3 | 2 | ddddd | + | 1D 0029 | SEX | INHERENT | 2 | 1 | -aa0- | +*/ + +static void Op12() // NOP +{ +} + +/* +D3F8: A6 47 LDA (7),U CC=--H----- A=30 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FA +D3FA: 8B 01 ADDA #$01 CC=--H----- A=31 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FC +D3FC: 19 DAA CC=--H----- A=37 B=00 DP=9C X=3C72 Y=CE5C S=BFFF U=BAF0 PC=D3FD +*/ + +static void Op19() // DAA +{ + uint16_t result = (uint16_t)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_t)result; + SET_ZN(result); + CLR_V; + flagC |= (result & 0x100) >> 8; // Overwrite carry if it was 0, otherwise, ignore +} + +static void Op1A() // ORCC +{ + regs.cc = PACK_FLAGS; // Mash flags back into the CC register + regs.cc |= READ_IMM; + UNPACK_FLAGS; // & unmash 'em +} + +static void Op1C() // ANDCC +{ + regs.cc = PACK_FLAGS; // Mash flags back into the CC register + regs.cc &= READ_IMM; + UNPACK_FLAGS; // & unmash 'em +} + +static void Op1D() // SEX +{ + regs.a = (regs.b & 0x80 ? 0xFF : 0x00); + SET_ZN16((regs.a << 8) | regs.b); + CLR_V; +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 0A 0010 | DEC | DIRECT | 6 | 2 | -aaa- | + | 4A 0074 | DECA | INHERENT | 2 | 1 | -aaa- | + | 5A 0090 | DECB | INHERENT | 2 | 1 | -aaa- | + | 6A 0106 | DEC | INDEXED | 6 | 2 | -aaa- | + | 7A 0122 | DEC | EXTENDED | 7 | 3 | -aaa- | +*/ + +// DEC opcodes (If we went from $80 -> $7F, sign overflowed.) + +#define OP_DEC_HANDLER(m) \ + m--; \ + SET_ZN(m); \ + flagV = (m == 0x7F ? 1 : 0) + +static void Op0A(void) // DEC DP +{ + uint8_t m; + READ_DP_WB(m); + OP_DEC_HANDLER(m); + WRITE_BACK(m); +} + +static void Op4A(void) // DECA +{ + OP_DEC_HANDLER(regs.a); +} + +static void Op5A(void) // DECB +{ + OP_DEC_HANDLER(regs.b); +} + +static void Op6A(void) // DEC IDX +{ + uint8_t m; + READ_IDX_WB(m); + OP_DEC_HANDLER(m); + WRITE_BACK(m); +} + +static void Op7A(void) // DEC ABS +{ + uint8_t m; + READ_ABS_WB(m); + OP_DEC_HANDLER(m); + WRITE_BACK(m); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 88 0136 | EORA | IMMEDIATE | 2 | 2 | -aa0- | + | 98 0152 | EORA | DIRECT | 4 | 2 | -aa0- | + | A8 0168 | EORA | INDEXED | 4 | 2 | -aa0- | + | B8 0184 | EORA | EXTENDED | 5 | 3 | -aa0- | + | C8 0200 | EORB | IMMEDIATE | 2 | 2 | -aa0- | + | D8 0216 | EORB | DIRECT | 4 | 2 | -aa0- | + | E8 0232 | EORB | INDEXED | 4 | 2 | -aa0- | + | F8 0248 | EORB | EXTENDED | 5 | 3 | -aa0- | +*/ + +// EOR opcodes + +#define OP_EOR_HANDLER(m, acc) \ + acc ^= (m); \ + SET_ZN(acc); \ + CLR_V + +static void Op88(void) // EORA # +{ + uint8_t m = READ_IMM; + OP_EOR_HANDLER(m, regs.a); +} + +static void Op98(void) // EORA DP +{ + uint8_t m = READ_DP; + OP_EOR_HANDLER(m, regs.a); +} + +static void OpA8(void) // EORA IDX +{ + uint8_t m = READ_IDX; + OP_EOR_HANDLER(m, regs.a); +} + +static void OpB8(void) // EORA ABS +{ + uint8_t m = READ_ABS; + OP_EOR_HANDLER(m, regs.a); +} + +static void OpC8(void) // EORB # +{ + uint8_t m = READ_IMM; + OP_EOR_HANDLER(m, regs.b); +} + +static void OpD8(void) // EORB DP +{ + uint8_t m = READ_DP; + OP_EOR_HANDLER(m, regs.b); +} + +static void OpE8(void) // EORB IDX +{ + uint8_t m = READ_IDX; + OP_EOR_HANDLER(m, regs.b); +} + +static void OpF8(void) // EORB ABS +{ + uint8_t m = READ_ABS; + OP_EOR_HANDLER(m, regs.b); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 0C 0012 | INC | DIRECT | 6 | 2 | -aaa- | + | 4C 0076 | INCA | INHERENT | 2 | 1 | -aaa- | + | 5C 0092 | INCB | INHERENT | 2 | 1 | -aaa- | + | 6C 0108 | INC | INDEXED | 6 | 2 | -aaa- | + | 7C 0124 | INC | EXTENDED | 7 | 3 | -aaa- | +*/ + +// INC opcodes (If we went from $7F -> $80, sign overflowed.) + +#define OP_INC_HANDLER(m) \ + m++; \ + SET_ZN(m); \ + flagV = (m == 0x80 ? 1 : 0) + +static void Op0C(void) // INC DP +{ + uint8_t m; + READ_DP_WB(m); + OP_INC_HANDLER(m); + WRITE_BACK(m); +} + + +static void Op4C(void) // INCA +{ + OP_INC_HANDLER(regs.a); +} + + +static void Op5C(void) // INCB +{ + OP_INC_HANDLER(regs.b); +} + + +static void Op6C(void) // INC IDX +{ + uint8_t m; + READ_IDX_WB(m); + OP_INC_HANDLER(m); + WRITE_BACK(m); +} + + +static void Op7C(void) // INC ABS +{ + uint8_t m; + READ_ABS_WB(m); + OP_INC_HANDLER(m); + WRITE_BACK(m); +} + + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 0E 0014 | JMP | DIRECT | 3 | 2 | ----- | + | 17 0023 | LBSR | RELATIVE | 9 | 3 | ----- | + | 39 0057 | RTS | INHERENT | 5 | 1 | ----- | + | 3B 0059 | RTI | INHERENT | 6/15 | 1 | ----- | + | 6E 0110 | JMP | INDEXED | 3 | 2 | ----- | + | 7E 0126 | JMP | EXTENDED | 3 | 3 | ----- | + | 8D 0141 | BSR | RELATIVE | 7 | 2 | ----- | + | 9D 0157 | JSR | DIRECT | 7 | 2 | ----- | + | AD 0173 | JSR | INDEXED | 7 | 2 | ----- | + | BD 0189 | JSR | EXTENDED | 8 | 3 | ----- | +*/ + +static void Op0E(void) // JMP DP +{ + // This needs to be separate because of the EA_DP adding to regs.pc. + uint16_t m = EA_DP; + regs.pc = m; +} + + +static void Op17(void) // LBSR +{ + uint16_t word = FetchMemW(regs.pc); + PUSHS16(regs.pc); + regs.pc += word; } -static void Op33(void) // LEAU + + +static void Op39(void) // RTS { - regs.u = DecodeIDX(regs.RdMem(regs.pc++)); - (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - regs.clock += 4; + PULLS16(regs.pc); } -static void Op34(void) // PSHS + + +static void Op3B(void) // RTI { - tmp = regs.RdMem(regs.pc++); - if (tmp&0x80) { regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); } - if (tmp&0x40) { regs.WrMem(--regs.s, regs.u&0xFF); regs.WrMem(--regs.s, regs.u>>8); } - if (tmp&0x20) { regs.WrMem(--regs.s, regs.y&0xFF); regs.WrMem(--regs.s, regs.y>>8); } - if (tmp&0x10) { regs.WrMem(--regs.s, regs.x&0xFF); regs.WrMem(--regs.s, regs.x>>8); } - if (tmp&0x08) regs.WrMem(--regs.s, regs.dp); - if (tmp&0x04) regs.WrMem(--regs.s, regs.b); - if (tmp&0x02) regs.WrMem(--regs.s, regs.a); - if (tmp&0x01) regs.WrMem(--regs.s, regs.cc); - regs.clock += 5; + PULLS(regs.cc); + UNPACK_FLAGS; + + // If E flag set, pull all regs + if (flagE) + { + PULLS(regs.a); + PULLS(regs.b); + PULLS(regs.dp); + PULLS16(regs.x); + PULLS16(regs.y); + PULLS16(regs.u); + regs.clock += 9; + } + + PULLS16(regs.pc); } -static void Op35(void) // PULS + + +static void Op6E(void) // JMP IDX { - tmp = regs.RdMem(regs.pc++); - if (tmp&0x01) regs.cc = regs.RdMem(regs.s++); - if (tmp&0x02) regs.a = regs.RdMem(regs.s++); - if (tmp&0x04) regs.b = regs.RdMem(regs.s++); - if (tmp&0x08) regs.dp = regs.RdMem(regs.s++); - if (tmp&0x10) regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); - if (tmp&0x20) regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); - if (tmp&0x40) regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); - if (tmp&0x80) regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); - regs.clock += 5; + regs.pc = EA_IDX; } -static void Op36(void) // PSHU + +static void Op7E(void) // JMP ABS { - tmp = regs.RdMem(regs.pc++); + regs.pc = EA_ABS; +} - if (tmp & 0x80) { regs.WrMem(--regs.u, regs.pc & 0xFF); regs.WrMem(--regs.u, regs.pc >> 8); } - if (tmp & 0x40) { regs.WrMem(--regs.u, regs.s & 0xFF); regs.WrMem(--regs.u, regs.s >> 8); } - if (tmp & 0x20) { regs.WrMem(--regs.u, regs.y & 0xFF); regs.WrMem(--regs.u, regs.y >> 8); } - if (tmp & 0x10) { regs.WrMem(--regs.u, regs.x & 0xFF); regs.WrMem(--regs.u, regs.x >> 8); } - if (tmp & 0x08) regs.WrMem(--regs.u, regs.dp); - if (tmp & 0x04) regs.WrMem(--regs.u, regs.b); - if (tmp & 0x02) regs.WrMem(--regs.u, regs.a); - if (tmp & 0x01) regs.WrMem(--regs.u, regs.cc); - regs.clock += 5; +static void Op8D(void) // BSR +{ + uint16_t word = (int16_t)(int8_t)READ_IMM; + PUSHS16(regs.pc); + regs.pc += word; } -static void Op37(void) // PULU + +static void Op9D(void) // JSR DP { - tmp = regs.RdMem(regs.pc++); - if (tmp&0x01) regs.cc = regs.RdMem(regs.u++); - if (tmp&0x02) regs.a = regs.RdMem(regs.u++); - if (tmp&0x04) regs.b = regs.RdMem(regs.u++); - if (tmp&0x08) regs.dp = regs.RdMem(regs.u++); - if (tmp&0x10) regs.x = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++); - if (tmp&0x20) regs.y = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++); - if (tmp&0x40) regs.s = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++); - if (tmp&0x80) regs.pc = (regs.RdMem(regs.u++)<<8) | regs.RdMem(regs.u++); - regs.clock += 5; + uint16_t word = EA_DP; + PUSHS16(regs.pc); + regs.pc = word; } -static void Op39(void) // RTS + + +static void OpAD(void) // JSR IDX { - regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); - regs.clock += 5; + uint16_t word = EA_IDX; + PUSHS16(regs.pc); + regs.pc = word; } -static void Op3A(void) // ABX + + +static void OpBD(void) // JSR ABS { - regs.x += regs.b; - regs.clock += 3; + uint16_t word = EA_ABS; + PUSHS16(regs.pc); + regs.pc = word; } -static void Op3B(void) // RTI + + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 1E 0030 | EXG | INHERENT | 8 | 2 | ccccc | + | 1F 0031 | TFR | INHERENT | 7 | 2 | ccccc | +*/ + +static void Op1E(void) // EXG { - regs.cc = regs.RdMem(regs.s++); - if (regs.cc&0x80) // If E flag set, pull all regs - { - regs.a = regs.RdMem(regs.s++); regs.b = regs.RdMem(regs.s++); regs.dp = regs.RdMem(regs.s++); - regs.x = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); - regs.y = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); - regs.u = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); - regs.clock += 15; - } - else - { - regs.clock += 6; - } - regs.pc = (regs.RdMem(regs.s++)<<8) | regs.RdMem(regs.s++); -} -static void Op3C(void) // CWAI -{ - regs.cc &= regs.RdMem(regs.pc++); regs.cc |= 0x80; - regs.clock += 1000000; // Force interrupt -} -static void Op3D(void) // MUL -{ - addr = regs.a * regs.b; regs.a = addr>>8; regs.b = addr&0xFF; - (addr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero - (regs.b&0x80 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry - regs.clock += 11; -} -static void Op3E(void) // RESET -{ -} -static void Op3F(void) // SWI -{ -} -static void Op40(void) // NEGA -{ - regs.a = 256 - regs.a; - (regs.a > 0x7F ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust carry - (regs.a == 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 - regs.clock += 2; -} -static void Op43(void) // COMA -{ - regs.a ^= 0xFF; - regs.cc &= 0xFD; regs.cc |= 0x01; // CLV, SEC - (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.clock += 2; -} -static void Op44(void) // LSRA -{ - (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 - regs.clock += 2; -} -static void Op46(void) // RORA -{ - 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 - regs.clock += 2; -} -static void Op47(void) // ASRA -{ - (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 - regs.clock += 2; -} -static void Op48(void) // LSLA [Keep checking from here...] -{ - (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 - regs.clock += 2; -} -static void Op49(void) // ROLA -{ - 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 - regs.clock += 2; -} -static void Op4A(void) // DECA -{ - 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 - regs.clock += 2; -} -static void Op4C(void) // INCA - { - 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 - regs.clock += 2; - } -static void Op4D(void) // TSTA - { - 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 - regs.clock += 2; - } -static void Op4F(void) // CLRA -{ - regs.a = 0; - regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC - regs.clock += 2; -} -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 - regs.clock += 2; - } -static void Op53(void) // COMB - { - 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 - regs.clock += 2; - } -static void Op54(void) // LSRB - { - (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 - regs.clock += 2; - } -static void Op56(void) // RORB - { - 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 - regs.clock += 2; - } -static void Op57(void) // ASRB - { - (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 - regs.clock += 2; - } -static void Op58(void) // LSLB - { - (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 - regs.clock += 2; - } -static void Op59(void) // ROLB -{ - 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 - regs.clock += 2; -} -static void Op5A(void) // DECB - { - 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 - regs.clock += 2; - } -static void Op5C(void) // INCB - { - 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 - regs.clock += 2; - } -static void Op5D(void) // TSTB - { - 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 - regs.clock += 2; - } -static void Op5F(void) // CLRB - { - regs.b = 0; - regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC - regs.clock += 2; - } -static void Op60(void) // NEG IDX - { - addr = DecodeIDX(regs.RdMem(regs.pc++)); - tmp = regs.RdMem(addr); uint8_t 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 - regs.clock += 6; - } -static void Op63(void) // COM IDX - { - 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 - regs.clock += 6; - } -static void Op64(void) // LSR IDX - { - 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 - regs.clock += 6; - } -static void Op66(void) // ROR IDX - { - addr = DecodeIDX(regs.RdMem(regs.pc++)); - tmp = regs.RdMem(addr); uint8_t 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 - regs.clock += 6; - } -static void Op67(void) // ASR IDX - { - 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 - regs.clock += 6; - } -static void Op68(void) // LSL IDX - { - 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 - regs.clock += 6; - } -static void Op69(void) // ROL IDX -{ - uint8_t 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 - regs.clock += 6; -} -static void Op6A(void) // DEC IDX - { - uint8_t tmp; uint16_t 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 - regs.clock += 6; - } -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 - regs.clock += 6; - } -static void Op6D(void) // TST IDX - { - 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 - regs.clock += 6; - } -static void Op6E(void) // JMP IDX -{ - regs.pc = DecodeIDX(regs.RdMem(regs.pc++)); - regs.clock += 3; -} -static void Op6F(void) // CLR IDX -{ - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.WrMem(addr, 0); - regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC - regs.clock += 6; -} -static void Op70(void) // NEG ABS - { - addr = FetchW(); - tmp = regs.RdMem(addr); uint8_t 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 - regs.clock += 7; - } -static void Op73(void) // COM ABS - { - 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 - regs.clock += 7; - } -static void Op74(void) // LSR ABS - { - 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 - regs.clock += 7; - } -static void Op76(void) // ROR ABS - { - uint8_t tmp; uint16_t addr; - addr = FetchW(); - tmp = regs.RdMem(addr); uint8_t 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 - regs.clock += 7; - } -static void Op77(void) // ASR ABS - { - uint8_t tmp; uint16_t 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 - regs.clock += 7; - } -static void Op78(void) // LSL ABS - { - uint8_t tmp; uint16_t 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 - regs.clock += 7; - } -static void Op79(void) // ROL ABS -{ - uint8_t 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 - regs.clock += 7; -} -static void Op7A(void) // DEC ABS - { - uint8_t tmp; uint16_t 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 - regs.clock += 7; - } -static void Op7C(void) // INC ABS - { - uint8_t tmp; uint16_t addr; - addr = FetchW(); - 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 - regs.clock += 7; - } - -static void Op7D(void) // TST ABS -{ - uint8_t 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.clock += 7; -} - -static void Op7E(void) // JMP ABS -{ - regs.pc = FetchW(); - regs.clock += 3; -} -static void Op7F(void) // CLR ABS - { - regs.WrMem(FetchW(), 0); - regs.cc &= 0xF0; regs.cc |= 0x04; // Set NZVC - regs.clock += 7; - } -static void Op80(void) // SUBA # -{ - uint8_t tmp = regs.RdMem(regs.pc++); uint8_t 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 - regs.clock += 2; -} -static void Op81(void) // CMPA # -{ - tmp = regs.RdMem(regs.pc++); - uint8_t 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 - regs.clock += 2; -} -static void Op82(void) // SBCA # -{ - tmp = regs.RdMem(regs.pc++); uint8_t 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 - regs.clock += 2; -} -static void Op83(void) // SUBD # -{ - addr = FetchW(); uint16_t dr = (regs.a<<8)|regs.b, ds = dr; - dr -= addr; - (ds < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.a = dr>>8; regs.b = dr&0xFF; - regs.clock += 4; + // If bit 3 & 7 are not equal, $FF is the result (undocumented)... + + uint8_t m = READ_IMM; + uint8_t reg1 = m >> 4, reg2 = m & 0x0F; + uint16_t acc1 = ReadEXG(reg1); + uint16_t acc2 = ReadEXG(reg2); + + // If bit 3 & 7 are not equal, $FF is the result (undocumented)... + if (((m >> 4) ^ m) & 0x08) + acc1 = acc2 = 0xFF; + + WriteEXG(reg1, acc2); + WriteEXG(reg2, acc1); } -static void Op84(void) // ANDA # - { - regs.a &= regs.RdMem(regs.pc++); - 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 - regs.clock += 2; - } -static void Op85(void) // BITA # - { - tmp = regs.a & 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 - regs.clock += 2; - } -static void Op86(void) // LDA # - { - 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 - regs.clock += 2; - } -static void Op88(void) // EORA # - { - 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 - regs.clock += 2; - } -static void Op89(void) // ADCA # -{ - tmp = regs.RdMem(regs.pc++); - addr = (uint16_t)regs.a + (uint16_t)tmp + (uint16_t)(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 - regs.clock += 2; -} -static void Op8A(void) // ORA # - { - 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 - regs.clock += 2; - } -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)&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); // Set Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag - regs.clock += 2; + +static void Op1F(void) // TFR +{ + uint8_t m = READ_IMM; + uint16_t acc = ReadEXG(m >> 4); + + // If bit 3 & 7 are not equal, $FF is the result (undocumented)... + if (((m >> 4) ^ m) & 0x08) + acc = 0xFF; + + WriteEXG(m & 0x0F, acc); } -static void Op8C(void) // CMPX # + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 86 0134 | LDA | IMMEDIATE | 2 | 2 | -aa0- | + | 8E 0142 | LDX | IMMEDIATE | 3 | 3 | -aa0- | + | 96 0150 | LDA | DIRECT | 4 | 2 | -aa0- | + | 9E 0158 | LDX | DIRECT | 5 | 2 | -aa0- | + | A6 0166 | LDA | INDEXED | 4 | 2 | -aa0- | + | AE 0174 | LDX | INDEXED | 5 | 2 | -aa0- | + | B6 0182 | LDA | EXTENDED | 5 | 3 | -aa0- | + | BE 0190 | LDX | EXTENDED | 6 | 3 | -aa0- | + | C6 0198 | LDB | IMMEDIATE | 2 | 2 | -aa0- | + | CC 0204 | LDD | IMMEDIATE | 3 | 3 | -aa0- | + | CE 0206 | LDU | IMMEDIATE | 3 | 3 | -aa0- | + | D6 0214 | LDB | DIRECT | 4 | 2 | -aa0- | + | DC 0220 | LDD | DIRECT | 5 | 2 | -aa0- | + | DE 0222 | LDU | DIRECT | 5 | 2 | -aa0- | + | E6 0230 | LDB | INDEXED | 4 | 2 | -aa0- | + | EC 0236 | LDD | INDEXED | 5 | 2 | -aa0- | + | EE 0238 | LDU | INDEXED | 5 | 2 | -aa0- | + | F6 0246 | LDB | EXTENDED | 5 | 3 | -aa0- | + | FC 0252 | LDD | EXTENDED | 6 | 3 | -aa0- | + | FE 0254 | LDU | EXTENDED | 6 | 3 | -aa0- | + | 108E 4238 | LDY | IMMEDIATE | 4 | 4 | -aa0- | + | 109E 4254 | LDY | DIRECT | 6 | 3 | -aa0- | + | 10AE 4270 | LDY | INDEXED | 6 | 3 | -aa0- | + | 10BE 4286 | LDY | EXTENDED | 7 | 4 | -aa0- | + | 10CE 4302 | LDS | IMMEDIATE | 4 | 4 | -aa0- | + | 10DE 4318 | LDS | DIRECT | 6 | 3 | -aa0- | + | 10EE 4334 | LDS | INDEXED | 6 | 3 | -aa0- | + | 10FE 4350 | LDS | EXTENDED | 7 | 4 | -aa0- | +*/ + +// LDA opcodes + +#define OP_LDA_HANDLER(m, acc) \ + acc = m; \ + CLR_V; \ + SET_ZN(acc) + +#define OP_LDA_HANDLER16(m, acc) \ + acc = m; \ + CLR_V; \ + SET_ZN16(acc) + +#define OP_LDA_HANDLER16D(m) \ + regs.a = (m >> 8); \ + regs.b = m & 0xFF; \ + CLR_V; \ + SET_ZN16(m) + +static void Op86(void) // LDA # { - addr = FetchW(); - uint16_t 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 - regs.clock += 4; + uint8_t m = READ_IMM; + OP_LDA_HANDLER(m, regs.a); } -static void Op8D(void) // Bregs.s +static void Op8E(void) // LDX # { - uint16_t word = (int16_t)(int8_t)regs.RdMem(regs.pc++); - regs.WrMem(--regs.s, regs.pc & 0xFF); - regs.WrMem(--regs.s, regs.pc >> 8); - regs.pc += word; + uint16_t m = READ_IMM16; + OP_LDA_HANDLER16(m, regs.x); +} - regs.clock += 7; -} - -static void Op8E(void) // LDX # - { - 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 - regs.clock += 3; - } -static void Op90(void) // SUBA DP - { - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8_t 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 - regs.clock += 4; - } -static void Op91(void) // CMPA DP - { - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - uint8_t 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 - regs.clock += 4; - } -static void Op92(void) // SBCA DP -{ - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8_t 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 - regs.clock += 4; +static void Op96(void) // LDA DP +{ + uint8_t m = READ_DP; + OP_LDA_HANDLER(m, regs.a); } -static void Op93(void) // SUBD DP + +static void Op9E(void) // LDX DP { - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); uint16_t dr = (regs.a<<8)|regs.b, ds = dr; - uint16_t adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - dr -= adr2; - (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.a = dr>>8; regs.b = dr&0xFF; - regs.clock += 6; + uint16_t m = READ_DP16; + OP_LDA_HANDLER16(m, regs.x); } -static void Op94(void) // ANDA DP + +static void OpA6(void) // LDA IDX { - regs.a &= regs.RdMem((regs.dp<<8)|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 - regs.clock += 4; + uint8_t m = READ_IDX; + OP_LDA_HANDLER(m, regs.a); } -static void Op95(void) // BITA DP - { - tmp = regs.a & regs.RdMem((regs.dp<<8)|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 - regs.clock += 4; - } -static void Op96(void) // LDA DP -{ - regs.a = regs.RdMem((regs.dp<<8)|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 - regs.clock += 4; + +static void OpAE(void) // LDX IDX +{ + uint16_t m = READ_IDX16; + OP_LDA_HANDLER16(m, regs.x); } -static void Op97(void) // STA DP - { - regs.WrMem((regs.dp<<8)|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.clock += 4; - } -static void Op98(void) // EORA DP - { - regs.a ^= regs.RdMem((regs.dp<<8)|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.clock += 4; - } -static void Op99(void) // ADCA DP -{ - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - addr = (uint16_t)regs.a + (uint16_t)tmp + (uint16_t)(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 - regs.clock += 4; + +static void OpB6(void) // LDA ABS +{ + uint8_t m = READ_ABS; + OP_LDA_HANDLER(m, regs.a); } -static void Op9A(void) // ORA DP - { - regs.a |= regs.RdMem((regs.dp<<8)|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.clock += 4; - } -static void Op9B(void) // ADDA DP -{ - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - addr = (uint16_t)regs.a + (uint16_t)tmp; - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((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); // 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 - regs.clock += 4; + +static void OpBE(void) // LDX ABS +{ + uint16_t m = READ_ABS16; + OP_LDA_HANDLER16(m, regs.x); } -static void Op9C(void) // CMPX DP - { - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); - uint16_t adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - uint16_t 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.clock += 6; - } -static void Op9D(void) // JSR DP - { - addr = (regs.dp<<8) | regs.RdMem(regs.pc++); - regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); - regs.pc = addr; // JSR to DP location... - regs.clock += 7; - } -static void Op9E(void) // LDX DP - { - addr = (regs.dp<<8) | 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 - regs.clock += 5; - } -static void Op9F(void) // STX DP - { - addr = (regs.dp<<8) | 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 - regs.clock += 5; - } -static void OpA0(void) // SUBA IDX - { - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8_t 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 - regs.clock += 4; - } -static void OpA1(void) // CMPA IDX - { - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - uint8_t 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 - regs.clock += 4; - } -static void OpA2(void) // SBCA IDX -{ - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8_t 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 - regs.clock += 4; + +static void OpC6(void) // LDB # +{ + uint8_t m = READ_IMM; + OP_LDA_HANDLER(m, regs.b); } -static void OpA3(void) // SUBD IDX + +static void OpCC(void) // LDD # { - addr = DecodeIDX(regs.RdMem(regs.pc++)); uint16_t dr = (regs.a<<8)|regs.b, ds = dr; - uint16_t adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - dr -= adr2; - (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.a = dr>>8; regs.b = dr&0xFF; - regs.clock += 6; -} -static void OpA4(void) // ANDA IDX - { - regs.a &= regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - 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 - regs.clock += 4; - } -static void OpA5(void) // BITA IDX - { - tmp = regs.a & 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 - regs.clock += 4; - } -static void OpA6(void) // LDA IDX -{ - 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 - regs.clock += 4; + uint16_t m = READ_IMM16; + OP_LDA_HANDLER16D(m); +} + +static void OpCE(void) // LDU # +{ + uint16_t m = READ_IMM16; + OP_LDA_HANDLER16(m, regs.u); +} + +static void OpD6(void) // LDB DP +{ + uint8_t m = READ_DP; + OP_LDA_HANDLER(m, regs.b); +} + +static void OpDC(void) // LDD DP +{ + uint16_t m = READ_DP16; + OP_LDA_HANDLER16D(m); +} + +static void OpDE(void) // LDU DP +{ + uint16_t m = READ_DP16; + OP_LDA_HANDLER16(m, regs.u); +} + +static void OpE6(void) // LDB IDX +{ + uint8_t m = READ_IDX; + OP_LDA_HANDLER(m, regs.b); +} + +static void OpEC(void) // LDD IDX +{ + uint16_t m = READ_IDX16; + OP_LDA_HANDLER16D(m); +} + +static void OpEE(void) // LDU IDX +{ + uint16_t m = READ_IDX16; + OP_LDA_HANDLER16(m, regs.u); +} + +static void OpF6(void) // LDB ABS +{ + uint8_t m = READ_ABS; + OP_LDA_HANDLER(m, regs.b); +} + +static void OpFC(void) // LDD ABS +{ + uint16_t m = READ_ABS16; + OP_LDA_HANDLER16D(m); +} + +static void OpFE(void) // LDU ABS +{ + uint16_t m = READ_ABS16; + OP_LDA_HANDLER16(m, regs.u); +} + +static void Op108E(void) // LDY # +{ + uint16_t m = READ_IMM16; + OP_LDA_HANDLER16(m, regs.y); +} + +static void Op109E(void) // LDY DP +{ + uint16_t m = READ_DP16; + OP_LDA_HANDLER16(m, regs.y); +} + +static void Op10AE(void) // LDY IDX +{ + uint16_t m = READ_IDX16; + OP_LDA_HANDLER16(m, regs.y); +} + +static void Op10BE(void) // LDY ABS +{ + uint16_t m = READ_ABS16; + OP_LDA_HANDLER16(m, regs.y); +} + +static void Op10CE(void) // LDS # +{ + uint16_t m = READ_IMM16; + OP_LDA_HANDLER16(m, regs.s); +} + +static void Op10DE(void) // LDS DP +{ + uint16_t m = READ_DP16; + OP_LDA_HANDLER16(m, regs.s); +} + +static void Op10EE(void) // LDS IDX +{ + uint16_t m = READ_IDX16; + OP_LDA_HANDLER16(m, regs.s); +} + +static void Op10FE(void) // LDS ABS +{ + uint16_t m = READ_ABS16; + OP_LDA_HANDLER16(m, regs.s); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 30 0048 | LEAX | INDEXED | 4 | 2 | --a-- | + | 31 0049 | LEAY | INDEXED | 4 | 2 | --a-- | + | 32 0050 | LEAS | INDEXED | 4 | 2 | ----- | + | 33 0051 | LEAU | INDEXED | 4 | 2 | ----- | +*/ + +static void Op30(void) // LEAX +{ + regs.x = EA_IDX; + SET_Z(regs.x); +} + +static void Op31(void) // LEAY +{ + regs.y = EA_IDX; + SET_Z(regs.y); +} + +static void Op32(void) // LEAS +{ + regs.s = EA_IDX; +} + +static void Op33(void) // LEAU +{ + regs.u = EA_IDX; +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 04 0004 | LSR | DIRECT | 6 | 2 | -0a-s | + | 44 0068 | LSRA | INHERENT | 2 | 1 | -0a-s | + | 54 0084 | LSRB | INHERENT | 2 | 1 | -0a-s | + | 64 0100 | LSR | INDEXED | 6 | 2 | -0a-s | + | 74 0116 | LSR | EXTENDED | 7 | 3 | -0a-s | +*/ + +// LSR opcodes + +#define OP_LSR_HANDLER(m) \ + flagC = m & 0x01; \ + m >>= 1; \ + SET_ZN(m) + +static void Op04(void) // LSR DP +{ + uint8_t m; + READ_DP_WB(m); + OP_LSR_HANDLER(m); + WRITE_BACK(m); +} + +static void Op44(void) // LSRA +{ + OP_LSR_HANDLER(regs.a); +} + +static void Op54(void) // LSRB +{ + OP_LSR_HANDLER(regs.b); +} + +static void Op64(void) // LSR IDX +{ + uint8_t m; + READ_IDX_WB(m); + OP_LSR_HANDLER(m); + WRITE_BACK(m); +} + +static void Op74(void) // LSR ABS +{ + uint8_t m; + READ_ABS_WB(m); + OP_LSR_HANDLER(m); + WRITE_BACK(m); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 3D 0061 | MUL | INHERENT | 11 | 1 | --a-a | +*/ + +static void Op3D(void) // MUL +{ + uint16_t prod = regs.a * regs.b; + regs.a = prod >> 8; + regs.b = prod & 0xFF; + SET_Z(prod); +// flagC = (prod & 0x0080 ? 1 : 0); + flagC = (prod >> 7) & 0x01; +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 00 0000 | NEG | DIRECT | 6 | 2 | uaaaa | + | 40 0064 | NEGA | INHERENT | 2 | 1 | uaaaa | + | 50 0080 | NEGB | INHERENT | 2 | 1 | uaaaa | + | 60 0096 | NEG | INDEXED | 6 | 2 | uaaaa | + | 70 0112 | NEG | EXTENDED | 7 | 3 | uaaaa | +*/ + +// NEG opcodes + +#define OP_NEG_HANDLER(m) \ + uint8_t res = -m; \ + SET_ZN(res); \ + SET_V(0, m, res); \ + flagC = (res >= 0x80 ? 1 : 0); \ + m = res + +/* + UINT16 r,t; + DIRBYTE(t); + r = -t; + CLR_NZVC; + SET_FLAGS8(0,t,r); + WM(EAD,r); +#define SET_FLAGS8(a,b,r) {SET_N8(r);SET_Z8(r);SET_V8(a,b,r);SET_C8(r);} +#define SET_C8(a) CC|=((a&0x100)>>8) +*/ +static void Op00(void) // NEG DP +{ + uint8_t m; + READ_DP_WB(m); + OP_NEG_HANDLER(m); + WRITE_BACK(m); +} + +static void Op40(void) // NEGA +{ + OP_NEG_HANDLER(regs.a); +} + +static void Op50(void) // NEGB +{ + OP_NEG_HANDLER(regs.b); +} + +static void Op60(void) // NEG IDX +{ + uint8_t m; + READ_IDX_WB(m); + OP_NEG_HANDLER(m); + WRITE_BACK(m); +} + +static void Op70(void) // NEG ABS +{ + uint8_t m; + READ_ABS_WB(m); + OP_NEG_HANDLER(m); + WRITE_BACK(m); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 8A 0138 | ORA | IMMEDIATE | 2 | 2 | -aa0- | + | 9A 0154 | ORA | DIRECT | 4 | 2 | -aa0- | + | AA 0170 | ORA | INDEXED | 4 | 2 | -aa0- | + | BA 0186 | ORA | EXTENDED | 5 | 3 | -aa0- | + | CA 0202 | ORB | IMMEDIATE | 2 | 2 | -aa0- | + | DA 0218 | ORB | DIRECT | 4 | 2 | -aa0- | + | EA 0234 | ORB | INDEXED | 4 | 2 | -aa0- | + | FA 0250 | ORB | EXTENDED | 5 | 3 | -aa0- | +*/ + +// ORA opcodes + +#define OP_OR_HANDLER(m, acc) \ + acc |= (m); \ + SET_ZN(acc); \ + CLR_V + +static void Op8A(void) // ORA # +{ + uint8_t m = READ_IMM; + OP_OR_HANDLER(m, regs.a); +} + +static void Op9A(void) // ORA DP +{ + uint8_t m = READ_DP; + OP_OR_HANDLER(m, regs.a); +} + +static void OpAA(void) // ORA IDX +{ + uint8_t m = READ_IDX; + OP_OR_HANDLER(m, regs.a); +} + +static void OpBA(void) // ORA ABS +{ + uint8_t m = READ_ABS; + OP_OR_HANDLER(m, regs.a); +} + +static void OpCA(void) // ORB # +{ + uint8_t m = READ_IMM; + OP_OR_HANDLER(m, regs.b); +} + +static void OpDA(void) // ORB DP +{ + uint8_t m = READ_DP; + OP_OR_HANDLER(m, regs.b); +} + +static void OpEA(void) // ORB IDX +{ + uint8_t m = READ_IDX; + OP_OR_HANDLER(m, regs.b); +} + +static void OpFA(void) // ORB ABS +{ + uint8_t m = READ_ABS; + OP_OR_HANDLER(m, regs.b); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 34 0052 | PSHS | INHERENT | 5 | 2 | ----- | + | 35 0053 | PULS | INHERENT | 5 | 2 | ccccc | + | 36 0054 | PSHU | INHERENT | 5 | 2 | ----- | + | 37 0055 | PULU | INHERENT | 5 | 2 | ccccc | +*/ + +static void Op34(void) // PSHS +{ + uint8_t m = READ_IMM; + + if (m & 0x80) + PUSHS16(regs.pc); + if (m & 0x40) + PUSHS16(regs.u); + if (m & 0x20) + PUSHS16(regs.y); + if (m & 0x10) + PUSHS16(regs.x); + if (m & 0x08) + PUSHS(regs.dp); + if (m & 0x04) + PUSHS(regs.b); + if (m & 0x02) + PUSHS(regs.a); + if (m & 0x01) + { + regs.cc = PACK_FLAGS; + PUSHS(regs.cc); + } + + // Count bits in each nybble to come up with correct cycle counts... + uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]); +} + +static void Op35(void) // PULS +{ + uint8_t m = READ_IMM; + + if (m & 0x01) + { + PULLS(regs.cc); + UNPACK_FLAGS; + } + if (m & 0x02) + PULLS(regs.a); + if (m & 0x04) + PULLS(regs.b); + if (m & 0x08) + PULLS(regs.dp); + if (m & 0x10) + PULLS16(regs.x); + if (m & 0x20) + PULLS16(regs.y); + if (m & 0x40) + PULLS16(regs.u); + if (m & 0x80) + PULLS16(regs.pc); + + // Count bits in each nybble to come up with correct cycle counts... + uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]); +} + +static void Op36(void) // PHSU +{ + uint8_t m = READ_IMM; + + if (m & 0x80) + PUSHU16(regs.pc); + if (m & 0x40) + PUSHU16(regs.s); + if (m & 0x20) + PUSHU16(regs.y); + if (m & 0x10) + PUSHU16(regs.x); + if (m & 0x08) + PUSHU(regs.dp); + if (m & 0x04) + PUSHU(regs.b); + if (m & 0x02) + PUSHU(regs.a); + if (m & 0x01) + { + regs.cc = PACK_FLAGS; + PUSHU(regs.cc); + } + + // Count bits in each nybble to come up with correct cycle counts... + uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]); +} + +static void Op37(void) // PULU +{ + uint8_t m = READ_IMM; + + if (m & 0x01) + { + PULLU(regs.cc); + UNPACK_FLAGS; + } + if (m & 0x02) + PULLU(regs.a); + if (m & 0x04) + PULLU(regs.b); + if (m & 0x08) + PULLU(regs.dp); + if (m & 0x10) + PULLU16(regs.x); + if (m & 0x20) + PULLU16(regs.y); + if (m & 0x40) + PULLU16(regs.s); + if (m & 0x80) + PULLU16(regs.pc); + + // Count bits in each nybble to come up with correct cycle counts... + uint8_t bitCount[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + regs.clock += (1 * bitCount[m & 0x0F]) + (2 * bitCount[m >> 4]); +} + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 09 0009 | ROL | DIRECT | 6 | 2 | -aaas | + | 49 0073 | ROLA | INHERENT | 2 | 1 | -aaas | + | 59 0089 | ROLB | INHERENT | 2 | 1 | -aaas | + | 69 0105 | ROL | INDEXED | 6 | 2 | -aaas | + | 79 0121 | ROL | EXTENDED | 7 | 3 | -aaas | +*/ + +// ROL opcodes + +#define OP_ROL_HANDLER(m) \ + uint8_t res = (m << 1) | flagC; \ + SET_ZN(res); \ + SET_V(m, m, res); \ + flagC = (m >> 7) & 0x01; \ + m = res + +/* + UINT16 t,r; + DIRBYTE(t); + r = (CC & CC_C) | (t << 1); + CLR_NZVC; + SET_FLAGS8(t,t,r); + WM(EAD,r); +*/ +static void Op09(void) // ROL DP +{ + uint8_t m; + READ_DP_WB(m); + OP_ROL_HANDLER(m); + WRITE_BACK(m); +} + +static void Op49(void) // ROLA +{ + OP_ROL_HANDLER(regs.a); } -static void OpA7(void) // STA IDX + +static void Op59(void) // ROLB { - 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 - regs.clock += 4; + OP_ROL_HANDLER(regs.b); } -static void OpA8(void) // EORA IDX - { - 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 - regs.clock += 4; - } -static void OpA9(void) // ADCA IDX -{ - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - addr = (uint16_t)regs.a + (uint16_t)tmp + (uint16_t)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((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); // 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 - regs.clock += 4; + +static void Op69(void) // ROL IDX +{ + uint8_t m; + READ_IDX_WB(m); + OP_ROL_HANDLER(m); + WRITE_BACK(m); } -static void OpAA(void) // ORA IDX + +static void Op79(void) // ROL ABS { - 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 - regs.clock += 4; + uint8_t m; + READ_ABS_WB(m); + OP_ROL_HANDLER(m); + WRITE_BACK(m); } -static void OpAB(void) // ADDA IDX + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 06 0006 | ROR | DIRECT | 6 | 2 | -aa-s | + | 46 0070 | RORA | INHERENT | 2 | 1 | -aa-s | + | 56 0086 | RORB | INHERENT | 2 | 1 | -aa-s | + | 66 0102 | ROR | INDEXED | 6 | 2 | -aa-s | + | 76 0118 | ROR | EXTENDED | 7 | 3 | -aa-s | +*/ + +// ROR opcodes + +#define OP_ROR_HANDLER(m) \ + uint8_t res = (flagC << 7) | (m >> 1); \ + SET_ZN(res); \ + SET_V(m, m, res); \ + flagC = m & 0x01; \ + m = res + +static void Op06(void) // ROR DP { - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - addr = (uint16_t)regs.a + (uint16_t)tmp; - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((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); // 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 - regs.clock += 4; + uint8_t m; + READ_DP_WB(m); + OP_ROR_HANDLER(m); + WRITE_BACK(m); } -static void OpAC(void) // CMPX IDX -{ - addr = DecodeIDX(regs.RdMem(regs.pc++)); - uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - uint16_t 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.clock += 6; -} -static void OpAD(void) // JSR IDX -{ - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); - regs.pc = addr; // Jregs.s directly to IDX ptr - regs.clock += 7; -} -static void OpAE(void) // LDX IDX -{ - addr = DecodeIDX(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 - regs.clock += 5; -} -static void OpAF(void) // STX IDX -{ - 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 - regs.clock += 5; -} -static void OpB0(void) // SUBA ABS - { - tmp = regs.RdMem(FetchW()); uint8_t 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 - regs.clock += 5; - } -static void OpB1(void) // CMPA ABS - { - tmp = regs.RdMem(FetchW()); - uint8_t 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 - regs.clock += 5; - } -static void OpB2(void) // SBCA ABS -{ - tmp = regs.RdMem(FetchW()); uint8_t 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 - regs.clock += 5; -} -static void OpB3(void) // SUBD ABS -{ - addr = FetchW(); uint16_t dr = (regs.a<<8)|regs.b, ds = dr; - uint16_t adr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - dr -= adr2; - (ds < adr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.a = dr>>8; regs.b = dr&0xFF; - regs.clock += 7; + +static void Op46(void) // RORA +{ + OP_ROR_HANDLER(regs.a); } -static void OpB4(void) // ANDA ABS + +static void Op56(void) // RORB { - regs.a &= regs.RdMem(FetchW()); - 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 - regs.clock += 5; + OP_ROR_HANDLER(regs.b); } -static void OpB5(void) // BITA ABS + +static void Op66(void) // ROR IDX { - tmp = regs.a & 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.clock += 5; + uint8_t m; + READ_IDX_WB(m); + OP_ROR_HANDLER(m); + WRITE_BACK(m); } -static void OpB6(void) // LDA ABS + +static void Op76(void) // ROR ABS { - 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.clock += 5; + uint8_t m; + READ_ABS_WB(m); + OP_ROR_HANDLER(m); + WRITE_BACK(m); } -static void OpB7(void) // STA ABS + +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 82 0130 | SBCA | IMMEDIATE | 2 | 2 | uaaaa | + | 92 0146 | SBCA | DIRECT | 4 | 2 | uaaaa | + | A2 0162 | SBCA | INDEXED | 4 | 2 | uaaaa | + | B2 0178 | SBCA | EXTENDED | 5 | 3 | uaaaa | + | C2 0194 | SBCB | IMMEDIATE | 2 | 2 | uaaaa | + | D2 0210 | SBCB | DIRECT | 4 | 2 | uaaaa | + | E2 0226 | SBCB | INDEXED | 4 | 2 | uaaaa | + | F2 0242 | SBCB | EXTENDED | 5 | 3 | uaaaa | +*/ + +// SBC opcodes + +#define OP_SBC_HANDLER(m, acc) \ + uint16_t sum = (uint16_t)acc - (m) - (uint16_t)flagC; \ + flagC = (sum >> 8) & 0x01; \ + SET_V(m, acc, sum); \ + acc = (uint8_t)sum; \ + SET_ZN(acc) + +static void Op82(void) // SBCA # { - 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 - regs.clock += 5; + uint8_t m = READ_IMM; + OP_SBC_HANDLER(m, regs.a); } -static void OpB8(void) // EORA ABS + +static void Op92(void) // SBCA DP { - 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.clock += 5; + uint8_t m = READ_DP; + OP_SBC_HANDLER(m, regs.a); } -static void OpB9(void) // ADCA ABS + +static void OpA2(void) // SBCA IDX { - tmp = regs.RdMem(FetchW()); - addr = (uint16_t)regs.a + (uint16_t)tmp + (uint16_t)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((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; // 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 - regs.clock += 5; + uint8_t m = READ_IDX; + OP_SBC_HANDLER(m, regs.a); } -static void OpBA(void) // ORA ABS + +static void OpB2(void) // SBCA ABS { - 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.clock += 5; + uint8_t m = READ_ABS; + OP_SBC_HANDLER(m, regs.a); } -static void OpBB(void) // ADDA ABS + +static void OpC2(void) // SBCB # { - tmp = regs.RdMem(FetchW()); - addr = (uint16_t)regs.a + (uint16_t)tmp; - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((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); // 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 - regs.clock += 5; + uint8_t m = READ_IMM; + OP_SBC_HANDLER(m, regs.b); } -static void OpBC(void) // CMPX ABS + +static void OpD2(void) // SBCB DP { - addr = FetchW(); uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - uint16_t 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.clock += 7; + uint8_t m = READ_DP; + OP_SBC_HANDLER(m, regs.b); } -static void OpBD(void) // JSR ABS + +static void OpE2(void) // SBCB IDX { - addr = FetchW(); - regs.WrMem(--regs.s, regs.pc&0xFF); regs.WrMem(--regs.s, regs.pc>>8); - regs.pc = addr; // Go to absolute address (Not indir) - regs.clock += 8; + uint8_t m = READ_IDX; + OP_SBC_HANDLER(m, regs.b); } -static void OpBE(void) // LDX ABS +static void OpF2(void) // SBCB ABS { -// addr = FetchW(); -// regs.x = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); - regs.x = RdMemW(FetchW()); + uint8_t m = READ_ABS; + OP_SBC_HANDLER(m, regs.b); +} - 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 +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 97 0151 | STA | DIRECT | 4 | 2 | -aa0- | + | 9F 0159 | STX | DIRECT | 5 | 2 | -aa0- | + | A7 0167 | STA | INDEXED | 4 | 2 | -aa0- | + | AF 0175 | STX | INDEXED | 5 | 2 | -aa0- | + | B7 0183 | STA | EXTENDED | 5 | 3 | -aa0- | + | BF 0191 | STX | EXTENDED | 6 | 3 | -aa0- | + | D7 0215 | STB | DIRECT | 4 | 2 | -aa0- | + | DD 0221 | STD | DIRECT | 5 | 2 | -aa0- | + | DF 0223 | STU | DIRECT | 5 | 2 | -aa0- | + | E7 0231 | STB | INDEXED | 4 | 2 | -aa0- | + | ED 0237 | STD | INDEXED | 5 | 2 | -aa0- | + | EF 0239 | STU | INDEXED | 5 | 2 | -aa0- | + | F7 0247 | STB | EXTENDED | 5 | 3 | -aa0- | + | FD 0253 | STD | EXTENDED | 6 | 3 | -aa0- | + | FF 0255 | STU | EXTENDED | 6 | 3 | -aa0- | + | 109F 4255 | STY | DIRECT | 6 | 3 | -aa0- | + | 10AF 4271 | STY | INDEXED | 6 | 3 | -aa0- | + | 10BF 4287 | STY | EXTENDED | 7 | 4 | -aa0- | + | 10DF 4319 | STS | DIRECT | 6 | 3 | -aa0- | + | 10EF 4335 | STS | INDEXED | 6 | 3 | -aa0- | + | 10FF 4351 | STS | EXTENDED | 7 | 4 | -aa0- | +*/ - regs.clock += 6; -} +// STA opcodes -static void OpBF(void) // STX ABS -{ -// addr = FetchW(); -// regs.WrMem(addr, regs.x>>8); regs.WrMem(addr+1, regs.x&0xFF); - WrMemW(FetchW(), regs.x); +#define OP_STA_HANDLER(m, acc) \ + regs.WrMem(m, acc); \ + CLR_V; \ + SET_ZN(acc) - 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 +#define OP_STA_HANDLER16(m, acc) \ + WrMemW(m, acc); \ + CLR_V; \ + SET_ZN16(acc) - regs.clock += 6; +static void Op97(void) // STA DP +{ + uint16_t addr = EA_DP; + OP_STA_HANDLER(addr, regs.a); } -static void OpC0(void) // SUBB # - { - tmp = regs.RdMem(regs.pc++); uint8_t 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 - regs.clock += 2; - } -static void OpC1(void) // CMPB # - { - tmp = regs.RdMem(regs.pc++); - uint8_t 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.clock += 2; - } -static void OpC2(void) // SBCB # +static void Op9F(void) // STX DP { - tmp = regs.RdMem(regs.pc++); uint8_t 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.clock += 2; + uint16_t addr = EA_DP; + OP_STA_HANDLER16(addr, regs.x); } -static void OpC3(void) // ADDD # + +static void OpA7(void) // STA IDX { - addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr; - dr += addr; - (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - dr &= 0xFFFF; - (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - ((ds^addr^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.a = dr>>8; regs.b = dr&0xFF; - regs.clock += 4; + uint16_t addr = EA_IDX; + OP_STA_HANDLER(addr, regs.a); } -static void OpC4(void) // ANDB # - { - regs.b &= 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 - regs.clock += 2; - } -static void OpC5(void) // BITB # -{ - 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.clock += 2; -} -static void OpC6(void) // LDB # -{ - 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.clock += 2; -} -static void OpC8(void) // EORB # - { - 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 - regs.clock += 2; - } -static void OpC9(void) // ADCB # -{ - tmp = regs.RdMem(regs.pc++); - addr = (uint16_t)regs.b + (uint16_t)tmp + (uint16_t)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((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.clock += 2; -} -static void OpCA(void) // ORB # - { - 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 - regs.clock += 2; - } -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)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((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.clock += 2; -} -static void OpCC(void) // LDD # -{ - regs.a = regs.RdMem(regs.pc++); regs.b = regs.RdMem(regs.pc++); - regs.cc &= 0xFD; // CLV - ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 3; -} -static void OpCE(void) // LDU # -{ - regs.u = FetchW(); - regs.cc &= 0xFD; // CLV - (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 3; -} -static void OpD0(void) // SUBB DP -{ - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8_t 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 - regs.clock += 4; -} -static void OpD1(void) // CMPB DP + +static void OpAF(void) // STX IDX { - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - uint8_t 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.clock += 4; + uint16_t addr = EA_IDX; + OP_STA_HANDLER16(addr, regs.x); } -static void OpD2(void) // SBCB DP + +static void OpB7(void) // STA ABS { - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8_t 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.clock += 4; + uint16_t addr = EA_ABS; + OP_STA_HANDLER(addr, regs.a); } -static void OpD3(void) // ADDD DP + +static void OpBF(void) // STX ABS { - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr; - uint16_t adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1); - dr += adr2; - (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - dr &= 0xFFFF; - (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.a = dr>>8; regs.b = dr&0xFF; - regs.clock += 6; -} -static void OpD4(void) // ANDB DP - { - regs.b &= regs.RdMem((regs.dp<<8)|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 - regs.clock += 4; - } -static void OpD5(void) // BITB DP - { - tmp = regs.b & regs.RdMem((regs.dp<<8)|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 - regs.clock += 4; - } -static void OpD6(void) // LDB DP -{ - regs.b = regs.RdMem((regs.dp<<8)|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.clock += 4; -} -static void OpD7(void) // STB DP - { - regs.WrMem((regs.dp<<8)|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 - regs.clock += 4; - } -static void OpD8(void) // EORB DP - { - regs.b ^= regs.RdMem((regs.dp<<8)|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.clock += 4; - } -static void OpD9(void) // ADCB DP -{ - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - addr = (uint16_t)regs.b + (uint16_t)tmp + (uint16_t)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((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.clock += 4; -} -static void OpDA(void) // ORB DP - { - regs.b |= regs.RdMem((regs.dp<<8)|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.clock += 4; - } -static void OpDB(void) // ADDB DP -{ - tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); - addr = (uint16_t)regs.b + (uint16_t)tmp; - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((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 - regs.clock += 4; -} -static void OpDC(void) // LDD DP -{ - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); - regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1); - regs.cc &= 0xFD; // CLV - ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 5; -} -static void OpDD(void) // STD DP -{ - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); - regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b); - regs.cc &= 0xFD; // CLV - ((regs.a|regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 5; -} -static void OpDE(void) // LDU DP -{ - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); - regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); - regs.cc &= 0xFD; // CLV - (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 5; -} -static void OpDF(void) // STU DP -{ - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); - regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF); - regs.cc &= 0xFD; // CLV - (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 5; -} -static void OpE0(void) // SUBB IDX -{ - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8_t 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 - regs.clock += 4; + uint16_t addr = EA_ABS; + OP_STA_HANDLER16(addr, regs.x); } -static void OpE1(void) // CMPB IDX + +static void OpD7(void) // STB DP { - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - uint8_t 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.clock += 4; + uint16_t addr = EA_DP; + OP_STA_HANDLER(addr, regs.b); } -static void OpE2(void) // SBCB IDX + +static void OpDD(void) // STD DP { - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8_t 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.clock += 4; + uint16_t addr = EA_DP; + OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b); } -static void OpE3(void) // ADDD IDX + +static void OpDF(void) // STU DP { - addr = DecodeIDX(regs.RdMem(regs.pc++)); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr; - uint16_t adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1); - dr += adr2; - (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - dr &= 0xFFFF; - (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow - regs.a = dr>>8; regs.b = dr&0xFF; - regs.clock += 6; -} -static void OpE4(void) // ANDB IDX - { - 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 - regs.clock += 4; - } -static void OpE5(void) // BITB IDX - { - 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 - regs.clock += 4; - } -static void OpE6(void) // LDB IDX - { - 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.clock += 4; - } -static void OpE7(void) // STB IDX -{ - 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 - regs.clock += 4; -} -static void OpE8(void) // EORB IDX - { - 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.clock += 4; - } -static void OpE9(void) // ADCB IDX -{ - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - addr = (uint16_t)regs.b + (uint16_t)tmp + (uint16_t)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((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.clock += 4; + uint16_t addr = EA_DP; + OP_STA_HANDLER16(addr, regs.u); } -static void OpEA(void) // ORB IDX - { - 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.clock += 4; - } -static void OpEB(void) // ADDB IDX -{ - tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); - addr = (uint16_t)regs.b + (uint16_t)tmp; - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((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.clock += 4; -} -static void OpEC(void) // LDD IDX -{ - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1); - regs.cc &= 0xF1; // CLV CLZ CLN - if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag - if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag - regs.clock += 5; -} -static void OpED(void) // STD IDX -{ - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b); - regs.cc &= 0xF1; // CLV CLZ CLZ - if (!(regs.a|regs.b)) regs.cc |= 0x04; // Adjust Zero flag - if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag - regs.clock += 5; -} -static void OpEE(void) // LDU IDX -{ - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); - regs.cc &= 0xF1; // CLV CLZ CLN - if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag - if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag - regs.clock += 5; -} -static void OpEF(void) // STU IDX -{ - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF); - regs.cc &= 0xF1; // CLV CLZ CLN - if (regs.u == 0) regs.cc |= 0x04; // Set Zero flag - if (regs.u&0x8000) regs.cc |= 0x08; // Set Negative flag - regs.clock += 5; -} -static void OpF0(void) // SUBB ABS - { - tmp = regs.RdMem(FetchW()); uint8_t 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 OpF1(void) // CMPB ABS - { - tmp = regs.RdMem(FetchW()); - uint8_t 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.clock += 5; - } -static void OpF2(void) // SBCB ABS -{ - tmp = regs.RdMem(FetchW()); uint8_t 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 - regs.clock += 5; -} -static void OpF3(void) // ADDD ABS -{ - addr = FetchW(); long dr = ((regs.a<<8)|regs.b)&0xFFFF, ds = dr; - uint16_t adr2 = (regs.RdMem(addr)<<8)|regs.RdMem(addr+1); - dr += adr2; - (dr > 0xFFFF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - dr &= 0xFFFF; - (dr == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dr&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - ((ds^adr2^dr^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.a = dr>>8; regs.b = dr&0xFF; - regs.clock += 7; -} -static void OpF4(void) // ANDB ABS - { - 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 - regs.clock += 5; - } -static void OpF5(void) // BITB ABS - { - 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.clock += 5; - } -static void OpF6(void) // LDB ABS - { - 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.clock += 5; - } -static void OpF7(void) // STB ABS - { - 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.clock += 5; - } -static void OpF8(void) // EORB ABS - { - 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.clock += 5; - } -static void OpF9(void) // ADCB ABS -{ - tmp = regs.RdMem(FetchW()); - addr = (uint16_t)regs.b + (uint16_t)tmp + (uint16_t)(regs.cc&0x01); - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((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.clock += 5; -} -static void OpFA(void) // ORB ABS - { - 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.clock += 5; - } -static void OpFB(void) // ADDB ABS -{ - tmp = regs.RdMem(FetchW()); - addr = (uint16_t)regs.b + (uint16_t)tmp; - (addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag - ((regs.b^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry - ((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.clock += 5; -} -static void OpFC(void) // LDD ABS - { - addr = FetchW(); - regs.a = regs.RdMem(addr); regs.b = regs.RdMem(addr+1); - regs.cc &= 0xFD; // CLV - ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; - } -static void OpFD(void) // STD ABS - { - addr = FetchW(); - regs.WrMem(addr, regs.a); regs.WrMem(addr+1, regs.b); - regs.cc &= 0xFD; // CLV - ((regs.a+regs.b) == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; - } -static void OpFE(void) // LDU ABS - { - addr = FetchW(); - regs.u = (regs.RdMem(addr) << 8) | regs.RdMem(addr+1); - regs.cc &= 0xFD; // CLV - (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; - } -static void OpFF(void) // STU ABS - { - addr = FetchW(); - regs.WrMem(addr, regs.u>>8); regs.WrMem(addr+1, regs.u&0xFF); - regs.cc &= 0xFD; // CLV - (regs.u == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.u&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; - } - -// -// Page one opcodes' execute code -// -static void Op1021(void) // LBRN +static void OpE7(void) // STB IDX { - addr = FetchW(); - - regs.clock += 5; + uint16_t addr = EA_IDX; + OP_STA_HANDLER(addr, regs.b); } -static void Op1022(void) // LBHI +static void OpED(void) // STD IDX { - uint16_t word = FetchW(); - - if (!((regs.cc & 0x01) | (regs.cc & 0x04))) - regs.pc += word; - - regs.clock += 5; + uint16_t addr = EA_IDX; + OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b); } -static void Op1023(void) // LBLS +static void OpEF(void) // STU IDX { - uint16_t word = FetchW(); + uint16_t addr = EA_IDX; + OP_STA_HANDLER16(addr, regs.u); +} - if ((regs.cc & 0x01) | (regs.cc & 0x04)) - regs.pc += word; +static void OpF7(void) // STB ABS +{ + uint16_t addr = EA_ABS; + OP_STA_HANDLER(addr, regs.b); +} - regs.clock += 5; +static void OpFD(void) // STD ABS +{ + uint16_t addr = EA_ABS; + OP_STA_HANDLER16(addr, (regs.a << 8) | regs.b); } -static void Op1024(void) // LBCC (LBHS) +static void OpFF(void) // STU ABS { - uint16_t word = FetchW(); + uint16_t addr = EA_ABS; + OP_STA_HANDLER16(addr, regs.u); +} - if (!(regs.cc & 0x01)) - regs.pc += word; +static void Op109F(void) // STY DP +{ + uint16_t addr = EA_DP; + OP_STA_HANDLER16(addr, regs.y); +} - regs.clock += 5; +static void Op10AF(void) // STY IDX +{ + uint16_t addr = EA_IDX; + OP_STA_HANDLER16(addr, regs.y); } -static void Op1025(void) // LBCS (LBLO) +static void Op10BF(void) // STY ABS { - uint16_t word = FetchW(); + uint16_t addr = EA_ABS; + OP_STA_HANDLER16(addr, regs.y); +} - if (regs.cc & 0x01) - regs.pc += word; +static void Op10DF(void) // STS DP +{ + uint16_t addr = EA_DP; + OP_STA_HANDLER16(addr, regs.s); +} - regs.clock += 5; +static void Op10EF(void) // STS IDX +{ + uint16_t addr = EA_IDX; + OP_STA_HANDLER16(addr, regs.s); } -static void Op1026(void) // LBNE +static void Op10FF(void) // STS ABS { - uint16_t word = FetchW(); + uint16_t addr = EA_ABS; + OP_STA_HANDLER16(addr, regs.s); +} - if (!(regs.cc & 0x04)) - regs.pc += word; +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 80 0128 | SUBA | IMMEDIATE | 2 | 2 | uaaaa | + | 83 0131 | SUBD | IMMEDIATE | 4 | 3 | -aaaa | + | 90 0144 | SUBA | DIRECT | 4 | 2 | uaaaa | + | 93 0147 | SUBD | DIRECT | 6 | 2 | -aaaa | + | A0 0160 | SUBA | INDEXED | 4 | 2 | uaaaa | + | A3 0163 | SUBD | INDEXED | 6 | 2 | -aaaa | + | B0 0176 | SUBA | EXTENDED | 5 | 3 | uaaaa | + | B3 0179 | SUBD | EXTENDED | 7 | 3 | -aaaa | + | C0 0192 | SUBB | IMMEDIATE | 2 | 2 | uaaaa | + | D0 0208 | SUBB | DIRECT | 4 | 2 | uaaaa | + | E0 0224 | SUBB | INDEXED | 4 | 2 | uaaaa | + | F0 0240 | SUBB | EXTENDED | 5 | 3 | uaaaa | +*/ - regs.clock += 5; -} +// SUB opcodes -static void Op1027(void) // LBEQ -{ - uint16_t word = FetchW(); +#define OP_SUB_HANDLER(m, acc) \ + uint16_t sum = (uint16_t)acc - (m); \ + flagC = (sum >> 8) & 0x01; \ + SET_V(m, acc, sum); \ + acc = (uint8_t)sum; \ + SET_ZN(acc) - if (regs.cc & 0x04) - regs.pc += word; +#define OP_SUB_HANDLER16D(m) \ + uint32_t acc = (uint32_t)((regs.a << 8) | regs.b); \ + uint32_t sum = acc - (m); \ + flagC = (sum >> 16) & 0x01; \ + SET_V16(m, acc, sum); \ + acc = sum & 0xFFFF; \ + regs.a = (acc >> 8) & 0xFF; \ + regs.b = acc & 0xFF; \ + SET_ZN16(acc) - regs.clock += 5; +static void Op80(void) // SUBA # +{ + uint8_t m = READ_IMM; + OP_SUB_HANDLER(m, regs.a); } -static void Op1028(void) // LBVC +static void Op83(void) // SUBD # { - uint16_t word = FetchW(); - - if (!(regs.cc & 0x02)) - regs.pc += word; - - regs.clock += 5; + uint16_t m = READ_IMM16; + OP_SUB_HANDLER16D(m); } -static void Op1029(void) // LBVS +static void Op90(void) // SUBA DP { - uint16_t word = FetchW(); + uint8_t m = READ_DP; + OP_SUB_HANDLER(m, regs.a); +} - if (regs.cc & 0x02) - regs.pc += word; +static void Op93(void) // SUBD DP +{ + uint16_t m = READ_DP16; + OP_SUB_HANDLER16D(m); +} - regs.clock += 5; +static void OpA0(void) // SUBA IDX +{ + uint8_t m = READ_IDX; + OP_SUB_HANDLER(m, regs.a); } -static void Op102A(void) // LBPL +static void OpA3(void) // SUBD IDX { - uint16_t word = FetchW(); + uint16_t m = READ_IDX16; + OP_SUB_HANDLER16D(m); +} - if (!(regs.cc & 0x08)) - regs.pc += word; +static void OpB0(void) // SUBA ABS +{ + uint8_t m = READ_ABS; + OP_SUB_HANDLER(m, regs.a); +} - regs.clock += 5; +static void OpB3(void) // SUBD ABS +{ + uint16_t m = READ_ABS16; + OP_SUB_HANDLER16D(m); } -static void Op102B(void) // LBMI +static void OpC0(void) // SUBB # { - uint16_t word = FetchW(); + uint8_t m = READ_IMM; + OP_SUB_HANDLER(m, regs.b); +} - if (regs.cc & 0x08) - regs.pc += word; +static void OpD0(void) // SUBB DP +{ + uint8_t m = READ_DP; + OP_SUB_HANDLER(m, regs.b); +} - regs.clock += 5; +static void OpE0(void) // SUBB IDX +{ + uint8_t m = READ_IDX; + OP_SUB_HANDLER(m, regs.b); } -static void Op102C(void) // LBGE +static void OpF0(void) // SUBB ABS { - uint16_t word = FetchW(); + uint8_t m = READ_ABS; + OP_SUB_HANDLER(m, regs.b); +} - if (!(((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02))) - regs.pc += word; +/* + +-----------------------------------------------------------------+ + | Opcode | | Addressing | | | + | Hex Dec | Instruction | Mode | Cycles Bytes | HNZVC | + +------------+-------------+--------------+-------+-------+-------+ + | 0D 0013 | TST | DIRECT | 6 | 2 | -aa0- | + | 4D 0077 | TSTA | INHERENT | 2 | 1 | -aa0- | + | 5D 0093 | TSTB | INHERENT | 2 | 1 | -aa0- | + | 6D 0109 | TST | INDEXED | 6 | 2 | -aa0- | + | 7D 0125 | TST | EXTENDED | 7 | 3 | -aa0- | +*/ - regs.clock += 5; -} +// TST opcodes -static void Op102D(void) // LBLT +#define OP_TST_HANDLER(m) \ + SET_ZN(m); \ + CLR_V + +static void Op0D(void) // TST DP { - uint16_t word = FetchW(); + uint8_t m = READ_DP; + OP_TST_HANDLER(m); +} - if (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)) - regs.pc += word; - regs.clock += 5; +static void Op4D(void) // TSTA +{ + OP_TST_HANDLER(regs.a); } -static void Op102E(void) // LBGT + +static void Op5D(void) // TSTB { - uint16_t word = FetchW(); + OP_TST_HANDLER(regs.b); +} - if (!((regs.cc & 0x04) | (((regs.cc & 0x08) >> 2) ^ (regs.cc & 0x02)))) - regs.pc += word; - regs.clock += 5; +static void Op6D(void) // TST IDX +{ + uint8_t m = READ_IDX; + OP_TST_HANDLER(m); } -static void Op102F(void) // LBLE + +static void Op7D(void) // TST ABS { - uint16_t 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; -} -static void Op1083(void) // CMPD # - { - addr = FetchW(); uint16_t dr = (regs.a<<8)|regs.b; - uint16_t dw = dr - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((dr^addr^dw^((uint16_t)regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 5; - } -static void Op108C(void) // CMPY # - { - addr = FetchW(); - uint16_t dw = regs.y - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 5; - } -static void Op108E(void) // LDY # - { - regs.y = FetchW(); - regs.cc &= 0xFD; // CLV - (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 4; - } -static void Op1093(void) // CMPD DP - { - uint16_t adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++), dr = (regs.a<<8)|regs.b; - addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); - uint16_t dw = dr - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (dr < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((dr^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 7; - } -static void Op109C(void) // CMPY DP - { - uint16_t adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++); - addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); - uint16_t dw = regs.y - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - ((regs.y^addr^dw^(regs.cc<<15))&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 7; - } - -static void Op109E(void) // LDY DP - { - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); - regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - regs.cc &= 0xFD; // CLV - (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; - } - -static void Op109F(void) // STY DP - { - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); - regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF); - regs.cc &= 0xFD; // CLV - (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; - } -static void Op10A3(void) // CMPD IDX -{ - uint16_t adr2 = DecodeIDX(regs.RdMem(regs.pc++)), dr = (regs.a<<8)|regs.b; - addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); - uint16_t dw = dr - addr; - regs.cc &= 0xF0; // CLC CLV CLZ CLN - if (dr < addr) regs.cc |= 0x01; // Set Carry flag - if ((dr^addr^dw^(regs.cc<<15))&0x8000) regs.cc |= 0x02; // Set oVerflow - if (dw == 0) regs.cc |= 0x04; // Set Zero flag - if (dw&0x8000) regs.cc |= 0x08; // Set Negative flag - regs.clock += 7; -} -static void Op10AC(void) // CMPY IDX - { - uint16_t adr2 = DecodeIDX(regs.RdMem(regs.pc++)); - addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); - uint16_t dw = regs.y - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.y < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^regs.y^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 7; - } -static void Op10AE(void) // LDY IDX -{ - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - regs.cc &= 0xF1; // CLV CLZ CLN - if (regs.y == 0) regs.cc |= 0x04; // Adjust Zero flag - if (regs.y&0x8000) regs.cc |= 0x08; // Adjust Negative flag - regs.clock += 6; -} -static void Op10AF(void) // STY IDX - { - addr = DecodeIDX(regs.RdMem(regs.pc++)); - regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF); - regs.cc &= 0xFD; // CLV - (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 6; - } -static void Op10B3(void) // CMPD ABS - { - addr = FetchW(); uint16_t dr = (regs.a<<8)|regs.b; - uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - uint16_t dw = dr - addr2; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (dr < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^dr^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 8; - } -static void Op10BC(void) // CMPY ABS - { - addr = FetchW(); uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - uint16_t dw = regs.y - addr2; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.y < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^regs.y^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 8; - } -static void Op10BE(void) // LDY ABS - { - addr = FetchW(); - regs.y = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - regs.cc &= 0xFD; // CLV - (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 7; - } -static void Op10BF(void) // STY ABS - { - addr = FetchW(); - regs.WrMem(addr, regs.y>>8); regs.WrMem(addr+1, regs.y&0xFF); - regs.cc &= 0xFD; // CLV - (regs.y == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (regs.y&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - regs.clock += 7; - } -static void Op10CE(void) // LDS # - { - 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 - regs.clock += 4; - } -static void Op10DE(void) // LDS DP - { - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); - 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.clock += 6; - } -static void Op10DF(void) // STS DP - { - addr = (regs.dp<<8)|regs.RdMem(regs.pc++); - 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.clock += 6; - } -static void Op10EE(void) // LDS IDX - { - addr = DecodeIDX(regs.RdMem(regs.pc++)); - 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.clock += 6; - } -static void Op10EF(void) // STS IDX - { - addr = DecodeIDX(regs.RdMem(regs.pc++)); - 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.clock += 6; - } -static void Op10FE(void) // LDS ABS - { - 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.clock += 7; - } -static void Op10FF(void) // STS ABS -{ - 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.clock += 7; + uint8_t m = READ_ABS; + OP_TST_HANDLER(m); } + // -// Page two opcodes' execute code +// Undocumented Opcodes // - -static void Op113F(void) // SWI3 - { - regs.clock += 20; - } -static void Op1183(void) // CMPU # - { - addr = FetchW(); - uint16_t dw = regs.u - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 5; - } -static void Op118C(void) // CMPS # - { - addr = FetchW(); - uint16_t dw = regs.s - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 5; - } -static void Op1193(void) // CMPU DP - { - uint16_t adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++); - addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); - uint16_t dw = regs.u - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 7; - } -static void Op119C(void) // CMPS DP - { - uint16_t adr2 = (regs.dp<<8)|regs.RdMem(regs.pc++); - addr = (regs.RdMem(adr2)<<8) | regs.RdMem(adr2+1); - uint16_t dw = regs.s - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 7; - } -static void Op11A3(void) // CMPU IDX - { - uint16_t addr2 = DecodeIDX(regs.RdMem(regs.pc++)); - addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1); - uint16_t dw = regs.u - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.u < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^regs.u^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 7; - } -static void Op11AC(void) // CMPS IDX - { - uint16_t addr2 = DecodeIDX(regs.RdMem(regs.pc++)); - addr = (regs.RdMem(addr2)<<8) | regs.RdMem(addr2+1); - uint16_t dw = regs.s - addr; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.s < addr ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^regs.s^addr^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 7; - } -static void Op11B3(void) // CMPU ABS - { - addr = FetchW(); uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - uint16_t dw = regs.u - addr2; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.u < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^regs.u^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 8; - } - -static void Op11BC(void) // CMPS ABS -{ - addr = FetchW(); uint16_t addr2 = (regs.RdMem(addr)<<8) | regs.RdMem(addr+1); - uint16_t dw = regs.s - addr2; - (dw == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag - (dw&0x8000 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag - (regs.s < addr2 ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag - (((regs.cc<<15)^regs.s^addr2^dw)&0x8000 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerfl - regs.clock += 8; +static void Op01(void) +{ + Op00(); // NEG DP } + //temp, for testing... #ifdef __DEBUG__ static uint8_t backTrace[256]; static uint16_t btPC[256]; static int btPtr = 0;//*/ #endif -static void Op__(void) // Illegal opcode +static void Op__(void) // Illegal opcode { regs.clock++; // illegal = true; @@ -3063,6 +3312,98 @@ for(int i=0; i<256; i++) #endif } +// +// Function arrays +// + +// These are defined below, so we just use forward declarations here to prevent the compiler barfing... +static void Op10(void); +static void Op11(void); + +// Array of page zero opcode functions... + +static void (* exec_op0[256])() = { + Op00, Op01, Op__, Op03, Op04, Op__, Op06, Op07, Op08, Op09, Op0A, Op__, Op0C, Op0D, Op0E, Op0F, + Op10, Op11, Op12, Op13, Op__, Op__, Op16, Op17, Op__, Op19, Op1A, Op__, Op1C, Op1D, Op1E, Op1F, + Op20, Op21, Op22, Op23, Op24, Op25, Op26, Op27, Op28, Op29, Op2A, Op2B, Op2C, Op2D, Op2E, Op2F, + Op30, Op31, Op32, Op33, Op34, Op35, Op36, Op37, Op__, Op39, Op3A, Op3B, Op3C, Op3D, Op3E, Op3F, + Op40, Op__, Op__, Op43, Op44, Op__, Op46, Op47, Op48, Op49, Op4A, Op__, Op4C, Op4D, Op__, Op4F, + Op50, Op__, Op__, Op53, Op54, Op__, Op56, Op57, Op58, Op59, Op5A, Op__, Op5C, Op5D, Op__, Op5F, + Op60, Op__, Op__, Op63, Op64, Op__, Op66, Op67, Op68, Op69, Op6A, Op__, Op6C, Op6D, Op6E, Op6F, + Op70, Op__, Op__, Op73, Op74, Op__, Op76, Op77, Op78, Op79, Op7A, Op__, Op7C, Op7D, Op7E, Op7F, + Op80, Op81, Op82, Op83, Op84, Op85, Op86, Op__, Op88, Op89, Op8A, Op8B, Op8C, Op8D, Op8E, Op__, + Op90, Op91, Op92, Op93, Op94, Op95, Op96, Op97, Op98, Op99, Op9A, Op9B, Op9C, Op9D, Op9E, Op9F, + OpA0, OpA1, OpA2, OpA3, OpA4, OpA5, OpA6, OpA7, OpA8, OpA9, OpAA, OpAB, OpAC, OpAD, OpAE, OpAF, + OpB0, OpB1, OpB2, OpB3, OpB4, OpB5, OpB6, OpB7, OpB8, OpB9, OpBA, OpBB, OpBC, OpBD, OpBE, OpBF, + OpC0, OpC1, OpC2, OpC3, OpC4, OpC5, OpC6, Op__, OpC8, OpC9, OpCA, OpCB, OpCC, Op__, OpCE, Op__, + OpD0, OpD1, OpD2, OpD3, OpD4, OpD5, OpD6, OpD7, OpD8, OpD9, OpDA, OpDB, OpDC, OpDD, OpDE, OpDF, + OpE0, OpE1, OpE2, OpE3, OpE4, OpE5, OpE6, OpE7, OpE8, OpE9, OpEA, OpEB, OpEC, OpED, OpEE, OpEF, + OpF0, OpF1, OpF2, OpF3, OpF4, OpF5, OpF6, OpF7, OpF8, OpF9, OpFA, OpFB, OpFC, OpFD, OpFE, OpFF +}; + +// Array of page one opcode functions... +static void (* exec_op1[256])() = { + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op1021, Op1022, Op1023, Op1024, Op1025, Op1026, Op1027, Op1028, Op1029, Op102A, Op102B, Op102C, Op102D, Op102E, Op102F, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op103F, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op1083, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op108C, Op__, Op108E, Op__, + Op__, Op__, Op__, Op1093, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op109C, Op__, Op109E, Op109F, + Op__, Op__, Op__, Op10A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10AC, Op__, Op10AE, Op10AF, + Op__, Op__, Op__, Op10B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10BC, Op__, Op10BE, Op10BF, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10CE, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10DE, Op10DF, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10EE, Op10EF, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op10FE, Op10FF +}; + +// Array of page two opcode functions... +static void (* exec_op2[256])() = { + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op113F, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op1183, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op118C, Op__, Op__, Op__, + Op__, Op__, Op__, Op1193, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op119C, Op__, Op__, Op__, + Op__, Op__, Op__, Op11A3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11AC, Op__, Op__, Op__, + Op__, Op__, Op__, Op11B3, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op11BC, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, + Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__, Op__ +}; + + +// These are here to save typing a ton of forward declarations... + + +// Page 1 opcode +static void Op10(void) +{ +// exec_op1[regs.RdMem(regs.pc++)](); + uint8_t opcode = regs.RdMem(regs.pc++); + exec_op1[opcode](); + regs.clock += page1Cycles[opcode]; +} + + +// Page 2 opcode +static void Op11(void) +{ +// exec_op2[regs.RdMem(regs.pc++)](); + uint8_t opcode = regs.RdMem(regs.pc++); + exec_op2[opcode](); + regs.clock += page2Cycles[opcode]; +} + // // Internal "memcpy" (so we don't have to link with any external libraries!) @@ -3075,6 +3416,7 @@ static void myMemcpy(void * dst, void * src, uint32_t size) d[i] = s[i]; } + // // Function to execute 6809 instructions // @@ -3087,28 +3429,25 @@ uint8_t backTrace[256]; V6809REGS btRegs[256]; bool tripped = false; #endif -#ifdef __DEBUG__ -//Here so this can be externally linked -bool disasm = false; -//bool disasm = true; -#endif void Execute6809(V6809REGS * context, uint32_t cycles) { - // If this is not in place, the clockOverrun calculations can cause the V6809 to get - // stuck in an infinite loop. - if (cycles == 0) // Nothing to do, so bail! + // If this is not in place, the clockOverrun calculations can cause the + // V6809 to get stuck in an infinite loop. + if (cycles == 0) return; myMemcpy(®s, context, sizeof(V6809REGS)); + // Explode flags register into individual uint8_ts + UNPACK_FLAGS; // Execute here... - // Since we can't guarantee that we'll execute the number of cycles passed in - // exactly, we have to keep track of how much we overran the number of cycles - // the last time we executed. Since we already executed those cycles, this time - // through we remove them from the cycles passed in in order to come out - // approximately even. Over the long run, this unevenness in execution times - // evens out. + // Since we can't guarantee that we'll execute the number of cycles passed + // in exactly, we have to keep track of how much we overran the number of + // cycles the last time we executed. Since we already executed those + // cycles, this time through we remove them from the cycles passed in in + // order to come out approximately even. Over the long run, this unevenness + // in execution times evens out. :-) uint64_t endCycles = regs.clock + (uint64_t)(cycles - regs.clockOverrun); while (regs.clock < endCycles) @@ -3138,8 +3477,16 @@ if (!tripped) } #endif #ifdef __DEBUG__ -//Decode6809(regs.pc); -if (disasm) Decode6809(regs); +if (disasm) +{ + Decode6809(regs); +// WriteLog("[e=%02X,f=%02X,h=%02X,i=%02X,n=%02X,z=%02X,v=%02X,c=%02X]", flagE, flagF, flagH, flagI, flagN, flagZ, flagV, flagC); +} +#if 0 //we solved this... +if ((flagE | flagF | flagH | flagI | flagN | flagZ | flagV | flagC) > 1) + WriteLog("\n\n!!! FLAG OUT OF BOUNDS !!!\n\n"); +#endif +//static bool disasm = false; /*//if (regs.pc == 0x15BA) disasm = true; //if (regs.pc == 0xFE76) disasm = true; if (regs.x == 0xFED4) disasm = true; @@ -3151,7 +3498,10 @@ if (disasm) Decode6809(regs.pc); btPC[btPtr] = regs.pc; btPtr = (btPtr + 1) & 0xFF;//*/ #endif - exec_op0[regs.RdMem(regs.pc++)](); +// exec_op0[regs.RdMem(regs.pc++)](); + uint8_t opcode = regs.RdMem(regs.pc++); + exec_op0[opcode](); + regs.clock += page0Cycles[opcode]; // Handle any pending interrupts @@ -3164,7 +3514,7 @@ btPtr = (btPtr + 1) & 0xFF;//*/ #ifdef __DEBUG__ if (disasm) WriteLog("\nV6809: RESET line asserted!\n"); #endif - regs.cc |= (FLAG_F | FLAG_I); // Set F, I + flagF = flagI = 1; // Set F, I regs.dp = 0; // Reset direct page register regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector context->cpuFlags &= ~V6809_ASSERT_LINE_RESET; @@ -3175,22 +3525,19 @@ if (disasm) WriteLog("\nV6809: RESET line asserted!\n"); #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... - regs.WrMem(--regs.s, regs.pc >> 8); - regs.WrMem(--regs.s, regs.u & 0xFF); - regs.WrMem(--regs.s, regs.u >> 8); - regs.WrMem(--regs.s, regs.y & 0xFF); - regs.WrMem(--regs.s, regs.y >> 8); - regs.WrMem(--regs.s, regs.x & 0xFF); - regs.WrMem(--regs.s, regs.x >> 8); - regs.WrMem(--regs.s, regs.dp); - regs.WrMem(--regs.s, regs.b); - regs.WrMem(--regs.s, regs.a); - regs.WrMem(--regs.s, regs.cc); - - regs.cc |= (FLAG_I | FLAG_F); // Set IRQ/FIRQ suppress flags + flagE = 1; // Set Entire flag + regs.cc = PACK_FLAGS; // Mash flags back into the CC register + + PUSHS16(regs.pc); // Save all regs... + PUSHS16(regs.u); + PUSHS16(regs.y); + PUSHS16(regs.x); + PUSHS(regs.dp); + PUSHS(regs.b); + PUSHS(regs.a); + PUSHS(regs.cc); + + flagI = flagF = 1; // Set IRQ/FIRQ suppress flags regs.pc = RdMemW(0xFFFC); // And load PC with the NMI vector regs.clock += 19; // context->cpuFlags &= ~V6809_ASSERT_LINE_NMI;// Reset the asserted line (NMI)... @@ -3201,18 +3548,18 @@ if (disasm) WriteLog("\nV6809: NMI line asserted!\n"); #ifdef __DEBUG__ if (disasm) WriteLog("\nV6809: FIRQ line asserted!\n"); #endif - if (!(regs.cc & FLAG_F)) // Is the FIRQ masked (F == 1)? + if (!flagF) // Is the FIRQ masked (F == 1)? { #ifdef __DEBUG__ if (disasm) WriteLog(" FIRQ taken...\n"); #endif - regs.cc &= ~FLAG_E; // Clear the Entire flag + flagE = 0; // Clear Entire flag + regs.cc = PACK_FLAGS; // Mash flags back into the CC register - regs.WrMem(--regs.s, regs.pc & 0xFF); // Save PC, CC regs... - regs.WrMem(--regs.s, regs.pc >> 8); - regs.WrMem(--regs.s, regs.cc); + PUSHS16(regs.pc); + PUSHS(regs.cc); - regs.cc |= (FLAG_I | FLAG_F); // Set IRQ/FIRQ suppress flags + flagI = flagF = 1; // Set IRQ/FIRQ suppress flags regs.pc = RdMemW(0xFFF6); // And load PC with the IRQ vector regs.clock += 10; // context->cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)... @@ -3224,56 +3571,49 @@ if (disasm) WriteLog(" FIRQ taken...\n"); #ifdef __DEBUG__ if (disasm) WriteLog("\nV6809: IRQ line asserted!\n"); #endif - if (!(regs.cc & FLAG_I)) // Is the IRQ masked (I == 1)? + if (!flagI) // 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... - regs.WrMem(--regs.s, regs.pc >> 8); - regs.WrMem(--regs.s, regs.u & 0xFF); - regs.WrMem(--regs.s, regs.u >> 8); - regs.WrMem(--regs.s, regs.y & 0xFF); - regs.WrMem(--regs.s, regs.y >> 8); - regs.WrMem(--regs.s, regs.x & 0xFF); - regs.WrMem(--regs.s, regs.x >> 8); - regs.WrMem(--regs.s, regs.dp); - regs.WrMem(--regs.s, regs.b); - regs.WrMem(--regs.s, regs.a); - regs.WrMem(--regs.s, regs.cc); - - regs.cc |= FLAG_I; // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags] + flagE = 1; // Set the Entire flag + regs.cc = PACK_FLAGS; // Mash flags back into the CC register + + PUSHS16(regs.pc); + PUSHS16(regs.u); + PUSHS16(regs.y); + PUSHS16(regs.x); + PUSHS(regs.dp); + PUSHS(regs.b); + PUSHS(regs.a); + PUSHS(regs.cc); + + flagI = 1; // Specs say that it doesn't affect FIRQ... or FLAG_F [WAS: Set IRQ/FIRQ suppress flags] regs.pc = RdMemW(0xFFF8); // And load PC with the IRQ vector regs.clock += 19; // Apparently, not done here! -// Need to put IRQ handling in somewhere... It shouldn't be cleared here! // context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)... // regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)... } } #ifdef __DEBUG__ -if (disasm) WriteLog("\tCC=%s%s%s%s%s%s%s%s A=%02X B=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n", - (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" : "-"), +if (disasm) WriteLog("CC=%s%s%s%s%s%s%s%s A=%02X B=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n", + (flagE ? "E" : "-"), (flagF ? "F" : "-"), (flagH ? "H" : "-"), (flagI ? "I" : "-"), + (flagN ? "N" : "-"), (flagZ ? "Z" : "-"), (flagV ? "V" : "-"), (flagC ? "C" : "-"), regs.a, regs.b, 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 } + // Keep track of how much we overran so we can adjust on the next run... regs.clockOverrun = (uint32_t)(regs.clock - endCycles); + regs.cc = PACK_FLAGS; // Mash flags back into the CC register myMemcpy(context, ®s, sizeof(V6809REGS)); - -#ifdef __DEBUG__ - if (disasm) - WriteLog("\n*** CONTEXT SWITCH ***\n\n"); -#endif } + // // Get the clock of the currently executing CPU // @@ -3282,6 +3622,7 @@ uint64_t GetCurrentV6809Clock(void) return regs.clock; } + // // Get the PC of the currently executing CPU // @@ -3290,12 +3631,14 @@ uint16_t GetCurrentV6809PC(void) return regs.pc; } + // Set a line of the currently executing CPU void SetLineOfCurrentV6809(uint32_t line) { regs.cpuFlags |= line; } + // Clear a line of the currently executing CPU void ClearLineOfCurrentV6809(uint32_t line) { @@ -3305,3 +3648,32 @@ if (disasm) #endif regs.cpuFlags &= ~line; } + + +#if 0 +FE54: 27 6A BEQ $FEC0 CC=EF-I-Z-- A=39 B=01 DP=00 X=FEE2 Y=F51 +E S=BFFF U=0000 PC=FEC0 +FEC0: 6E A4 JMP ,Y CC=EF-I-Z-- A=39 B=01 DP=00 X=FEE2 Y=F51E S=BFFF + U=0000 PC=F51E +F51E: 86 34 LDA #$34 CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF + U=0000 PC=F520 +F520: B7 C8 0D STA $C80D CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F523 +F523: B7 C8 0F STA $C80F CC=EF-I---- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F526 +F526: 7F C8 0E CLR $C80EV6809: Clearing line IRQ... CC=EF-I-Z-- A=34 B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F529 +F529: 86 9C LDA #$9C CC=EF-IN--- A=9C B=01 DP=00 X=FEE2 Y=F51E S=BFFF U=0000 PC=F52B +F52B: 1F 8B TFR A,DP CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFF U=0000 PC=F52D +F52D: 10 CE BF FF LDS #$BFFF CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFF U=0000 PC=F531 +F531: BD 13 BD JSR $13BD CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFFD U=0000 PC=13BD +13BD: 34 76 PSHS A B X Y U CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFF5 U=0000 PC=13BF +13BF: CE 9C 00 LDU #$9C00 CC=EF-IN--- A=9C B=01 DP=9C X=FEE2 Y=F51E S=BFF5 U=9C00 PC=13C2 +13C2: 8E 00 00 LDX #$0000 CC=EF-I-Z-- A=9C B=01 DP=9C X=0000 Y=F51E S=BFF5 U=9C00 PC=13C5 +13C5: 1F 12 TFR X,Y CC=EF-I-Z-- A=9C B=01 DP=9C X=0000 Y=0000 S=BFF5 U=9C00 PC=13C7 +13C7: 1F 10 TFR X,D CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFF5 U=9C00 PC=13C9 +13C9: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFEF U=9C00 PC=13CB +13CB: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFE9 U=9C00 PC=13CD +13CD: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFE3 U=9C00 PC=13CF +13CF: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFDD U=9C00 PC=13D1 +13D1: 36 36 PSHU A B X Y CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFD7 U=9C00 PC=13D3 +13D3: 36 10 PSHU X CC=EF-I-Z-- A=00 B=00 DP=9C X=0000 Y=0000 S=BFD5 U=9C00 PC=13D5 +13D5: 11 83 00 00 CMPU #$0000 CC=EF-IN--- A=00 B=00 DP=9C X=0000 Y=000 +#endif diff --git a/src/v6809.h b/src/v6809.h old mode 100644 new mode 100755 index 380318c..ae8a337 --- a/src/v6809.h +++ b/src/v6809.h @@ -1,9 +1,9 @@ // // Virtual 6809 Header file // -// by James Hammons +// by James L. Hammons // -// (C) 1997, 2014 Underground Software +// (C) 1997, 2004 Underground Software // #ifndef __V6809_H__ @@ -13,14 +13,14 @@ // Useful defines -#define FLAG_E 0x80 // Entire -#define FLAG_F 0x40 // Fast IRQ -#define FLAG_H 0x20 // Half carry -#define FLAG_I 0x10 // IRQ -#define FLAG_N 0x08 // Negative -#define FLAG_Z 0x04 // Zero -#define FLAG_V 0x02 // oVerflow -#define FLAG_C 0x01 // Carry +#define FLAG_E 0x80 // Entire +#define FLAG_F 0x40 // Fast IRQ +#define FLAG_H 0x20 // Half carry +#define FLAG_I 0x10 // IRQ +#define FLAG_N 0x08 // Negative +#define FLAG_Z 0x04 // Zero +#define FLAG_V 0x02 // oVerflow +#define FLAG_C 0x01 // Carry #define V6809_ASSERT_LINE_RESET 0x0001 // v6809 RESET line #define V6809_ASSERT_LINE_IRQ 0x0002 // v6809 IRQ line @@ -28,6 +28,7 @@ #define V6809_ASSERT_LINE_NMI 0x0008 // v6809 NMI line #define V6809_STATE_SYNC 0x0010 // v6809 SYNC line #define V6809_STATE_ILLEGAL_INST 0x0020 // Illegal instruction executed flag + //#define V6809_START_DEBUG_LOG EQU 0020h // Debug log go (temporary!) // Useful structs @@ -43,10 +44,9 @@ struct V6809REGS uint8_t a; // 6809 A register uint8_t b; // 6809 B register uint8_t dp; // 6809 Direct Page register -// uint32_t clock; // 6809 clock (@ 1 MHz, wraps at 71.5 minutes) uint64_t clock; // 6809 clock (@ 1 MHz, wraps at 570842 years) - uint8_t (* RdMem)(uint16_t); // Address of uint8_t read routine - void (* WrMem)(uint16_t, uint8_t); // Address of uint8_t write routine + uint8_t (* RdMem)(uint16_t); // Address of uint8 read routine + void (* WrMem)(uint16_t, uint8_t); // Address of uint8 write routine uint32_t cpuFlags; // v6809 IRQ/RESET flags uint32_t clockOverrun; }; diff --git a/src/ym2151.c b/src/ym2151.c index 46776ee..2074a4c 100644 --- a/src/ym2151.c +++ b/src/ym2151.c @@ -1,10 +1,17 @@ +// +// Jarek Burczynski's YM2151 emulator +// +// Cleaned of most MAMEisms & cleaned up in general by James Hammons +// (this is mostly a placeholder until I write my own) +// + +#include "ym2151.h" + #include #include #include #include #include -//#include "driver.h" -#include "ym2151.h" // Missing shit (from M.A.M.E.) @@ -12,9 +19,15 @@ #if 1 #define PI 3.1415629535897932338 static FILE * errorlog = 0; -int cpu_scalebyfcount(int); -void timer_remove(void *); -void * timer_set(int, int, void (*)(int)); +//int cpu_scalebyfcount(int); +//void timer_remove(void *); +//void * timer_set(int, int, void (*)(int)); + +// Bogus M.A.M.E. shite +int cpu_scalebyfcount(int f) { return f; } +void timer_remove(void * foo) { printf("STUB: timer_remove()\n"); } +void * timer_set(int foo, int bar, void (* baz)(int)) { printf("STUB: timer_set()\n"); return 0; } + #endif diff --git a/test/mcu-sound.cpp b/test/mcu-sound.cpp index 6c8f230..9430ac2 100644 --- a/test/mcu-sound.cpp +++ b/test/mcu-sound.cpp @@ -60,13 +60,6 @@ uint8_t ReadMemory(uint16_t address) // else if (address == 0x2021) // return input_port_1_r(0); -#if 0 - // This is a cheap hack to fool the MCU into thinking something's - // attached to it... - if (address == 0x1181) - return 0xA6; -#endif - return memory[address]; }