//
-// Virtual 6808 Emulator v2.0
+// Virtual 6808 Emulator v2.1
//
-// by James L. Hammons
+// by James Hammons
// (C) 2006 Underground Software
//
-// JLH = James L. Hammons <jlhamm@acm.org>
+// JLH = James Hammons <jlhamm@acm.org>
//
// WHO WHEN WHAT
// --- ---------- ------------------------------------------------------------
// 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
+// JLH 09/21/2009 Fixed EA_ABS macros
//
// NOTE: V6808_STATE_WAI is not handled in the main loop correctly. !!! FIX !!!
-// Some random thoughts: Could there be a performance gain by breaking
-// out the flags in regs.cc into separate uint8 variables (or bools)?
-// You'd have to convert on entering and exiting the emulation loop, but I
-// think the perfomance hit would be negligible compared to the gain in not
-// having to mask and shift flags all the time. Investigate after the
-// conversion to macro style opcodes is completed. :-)
-// [DONE--remain to be seen if there is any performance increase]
-
-//#define __DEBUG__
+#define TEST_DONT_BRANCH_OPTIMIZATION
#include "v6808.h"
// Various macros
-#if 0
-#define CLR_Z (regs.cc &= ~FLAG_Z)
-#define CLR_ZN (regs.cc &= ~(FLAG_Z | FLAG_N))
-#define CLR_ZNC (regs.cc &= ~(FLAG_Z | FLAG_N | FLAG_C))
-#define CLR_NVC (regs.cc &= ~(FLAG_N | FLAG_V | FLAG_C))
-#define CLR_VC (regs.cc &= ~(FLAG_V | FLAG_C))
-#define CLR_V (regs.cc &= ~FLAG_V)
-#define CLR_N (regs.cc &= ~FLAG_N)
-#define SET_Z(r) (regs.cc = ((r) == 0 ? regs.cc | FLAG_Z : regs.cc & ~FLAG_Z))
-#define SET_N(r) (regs.cc = ((r) & 0x80 ? regs.cc | FLAG_N : regs.cc & ~FLAG_N))
-#define SET_V(a,b,r) (regs.cc = ((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x80 ? regs.cc | FLAG_V : regs.cc & ~FLAG_V)
-
-//Not sure that this code is computing the carry correctly... Investigate! [Seems to be]
-#define SET_C_ADD(a,b) (regs.cc = ((uint8)(b) > (uint8)(~(a)) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
-#define SET_C_CMP(a,b) (regs.cc = ((uint8)(b) < (uint8)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
-#define SET_ZN(r) SET_N(r); SET_Z(r)
-#define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b)
-#define SET_ZNVC_CMP(a,b,r) SET_N(r); SET_Z(r); SET_C_CMP(a,b); SET_V(a,b,r)
-
-#define SET_N16(r) (regs.cc = ((r) & 0x8000 ? regs.cc | FLAG_N : regs.cc & ~FLAG_N))
-#define SET_V16(a,b,r) (regs.cc = ((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x8000 ? regs.cc | FLAG_V : regs.cc & ~FLAG_V)
-#define SET_C_CMP16(a,b) (regs.cc = ((uint16)(b) < (uint16)(a) ? regs.cc | FLAG_C : regs.cc & ~FLAG_C))
-#define SET_ZNVC_CMP16(a,b,r) SET_N16(r); SET_Z(r); SET_C_CMP16(a,b); SET_V16(a,b,r)
-#else
#define CLR_Z (flagZ = 0)
#define CLR_ZN (flagZ = flagN = 0)
#define CLR_ZNC (flagZ = flagN = flagC = 0)
#define SET_N(r) (flagN = ((r) & 0x80) >> 7)
#define SET_V(a,b,r) (flagV = (((b) ^ (a) ^ (r) ^ ((r) >> 1)) & 0x80) >> 7)
-#define SET_C_CMP(a,b) (flagC = ((uint8)(b) < (uint8)(a) ? 1 : 0))
+#define SET_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)(b) < (uint16)(a) ? 1 : 0))
+#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)
-#endif
-//Small problem with the EA_ macros: ABS macros don't increment the PC!!! !!! FIX !!! [DONE, kinda]
#define EA_IMM regs.pc++
#define EA_ZP regs.RdMem(regs.pc++)
#define EA_ZP_X (regs.RdMem(regs.pc++) + regs.x)
-#define EA_ABS RdMemW(regs.pc)
+#define 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_ABS regs.RdMem(EA_ABS); regs.pc += 2
+#define READ_ABS regs.RdMem(EA_ABS)
-#define READ_IMM16 RdMemW(regs.pc); regs.pc += 2
+#define READ_IMM16 FetchMemW(regs.pc);
#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_ABS16 RdMemW(EA_ABS)
-#define READ_IMM_WB(v) uint16 addr = EA_IMM; v = regs.RdMem(addr)
-#define READ_ZP_WB(v) uint16 addr = EA_ZP; v = regs.RdMem(addr)
-#define READ_ZP_X_WB(v) uint16 addr = EA_ZP_X; v = regs.RdMem(addr)
-#define READ_ABS_WB(v) uint16 addr = EA_ABS; v = regs.RdMem(addr); regs.pc += 2
+#define READ_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)
#define WRITE_BACK(d) regs.WrMem(addr, (d))
// Private global variables
static V6808REGS regs;
-static uint8 flagH, flagI, flagN, flagZ, flagV, flagC;
+static uint8_t flagH, flagI, flagN, flagZ, flagV, flagC;
-static uint8 CPUCycles[256] = {
+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,
// Private function prototypes
-static uint16 RdMemW(uint16);
+static uint16_t RdMemW(uint16_t);
+static uint16_t FetchMemW(uint16_t);
//
// Read a word out of 6808 memory (little endian format)
//
-static inline uint16 RdMemW(uint16 address)
+static inline uint16_t RdMemW(uint16_t address)
{
- return (uint16)(regs.RdMem(address) << 8) | regs.RdMem(address + 1);
+ return (uint16_t)(regs.RdMem(address) << 8) | regs.RdMem(address + 1);
+}
+
+//
+// Fetch a word out of 6808 memory (little endian format). Increments PC
+//
+static inline uint16_t FetchMemW(uint16_t address)
+{
+ regs.pc += 2;
+ return (uint16_t)(regs.RdMem(address) << 8) | regs.RdMem(address + 1);
}
//
//
/*
-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|
+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 sum = (uint16)(acc) + (m); \
- regs.cc = (regs.cc & ~FLAG_C) | (sum >> 8); \
- regs.cc = (regs.cc & ~FLAG_H) | ((sum << 1) & FLAG_H); \
- SET_V(m, acc, sum); \
- (acc) = sum & 0xFF; \
- SET_ZN(acc)
#define OP_ADD_HANDLER(m, acc) \
- uint16 sum = (uint16)(acc) + (m); \
+ uint16_t sum = (uint16_t)(acc) + (m); \
flagC = sum >> 8; \
flagH = (sum >> 4) & 0x01; \
SET_V(m, acc, sum); \
static void Op8B(void) // ADDA #
{
- uint16 m = READ_IMM;
+ uint16_t m = READ_IMM;
OP_ADD_HANDLER(m, regs.a);
}
static void Op9B(void) // ADDA ZP
{
- uint16 m = READ_ZP;
+ uint16_t m = READ_ZP;
OP_ADD_HANDLER(m, regs.a);
}
static void OpAB(void) // ADDA ZP, X
{
- uint16 m = READ_ZP_X;
+ uint16_t m = READ_ZP_X;
OP_ADD_HANDLER(m, regs.a);
}
static void OpBB(void) // ADDA ABS
{
- uint16 m = READ_ABS;
+ uint16_t m = READ_ABS;
OP_ADD_HANDLER(m, regs.a);
}
static void OpCB(void) // ADDB #
{
- uint16 m = READ_IMM;
+ uint16_t m = READ_IMM;
OP_ADD_HANDLER(m, regs.b);
}
static void OpDB(void) // ADDB ZP
{
- uint16 m = READ_ZP;
+ uint16_t m = READ_ZP;
OP_ADD_HANDLER(m, regs.b);
}
static void OpEB(void) // ADDB ZP, X
{
- uint16 m = READ_ZP_X;
+ uint16_t m = READ_ZP_X;
OP_ADD_HANDLER(m, regs.b);
}
static void OpFB(void) // ADDB ABS
{
- uint16 m = READ_ABS;
+ uint16_t m = READ_ABS;
OP_ADD_HANDLER(m, regs.b);
}
}
/*
-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|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Add with Carry |ADCA |89 2 2|99 3 2|A9 5 2|B9 4 3| |A=A+M+C |T TTTT|
+ |ADCB |C9 2 2|D9 3 2|E9 5 2|F9 4 3| |B=B+M+C |T TTTT|
*/
// ADC opcodes
-//#define OP_ADC_HANDLER(m, acc) \
- uint16 sum = (uint16)acc + (m) + (uint16)(regs.cc & FLAG_C); \
- regs.cc = (regs.cc & ~FLAG_C) | (sum >> 8); \
- regs.cc = (regs.cc & ~FLAG_H) | ((sum << 1) & FLAG_H); \
- SET_V(m, acc, sum); \
- acc = sum & 0xFF; \
- SET_ZN(acc)
#define OP_ADC_HANDLER(m, acc) \
- uint16 sum = (uint16)acc + (m) + (uint16)flagC; \
+ uint16_t sum = (uint16_t)acc + (m) + (uint16_t)flagC; \
flagC = sum >> 8; \
flagH = (sum >> 4) & 0x01; \
SET_V(m, acc, sum); \
static void Op89(void) // ADCA #
{
- uint16 m = READ_IMM;
+ uint16_t m = READ_IMM;
OP_ADC_HANDLER(m, regs.a);
}
static void Op99(void) // ADCA ZP
{
- uint16 m = READ_ZP;
+ uint16_t m = READ_ZP;
OP_ADC_HANDLER(m, regs.a);
}
static void OpA9(void) // ADCA ZP, X
{
- uint16 m = READ_ZP_X;
+ uint16_t m = READ_ZP_X;
OP_ADC_HANDLER(m, regs.a);
}
static void OpB9(void) // ADCA ABS
{
- uint16 m = READ_ABS;
+ uint16_t m = READ_ABS;
OP_ADC_HANDLER(m, regs.a);
}
static void OpC9(void) // ADCB #
{
- uint16 m = READ_IMM;
+ uint16_t m = READ_IMM;
OP_ADC_HANDLER(m, regs.b);
}
static void OpD9(void) // ADCB ZP
{
- uint16 m = READ_ZP;
+ uint16_t m = READ_ZP;
OP_ADC_HANDLER(m, regs.b);
}
static void OpE9(void) // ADCB ZP, X
{
- uint16 m = READ_ZP_X;
+ uint16_t m = READ_ZP_X;
OP_ADC_HANDLER(m, regs.b);
}
static void OpF9(void) // ADCB ABS
{
- uint16 m = READ_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 |
+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
static void Op84(void) // ANDA #
{
- uint8 m = READ_IMM;
+ uint8_t m = READ_IMM;
OP_AND_HANDLER(m, regs.a);
}
static void Op94(void) // ANDA ZP
{
- uint8 m = READ_ZP;
+ uint8_t m = READ_ZP;
OP_AND_HANDLER(m, regs.a);
}
static void OpA4(void) // ANDA ZP, X
{
- uint16 m = READ_ZP_X;
+ uint16_t m = READ_ZP_X;
OP_AND_HANDLER(m, regs.a);
}
static void OpB4(void) // ANDA ABS
{
- uint16 m = READ_ABS;
+ uint16_t m = READ_ABS;
OP_AND_HANDLER(m, regs.a);
}
static void OpC4(void) // ANDB #
{
- uint8 m = READ_IMM;
+ uint8_t m = READ_IMM;
OP_AND_HANDLER(m, regs.b);
}
static void OpD4(void) // ANDB ZP
{
- uint8 m = READ_ZP;
+ uint8_t m = READ_ZP;
OP_AND_HANDLER(m, regs.b);
}
static void OpE4(void) // ANDB ZP, X
{
- uint16 m = READ_ZP_X;
+ uint16_t m = READ_ZP_X;
OP_AND_HANDLER(m, regs.b);
}
static void OpF4(void) // ANDB ABS
{
- uint16 m = READ_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 |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Bit Test |BITA |85 2 2|95 3 2|A5 5 2|B5 4 3| |A+M | TTR |
+ |BITB |C5 2 2|D5 3 2|E5 5 2|F5 4 3| |B+M | TTR |
*/
// BIT opcodes
#define OP_BIT_HANDLER(m, acc) \
- int8 result = acc & (m); \
+ int8_t result = acc & (m); \
SET_ZN(result)
static void Op85(void) // BITA #
{
- uint8 m = READ_IMM;
+ uint8_t m = READ_IMM;
OP_BIT_HANDLER(m, regs.a);
}
static void Op95(void) // BITA ZP
{
- uint8 m = READ_ZP;
+ uint8_t m = READ_ZP;
OP_BIT_HANDLER(m, regs.a);
}
static void OpA5(void) // BITA ZP, X
{
- uint8 m = READ_ZP_X;
+ uint8_t m = READ_ZP_X;
OP_BIT_HANDLER(m, regs.a);
}
static void OpB5(void) // BITA ABS
{
- uint8 m = READ_ABS;
+ uint8_t m = READ_ABS;
OP_BIT_HANDLER(m, regs.a);
}
static void OpC5(void) // BITB #
{
- uint8 m = READ_IMM;
+ uint8_t m = READ_IMM;
OP_BIT_HANDLER(m, regs.b);
}
static void OpD5(void) // BITB ZP
{
- uint8 m = READ_ZP;
+ uint8_t m = READ_ZP;
OP_BIT_HANDLER(m, regs.b);
}
static void OpE5(void) // BITB ZP, X
{
- uint8 m = READ_ZP_X;
+ uint8_t m = READ_ZP_X;
OP_BIT_HANDLER(m, regs.b);
}
static void OpF5(void) // BITB ABS
{
- uint8 m = READ_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|
+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 Op7F(void) // CLR ABS
{
regs.WrMem(EA_ABS, 0);
- regs.pc += 2;
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|
+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
*/
#define OP_CMP_HANDLER(m, acc) \
- uint16 result = acc - (m); \
+ uint16_t result = acc - (m); \
SET_ZNVC_CMP(m, acc, result)
static void Op81(void) // CMPA #
{
- uint8 m = READ_IMM;
+ uint8_t m = READ_IMM;
OP_CMP_HANDLER(m, regs.a);
}
static void Op91(void) // CMPA ZP
{
- uint8 m = READ_ZP;
+ uint8_t m = READ_ZP;
OP_CMP_HANDLER(m, regs.a);
}
static void OpA1(void) // CMPA ZP, X
{
- uint8 m = READ_ZP_X;
+ uint8_t m = READ_ZP_X;
OP_CMP_HANDLER(m, regs.a);
}
static void OpB1(void) // CMPA ABS
{
- uint8 m = READ_ABS;
+ uint8_t m = READ_ABS;
OP_CMP_HANDLER(m, regs.a);
}
static void OpC1(void) // CMPB #
{
- uint8 m = READ_IMM;
+ uint8_t m = READ_IMM;
OP_CMP_HANDLER(m, regs.b);
}
static void OpD1(void) // CMPB ZP
{
- uint8 m = READ_ZP;
+ uint8_t m = READ_ZP;
OP_CMP_HANDLER(m, regs.b);
}
static void OpE1(void) // CMPB ZP, X
{
- uint8 m = READ_ZP_X;
+ uint8_t m = READ_ZP_X;
OP_CMP_HANDLER(m, regs.b);
}
static void OpF1(void) // CMPB ABS
{
- uint8 m = READ_ABS;
+ uint8_t m = READ_ABS;
OP_CMP_HANDLER(m, regs.b);
}
}
/*
-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|
+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; \
- regs.cc |= FLAG_C
#define OP_COM_HANDLER(m) \
m = m ^ 0xFF; \
SET_ZN(m); \
static void Op63(void) // COM ZP, X
{
- uint8 m;
+ uint8_t m;
READ_ZP_X_WB(m);
OP_COM_HANDLER(m);
WRITE_BACK(m);
static void Op73(void) // COM ABS
{
- uint8 m;
+ uint8_t m;
READ_ABS_WB(m);
OP_COM_HANDLER(m);
WRITE_BACK(m);
}
/*
-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|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Complement 2's |NEG | | |60 7 2|70 6 3| |M=00-M | TT12|
+ |NEGA | | | | |40 2 1|A=00-A | TT12|
+ |NEGB | | | | |50 2 1|B=00-B | TT12|
*/
// NEG opcodes
-//#define OP_NEG_HANDLER(m) \
- m = -m; \
- SET_ZN(m); \
- regs.cc = (m == 0x80 ? regs.cc | FLAG_V : regs.cc & ~FLAG_V); \
- regs.cc = (m == 0x00 ? regs.cc | FLAG_C : regs.cc & ~FLAG_C)
#define OP_NEG_HANDLER(m) \
m = -m; \
SET_ZN(m); \
static void Op60(void) // NEG ZP, X
{
- uint8 m;
+ uint8_t m;
READ_ZP_X_WB(m);
OP_NEG_HANDLER(m);
WRITE_BACK(m);
static void Op70(void) // NEG ABS
{
- uint8 m;
+ uint8_t m;
READ_ABS_WB(m);
OP_NEG_HANDLER(m);
WRITE_BACK(m);
}
/*
-Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
- | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
-Decimal Adjust |DAA | | | | |19 2 1|* | TTT3|
+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
{
-#if 0 // Just because we can optimize a little here, we will... ;-)
- uint16 adjust = 0;
-
- if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H))
- adjust |= 0x06;
+ uint16_t result = (uint16_t)regs.a;
- if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
- adjust |= 0x60;
-
- uint16 result = regs.a + adjust;
- regs.a = (uint8)result;
- SET_ZN(result);
- CLR_V; // Not sure this is correct...
- regs.cc |= (result & 0x100) >> 8; // Overwrite carry if it was 0, otherwise, ignore
-#else
- uint16 result = (uint16)regs.a;
-
-// if ((regs.a & 0x0F) > 0x09 || (regs.cc & FLAG_H))
if ((regs.a & 0x0F) > 0x09 || flagH)
result += 0x06;
-// if ((regs.a & 0xF0) > 0x90 || (regs.cc & FLAG_C) || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
if ((regs.a & 0xF0) > 0x90 || flagC || ((regs.a & 0xF0) > 0x80 && (regs.a & 0x0F) > 0x09))
result += 0x60;
- regs.a = (uint8)result;
+ regs.a = (uint8_t)result;
SET_ZN(result);
CLR_V; // Not sure this is correct...
-// regs.cc |= (result & 0x100) >> 8; // Overwrite carry if it was 0, otherwise, ignore
flagC |= (result & 0x100) >> 8; // Overwrite carry if it was 0, otherwise, ignore
-#endif
}
/*
-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 |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Decrement |DEC | | |6A 7 2|7A 6 3| |M=M-1 | TT4 |
+ |DECA | | | | |4A 2 1|A=A-1 | TT4 |
+ |DECB | | | | |5A 2 1|B=B-1 | TT4 |
*/
// DEC opcodes
-//#define OP_DEC_HANDLER(m) \
- m--; \
- SET_ZN(m); \
- regs.cc = (m == 0x7F ? regs.cc | FLAG_V : regs.cc & ~FLAG_V)
#define OP_DEC_HANDLER(m) \
m--; \
SET_ZN(m); \
static void Op6A(void) // DEC ZP, X
{
- uint8 m;
+ uint8_t m;
READ_ZP_X_WB(m);
OP_DEC_HANDLER(m);
WRITE_BACK(m);
static void Op7A(void) // DEC ABS
{
- uint8 m;
+ uint8_t m;
READ_ABS_WB(m);
OP_DEC_HANDLER(m);
WRITE_BACK(m);
}
/*
-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 |
+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
static void Op88(void) // EORA #
{
- uint8 m = READ_IMM;
+ uint8_t m = READ_IMM;
OP_EOR_HANDLER(m, regs.a);
}
static void Op98(void) // EORA ZP
{
- uint8 m = READ_ZP;
+ uint8_t m = READ_ZP;
OP_EOR_HANDLER(m, regs.a);
}
static void OpA8(void) // EORA ZP, X
{
- uint8 m = READ_ZP_X;
+ uint8_t m = READ_ZP_X;
OP_EOR_HANDLER(m, regs.a);
}
static void OpB8(void) // EORA ABS
{
- uint8 m = READ_ABS;
+ uint8_t m = READ_ABS;
OP_EOR_HANDLER(m, regs.a);
}
static void OpC8(void) // EORB #
{
- uint8 m = READ_IMM;
+ uint8_t m = READ_IMM;
OP_EOR_HANDLER(m, regs.b);
}
static void OpD8(void) // EORB ZP
{
- uint8 m = READ_ZP;
+ uint8_t m = READ_ZP;
OP_EOR_HANDLER(m, regs.b);
}
static void OpE8(void) // EORB ZP, X
{
- uint8 m = READ_ZP_X;
+ uint8_t m = READ_ZP_X;
OP_EOR_HANDLER(m, regs.b);
}
static void OpF8(void) // EORB ABS
{
- uint8 m = READ_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 |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Increment |INC | | |6C 7 2|7C 6 3| |M=M+1 | TT5 |
+ |INCA | | | | |4C 2 1|A=A+1 | TT5 |
+ |INCB | | | | |5C 2 1|B=B+1 | TT5 |
*/
// INC opcodes
-//#define OP_INC_HANDLER(m) \
- m++; \
- SET_ZN(m); \
- regs.cc = (m == 0x80 ? regs.cc | FLAG_V : regs.cc & ~FLAG_V)
#define OP_INC_HANDLER(m) \
m++; \
SET_ZN(m); \
static void Op6C(void) // INC ZP, X
{
- uint8 m;
+ uint8_t m;
READ_ZP_X_WB(m);
OP_INC_HANDLER(m);
WRITE_BACK(m);
static void Op7C(void) // INC ABS
{
- uint8 m;
+ uint8_t m;
READ_ABS_WB(m);
OP_INC_HANDLER(m);
WRITE_BACK(m);
}
/*
-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 |
+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
static void Op86(void) // LDAA #
{
- uint8 m = READ_IMM;
+ uint8_t m = READ_IMM;
OP_LDA_HANDLER(m, regs.a);
}
static void Op96(void) // LDAA ZP
{
- uint8 m = READ_ZP;
+ uint8_t m = READ_ZP;
OP_LDA_HANDLER(m, regs.a);
}
static void OpA6(void) // LDAA ZP, X
{
- uint8 m = READ_ZP_X;
+ uint8_t m = READ_ZP_X;
OP_LDA_HANDLER(m, regs.a);
}
static void OpB6(void) // LDAA ABS
{
- uint8 m = READ_ABS;
+ uint8_t m = READ_ABS;
OP_LDA_HANDLER(m, regs.a);
}
static void OpC6(void) // LDAB #
{
- uint8 m = READ_IMM;
+ uint8_t m = READ_IMM;
OP_LDA_HANDLER(m, regs.b);
}
static void OpD6(void) // LDAB ZP
{
- uint8 m = READ_ZP;
+ uint8_t m = READ_ZP;
OP_LDA_HANDLER(m, regs.b);
}
static void OpE6(void) // LDAB ZP, X
{
- uint8 m = READ_ZP_X;
+ uint8_t m = READ_ZP_X;
OP_LDA_HANDLER(m, regs.b);
}
static void OpF6(void) // LDAB ABS
{
- uint8 m = READ_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 |
+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
static void Op8A(void) // ORAA #
{
- uint8 m = READ_IMM;
+ uint8_t m = READ_IMM;
OP_ORA_HANDLER(m, regs.a);
}
static void Op9A(void) // ORAA ZP
{
- uint8 m = READ_ZP;
+ uint8_t m = READ_ZP;
OP_ORA_HANDLER(m, regs.a);
}
static void OpAA(void) // ORAA ZP, X
{
- uint8 m = READ_ZP_X;
+ uint8_t m = READ_ZP_X;
OP_ORA_HANDLER(m, regs.a);
}
static void OpBA(void) // ORAA ABS
{
- uint8 m = READ_ABS;
+ uint8_t m = READ_ABS;
OP_ORA_HANDLER(m, regs.a);
}
static void OpCA(void) // ORAB #
{
- uint8 m = READ_IMM;
+ uint8_t m = READ_IMM;
OP_ORA_HANDLER(m, regs.b);
}
static void OpDA(void) // ORAB ZP
{
- uint8 m = READ_ZP;
+ uint8_t m = READ_ZP;
OP_ORA_HANDLER(m, regs.b);
}
static void OpEA(void) // ORAB ZP, X
{
- uint8 m = READ_ZP_X;
+ uint8_t m = READ_ZP_X;
OP_ORA_HANDLER(m, regs.b);
}
static void OpFA(void) // ORAB ABS
{
- uint8 m = READ_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, *+ | |
+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
{
-// regs.WrMem(--regs.s, regs.a);
PUSH(regs.a);
}
static void Op37(void) // PSHB
{
-// regs.WrMem(--regs.s, regs.b);
PUSH(regs.b);
}
static void Op32(void) // PULA
{
-// regs.a = regs.RdMem(regs.s++);
regs.a = PULL;
}
static void Op33(void) // PULB
{
-// regs.b = regs.RdMem(regs.s++);
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|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Rotate Left |ROL | | |69 7 2|79 6 3| |Memory *1| TT6T|
+ |ROLA | | | | |49 2 1|Accum A *1| TT6T|
+ |ROLB | | | | |59 2 1|Accum B *1| TT6T|
*/
// ROL opcodes
-//#define OP_ROL_HANDLER(m) \
- uint8 newCarry = (m & 0x80) >> 7; \
- m = (m << 1) | (regs.cc & FLAG_C); \
- SET_ZN(m); \
- regs.cc = (regs.cc & ~FLAG_C) | newCarry; \
- regs.cc = (regs.cc & ~FLAG_V) | ((regs.cc & FLAG_N) >> 2) ^ ((regs.cc & FLAG_C) << 1)
#define OP_ROL_HANDLER(m) \
- uint8 newCarry = (m & 0x80) >> 7; \
+ uint8_t newCarry = (m & 0x80) >> 7; \
m = (m << 1) | flagC; \
SET_ZN(m); \
flagC = newCarry; \
static void Op69(void) // ROL ZP, X
{
- uint8 m;
+ uint8_t m;
READ_ZP_X_WB(m);
OP_ROL_HANDLER(m);
WRITE_BACK(m);
static void Op79(void) // ROL ABS
{
- uint8 m;
+ uint8_t m;
READ_ABS_WB(m);
OP_ROL_HANDLER(m);
WRITE_BACK(m);
}
/*
-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|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Rotate Right |ROR | | |66 7 2|76 6 3| |Memory *2| TT6T|
+ |RORA | | | | |46 2 1|Accum A *2| TT6T|
+ |RORB | | | | |56 2 1|Accum B *2| TT6T|
*/
// ROR opcodes
-//#define OP_ROR_HANDLER(m) \
- uint8 newCarry = m & 0x01; \
- m = (m >> 1) | ((regs.cc & FLAG_C) << 7); \
- SET_ZN(m); \
- regs.cc = (regs.cc & ~FLAG_C) | newCarry; \
- regs.cc = (regs.cc & ~FLAG_V) | ((regs.cc & FLAG_N) >> 2) ^ ((regs.cc & FLAG_C) << 1)
#define OP_ROR_HANDLER(m) \
- uint8 newCarry = m & 0x01; \
+ uint8_t newCarry = m & 0x01; \
m = (m >> 1) | (flagC << 7); \
SET_ZN(m); \
flagC = newCarry; \
static void Op66(void) // ROR ZP, X
{
- uint8 m;
+ uint8_t m;
READ_ZP_X_WB(m);
OP_ROR_HANDLER(m);
WRITE_BACK(m);
static void Op76(void) // ROR ABS
{
- uint8 m;
+ uint8_t m;
READ_ABS_WB(m);
OP_ROR_HANDLER(m);
WRITE_BACK(m);
}
/*
-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|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Arithmetic Shft Left|ASL | | |68 7 2|78 6 3| |Memory *3| TT6T|
+ |ASLA | | | | |48 2 1|Accum A *3| TT6T|
+ |ASLB | | | | |58 2 1|Accum B *3| TT6T|
*/
// ASL opcodes
-//#define OP_ASL_HANDLER(m) \
- uint8 newCarry = (m & 0x80) >> 7; \
- m <<= 1; \
- SET_ZN(m); \
- regs.cc = (regs.cc & ~FLAG_C) | newCarry; \
- regs.cc = (regs.cc & ~FLAG_V) | ((regs.cc & FLAG_N) >> 2) ^ ((regs.cc & FLAG_C) << 1)
#define OP_ASL_HANDLER(m) \
- uint8 newCarry = (m & 0x80) >> 7; \
+ uint8_t newCarry = (m & 0x80) >> 7; \
m <<= 1; \
SET_ZN(m); \
flagC = newCarry; \
static void Op68(void) // ASL ZP, X
{
- uint8 m;
+ uint8_t m;
READ_ZP_X_WB(m);
OP_ASL_HANDLER(m);
WRITE_BACK(m);
static void Op78(void) // ASL ABS
{
- uint8 m;
+ uint8_t m;
READ_ABS_WB(m);
OP_ASL_HANDLER(m);
WRITE_BACK(m);
}
/*
-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|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Arithmetic Shft Rght|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 newCarry = m & 0x01; \
- m = (m >> 1) | (m & 0x80); \
- SET_ZN(m); \
- regs.cc = (regs.cc & ~FLAG_C) | newCarry; \
- regs.cc = (regs.cc & ~FLAG_V) | ((regs.cc & FLAG_N) >> 2) ^ ((regs.cc & FLAG_C) << 1)
#define OP_ASR_HANDLER(m) \
- uint8 newCarry = m & 0x01; \
+ uint8_t newCarry = m & 0x01; \
m = (m >> 1) | (m & 0x80); \
SET_ZN(m); \
flagC = newCarry; \
static void Op67(void) // ASR ZP, X
{
- uint8 m;
+ uint8_t m;
READ_ZP_X_WB(m);
OP_ASR_HANDLER(m);
WRITE_BACK(m);
static void Op77(void) // ASR ABS
{
- uint8 m;
+ uint8_t m;
READ_ABS_WB(m);
OP_ASR_HANDLER(m);
WRITE_BACK(m);
}
/*
-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|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Logic Shift Right |LSR | | |64 7 2|74 6 3| |Memory *5| TT6T|
+ |LSRA | | | | |44 2 1|Accum A *5| TT6T|
+ |LSRB | | | | |54 2 1|Accum B *5| TT6T|
*/
// LSR opcodes
-//#define OP_LSR_HANDLER(m) \
- uint8 newCarry = m & 0x01; \
- m >>= 1; \
- SET_ZN(m); \
- regs.cc = (regs.cc & ~FLAG_C) | newCarry; \
- regs.cc = (regs.cc & ~FLAG_V) | ((regs.cc & FLAG_N) >> 2) ^ ((regs.cc & FLAG_C) << 1)
#define OP_LSR_HANDLER(m) \
- uint8 newCarry = m & 0x01; \
+ uint8_t newCarry = m & 0x01; \
m >>= 1; \
SET_ZN(m); \
flagC = newCarry; \
static void Op64(void) // LSR ZP, X
{
- uint8 m;
+ uint8_t m;
READ_ZP_X_WB(m);
OP_LSR_HANDLER(m);
WRITE_BACK(m);
static void Op74(void) // LSR ABS
{
- uint8 m;
+ uint8_t m;
READ_ABS_WB(m);
OP_LSR_HANDLER(m);
WRITE_BACK(m);
}
/*
-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 |
+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
static void OpB7(void) // STAA ABS
{
regs.WrMem(EA_ABS, regs.a);
- regs.pc += 2;
}
static void OpD7(void) // STAB ZP
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|
+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 Accumulatrs|SBA | | | | |10 2 1|A=A-B | TTTT|
*/
// SUB opcodes
-//#define OP_SUB_HANDLER(m, acc) \
- uint16 sum = (uint16)acc - (m); \
- regs.cc = (regs.cc & ~FLAG_C) | (sum >> 15); \
- SET_V(m, acc, sum); \
- acc = (uint8)sum; \
- SET_ZN(acc)
#define OP_SUB_HANDLER(m, acc) \
- uint16 sum = (uint16)acc - (m); \
+ uint16_t sum = (uint16_t)acc - (m); \
flagC = sum >> 15; \
SET_V(m, acc, sum); \
- acc = (uint8)sum; \
+ acc = (uint8_t)sum; \
SET_ZN(acc)
static void Op80(void) // SUBA #
{
- uint16 m = READ_IMM;
+ uint16_t m = READ_IMM;
OP_SUB_HANDLER(m, regs.a);
}
static void Op90(void) // SUBA ZP
{
- uint16 m = READ_ZP;
+ uint16_t m = READ_ZP;
OP_SUB_HANDLER(m, regs.a);
}
static void OpA0(void) // SUBA ZP, X
{
- uint16 m = READ_ZP_X;
+ uint16_t m = READ_ZP_X;
OP_SUB_HANDLER(m, regs.a);
}
static void OpB0(void) // SUBA ABS
{
- uint16 m = READ_ABS;
+ uint16_t m = READ_ABS;
OP_SUB_HANDLER(m, regs.a);
}
static void OpC0(void) // SUBB #
{
- uint16 m = READ_IMM;
+ uint16_t m = READ_IMM;
OP_SUB_HANDLER(m, regs.b);
}
static void OpD0(void) // SUBB ZP
{
- uint16 m = READ_ZP;
+ uint16_t m = READ_ZP;
OP_SUB_HANDLER(m, regs.b);
}
static void OpE0(void) // SUBB ZP, X
{
- uint16 m = READ_ZP_X;
+ uint16_t m = READ_ZP_X;
OP_SUB_HANDLER(m, regs.b);
}
static void OpF0(void) // SUBB ABS
{
- uint16 m = READ_ABS;
+ uint16_t m = READ_ABS;
OP_SUB_HANDLER(m, regs.b);
}
}
/*
-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|
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Subtract with Carry |SBCA |82 2 2|92 3 2|A2 5 2|B2 4 3| |A=A-M-C | TTTT|
+ |SBCB |C2 2 2|D2 3 2|E2 5 2|F2 4 3| |B=B-M-C | TTTT|
*/
// SBC opcodes
-//#define OP_SBC_HANDLER(m, acc) \
- uint16 sum = (uint16)acc - (m) - (uint16)(regs.cc & FLAG_C); \
- regs.cc = (regs.cc & ~FLAG_C) | (sum >> 15); \
- SET_V(m, acc, sum); \
- acc = (uint8)sum; \
- SET_ZN(acc)
#define OP_SBC_HANDLER(m, acc) \
- uint16 sum = (uint16)acc - (m) - (uint16)flagC; \
+ uint16_t sum = (uint16_t)acc - (m) - (uint16_t)flagC; \
flagC = sum >> 15; \
SET_V(m, acc, sum); \
- acc = (uint8)sum; \
+ acc = (uint8_t)sum; \
SET_ZN(acc)
static void Op82(void) // SBCA #
{
- uint16 m = READ_IMM;
+ uint16_t m = READ_IMM;
OP_SBC_HANDLER(m, regs.a);
}
static void Op92(void) // SBCA ZP
{
- uint16 m = READ_ZP;
+ uint16_t m = READ_ZP;
OP_SBC_HANDLER(m, regs.a);
}
static void OpA2(void) // SBCA ZP, X
{
- uint16 m = READ_ZP_X;
+ uint16_t m = READ_ZP_X;
OP_SBC_HANDLER(m, regs.a);
}
static void OpB2(void) // SBCA ABS
{
- uint16 m = READ_ABS;
+ uint16_t m = READ_ABS;
OP_SBC_HANDLER(m, regs.a);
}
static void OpC2(void) // SBCB #
{
- uint16 m = READ_IMM;
+ uint16_t m = READ_IMM;
OP_SBC_HANDLER(m, regs.b);
}
static void OpD2(void) // SBCB ZP
{
- uint16 m = READ_ZP;
+ uint16_t m = READ_ZP;
OP_SBC_HANDLER(m, regs.b);
}
static void OpE2(void) // SBCB ZP, X
{
- uint16 m = READ_ZP_X;
+ uint16_t m = READ_ZP_X;
OP_SBC_HANDLER(m, regs.b);
}
static void OpF2(void) // SBCB ABS
{
- uint16 m = READ_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 |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Transfer Accumulatrs|TAB | | | | |16 2 1|B=A | TTR |
+ |TBA | | | | |17 2 1|A=B | TTR |
*/
static void Op16(void) // TAB
}
/*
-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|
+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
static void Op6D(void) // TST ZP, X
{
- uint8 m;
+ uint8_t m;
READ_ZP_X_WB(m);
OP_TST_HANDLER(m);
WRITE_BACK(m);
static void Op7D(void) // TST ABS
{
- uint8 m;
+ uint8_t m;
READ_ABS_WB(m);
OP_TST_HANDLER(m);
WRITE_BACK(m);
}
/*
-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 |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Compare Index Regstr|CPX |8C 3 3|9C 4 2|AC 6 2|BC 5 3| |Formula 1 | 7T8 |
*/
// CPX opcodes
*/
#define OP_CPX_HANDLER(m) \
- uint32 result = regs.x - (m); \
+ uint32_t result = regs.x - (m); \
SET_ZNVC_CMP16(m, regs.x, result)
static void Op8C(void) // CPX #
{
- uint16 m = READ_IMM16;
+ uint16_t m = READ_IMM16;
OP_CPX_HANDLER(m);
}
static void Op9C(void) // CPX ZP
{
- uint16 m = READ_ZP16;
+ uint16_t m = READ_ZP16;
OP_CPX_HANDLER(m);
}
static void OpAC(void) // CPX ZP, X
{
- uint16 m = READ_ZP_X16;
+ uint16_t m = READ_ZP_X16;
OP_CPX_HANDLER(m);
}
static void OpBC(void) // CPX ABS
{
- uint16 m = READ_ABS16;
+ 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 | |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Decrement Index Regr|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
}
/*
-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 |
+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
}
/*
-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 |
+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
static void OpDF(void) // STX ZP
{
- uint16 m = EA_ZP;
+ uint16_t m = EA_ZP;
OP_ST_HANDLER(m, regs.x);
}
static void OpEF(void) // STX ZP, X
{
- uint16 m = EA_ZP_X;
+ uint16_t m = EA_ZP_X;
OP_ST_HANDLER(m, regs.x);
}
static void OpFF(void) // STX ABS
{
- uint16 m = EA_ABS;
- regs.pc += 2;
+ uint16_t m = EA_ABS;
OP_ST_HANDLER(m, regs.x);
}
static void Op9F(void) // STS ZP
{
- uint16 m = EA_ZP;
+ uint16_t m = EA_ZP;
OP_ST_HANDLER(m, regs.s);
}
static void OpAF(void) // STS ZP, X
{
- uint16 m = EA_ZP_X;
+ uint16_t m = EA_ZP_X;
OP_ST_HANDLER(m, regs.s);
}
static void OpBF(void) // STS ABS
{
- uint16 m = EA_ABS;
- regs.pc += 2;
+ uint16_t m = EA_ABS;
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 | |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+Indx Reg > Stack Ptr|TXS | | | | |35 4 1|SP=X-1 | |
+Stack Ptr > Indx Reg|TSX | | | | |30 4 1|X=SP+1 | |
*/
static void Op35(void) // TXS
}
/*
-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 | |
+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 / Equal to 0|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 / Equal than 0 |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 m = (int16)(int8)READ_IMM;
+ int16_t m = (int16_t)(int8_t)READ_IMM;
regs.pc += m;
}
static void Op24(void) // BCC
{
- int16 m = (int16)(int8)READ_IMM;
+// 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;
-// if (!(regs.cc & FLAG_C))
+#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 m = (int16)(int8)READ_IMM;
+ int16_t m = (int16_t)(int8_t)READ_IMM;
-// if (regs.cc & FLAG_C)
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += m * (flagC);
+#else
if (flagC)
regs.pc += m;
+#endif
}
static void Op27(void) // BEQ
{
- int16 m = (int16)(int8)READ_IMM;
+ int16_t m = (int16_t)(int8_t)READ_IMM;
-// if (regs.cc & FLAG_Z)
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += m * (flagZ);
+#else
if (flagZ)
regs.pc += m;
+#endif
}
static void Op2C(void) // BGE
{
- int16 m = (int16)(int8)READ_IMM;
+ int16_t m = (int16_t)(int8_t)READ_IMM;
-// if (!(((regs.cc & FLAG_N) >> 2) ^ (regs.cc & FLAG_V)))
+#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 m = (int16)(int8)READ_IMM;
+ int16_t m = (int16_t)(int8_t)READ_IMM;
-// if (!(((regs.cc & FLAG_Z) >> 1) | (((regs.cc & FLAG_N) >> 2) ^ (regs.cc & FLAG_V))))
+#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 m = (int16)(int8)READ_IMM;
+ int16_t m = (int16_t)(int8_t)READ_IMM;
-// if (!(((regs.cc & FLAG_Z) >> 2) | (regs.cc & FLAG_C)))
+#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 m = (int16)(int8)READ_IMM;
+ int16_t m = (int16_t)(int8_t)READ_IMM;
-// if (((regs.cc & FLAG_Z) >> 1) | (((regs.cc & FLAG_N) >> 2) ^ (regs.cc & FLAG_V)))
+#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 m = (int16)(int8)READ_IMM;
+ int16_t m = (int16_t)(int8_t)READ_IMM;
-// if (((regs.cc & FLAG_Z) >> 2) | (regs.cc & FLAG_C))
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += m * (flagZ | flagC);
+#else
if (flagZ | flagC)
regs.pc += m;
+#endif
}
static void Op2D(void) // BLT
{
- int16 m = (int16)(int8)READ_IMM;
+ int16_t m = (int16_t)(int8_t)READ_IMM;
-// if (((regs.cc & FLAG_N) >> 2) ^ (regs.cc & FLAG_V))
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += m * (flagN ^ flagV);
+#else
if (flagN ^ flagV)
regs.pc += m;
+#endif
}
static void Op2B(void) // BMI
{
- int16 m = (int16)(int8)READ_IMM;
+ int16_t m = (int16_t)(int8_t)READ_IMM;
-// if (regs.cc & FLAG_N)
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += m * (flagN);
+#else
if (flagN)
regs.pc += m;
+#endif
}
static void Op26(void) // BNE
{
- int16 m = (int16)(int8)READ_IMM;
+ int16_t m = (int16_t)(int8_t)READ_IMM;
-// if (!(regs.cc & FLAG_Z))
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += m * (flagZ ^ 0x01);
+#else
if (!flagZ)
regs.pc += m;
+#endif
}
static void Op28(void) // BVC
{
- int16 m = (int16)(int8)READ_IMM;
+ int16_t m = (int16_t)(int8_t)READ_IMM;
-// if (!(regs.cc & FLAG_V))
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += m * (flagV ^ 0x01);
+#else
if (!flagV)
regs.pc += m;
+#endif
}
static void Op29(void) // BVS
{
- int16 m = (int16)(int8)READ_IMM;
+ int16_t m = (int16_t)(int8_t)READ_IMM;
-// if (regs.cc & FLAG_V)
+#ifdef TEST_DONT_BRANCH_OPTIMIZATION
+ regs.pc += m * (flagV);
+#else
if (flagV)
regs.pc += m;
+#endif
}
static void Op2A(void) // BPL
{
- int16 m = (int16)(int8)READ_IMM;
+ int16_t m = (int16_t)(int8_t)READ_IMM;
-// if (!(regs.cc & FLAG_N))
+#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| | | |
+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 m = (int16)(int8)READ_IMM;
+ 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;
+ uint16_t m = EA_ZP_X;
+ regs.pc = m;
}
static void Op7E(void) // JMP ABS
static void OpAD(void) // JSR ZP, X
{
- uint16 m = EA_ZP_X;
+ uint16_t m = EA_ZP_X;
PUSH16(regs.pc);
regs.pc = m;
}
static void OpBD(void) // JSR ABS
{
- uint16 m = EA_ABS;
- regs.pc += 2;
+ uint16_t m = EA_ABS;
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 |
+Operation |Mnem.|Immed.|Direct|Index |Extend|Inher.|Operation |CC Reg|
+ | |OP ~ #|OP ~ #|OP ~ #|OP ~ #|OP ~ #| |HINZVC|
+No Operation |NOP | | | | |01 2 1| | |
+Return from Interrpt|RTI | | | | |3B A 1| |AAAAAA|
+Return from Subrtine|RTS | | | | |39 5 1| | |
+Software Interrupt |SWI | | | | |3F C 1| | S |
+Wait For Interrupt |WAI | | | | |3E 9 1| | B |
*/
static void Op01(void) // NOP
PUSH(regs.a);
PUSH(regs.cc);
regs.pc = RdMemW(0xFFFA); // And do it!
-// regs.cc |= FLAG_I; // Also, set IRQ inhibit
flagI = 1; // Also, set IRQ inhibit
}
}
/*
-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 | |
+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
{
-// regs.cc &= ~FLAG_C;
flagC = 0;
}
static void Op0E(void) // CLI
{
-// regs.cc &= ~FLAG_I;
flagI = 0;
}
static void Op0A(void) // CLV
{
-// regs.cc &= ~FLAG_V;
flagV = 0;
}
static void Op0D(void) // SEC
{
-// regs.cc |= FLAG_C;
flagC = 1;
}
static void Op0F(void) // SEI
{
-// regs.cc |= FLAG_I;
flagI = 1;
}
static void Op0B(void) // SEV
{
-// regs.cc |= FLAG_V;
flagV = 1;
}
static void Op07(void) // TPA
{
-// regs.a = regs.cc;
regs.a = PACK_FLAGS;
}
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!
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 size)
+static void myMemcpy(void * dst, void * src, uint32_t size)
{
- uint8 * d = (uint8 *)dst, * s = (uint8 *)src;
+ uint8_t * d = (uint8_t *)dst, * s = (uint8_t *)src;
- for(uint32 i=0; i<size; i++)
+ for(uint32_t i=0; i<size; i++)
d[i] = s[i];
}
-#ifdef __DEBUG__
-//int instCount[256];
-static bool logGo = false;
-#endif
//
// Function to execute 6808 for "cycles" cycles
//
-void Execute6808(V6808REGS * context, uint32 cycles)
+void Execute6808(V6808REGS * context, uint32_t cycles)
{
-#warning V6808_STATE_WAI is not properly handled yet!
-
+#warning "V6808_STATE_WAI is not properly handled yet! !!! FIX !!!"
+#warning "Need to convert from destructive clock to non-destructive. !!! FIX !!!"
myMemcpy(®s, context, sizeof(V6808REGS));
- UNPACK_FLAGS; // Explode flags register into individual uint8s
+ UNPACK_FLAGS; // Explode flags register into individual uint8_ts
// Execute here...
while (regs.clock < cycles)
{
-#ifdef __DEBUG__
-if (logGo)
- Decode6808(regs.pc);
-#endif
- uint8 opcode = regs.RdMem(regs.pc++);
-
-#ifdef __DEBUG__
-//if (!(regs.cpuFlags & V6808_STATE_ILLEGAL_INST))
-//instCount[opcode]++;
-#endif
-
- exec_op[opcode](); // Execute that opcode...
+ uint8_t opcode = regs.RdMem(regs.pc++);
+ exec_op[opcode](); // Execute that opcode...
regs.clock += CPUCycles[opcode];
-#ifdef __DEBUG__
-if (logGo)
-// WriteLog(" [PC=%04X, S=%04X, X=%04X, A=%02X, B=%02X, CC=%s%s%s%s%s%s%s%s]\n", regs.pc, regs.s, regs.x, regs.a, regs.b, (regs.cc & FLAG_E ? "E" : " "), (regs.cc & FLAG_F ? "F" : " "), (regs.cc & FLAG_H ? "H" : " "), (regs.cc & FLAG_I ? "I" : " "), (regs.cc & FLAG_N ? "N" : " "), (regs.cc & FLAG_Z ? "Z" : " "), (regs.cc & FLAG_V ? "V" : " "), (regs.cc & FLAG_C ? "C" : " "));
- WriteLog(" [PC=%04X, S=%04X, X=%04X, A=%02X, B=%02X, CC=%s%s%s%s%s%s%s%s]\n", regs.pc, regs.s, regs.x, regs.a, regs.b, (regs.cc & FLAG_E ? "E" : " "), (regs.cc & FLAG_F ? "F" : " "), (flagH ? "H" : " "), (flagI ? "I" : " "), (flagN ? "N" : " "), (flagZ ? "Z" : " "), (flagV ? "V" : " "), (flagC ? "C" : " "));
-#endif
- if (regs.cpuFlags & V6808_ASSERT_LINE_RESET)
+ if (regs.cpuFlags & V6808_LINE_RESET)
{
-#ifdef __DEBUG__
-WriteLog("*** RESET LINE ASSERTED ***\n");
-#endif
-// regs.cc |= FLAG_I; // Set I
- flagI = 1; // Set I
- regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector
+ flagI = 1; // Set I
+ regs.pc = RdMemW(0xFFFE); // And load PC with the RESET vector
- context->cpuFlags &= ~V6808_ASSERT_LINE_RESET;
- regs.cpuFlags &= ~V6808_ASSERT_LINE_RESET;
+ context->cpuFlags &= ~V6808_LINE_RESET;
+ regs.cpuFlags &= ~V6808_LINE_RESET;
}
- else if (regs.cpuFlags & V6808_ASSERT_LINE_NMI)
+ else if (regs.cpuFlags & V6808_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...
+ regs.cc = PACK_FLAGS; // Mash flags back into the CC register
+ PUSH16(regs.pc); // Save all regs...
PUSH16(regs.x);
PUSH(regs.b);
PUSH(regs.a);
PUSH(regs.cc);
- regs.pc = RdMemW(0xFFFC); // And do it!
+ regs.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)...
+ context->cpuFlags &= ~V6808_LINE_NMI;// Reset the asserted line (NMI)...
+ regs.cpuFlags &= ~V6808_LINE_NMI; // Reset the asserted line (NMI)...
}
- else if (regs.cpuFlags & V6808_ASSERT_LINE_IRQ)
+ else if (regs.cpuFlags & V6808_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)?
+ 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...
+ regs.cc = PACK_FLAGS; // Mash flags back into the CC register
+ PUSH16(regs.pc); // Save all regs...
PUSH16(regs.x);
PUSH(regs.b);
PUSH(regs.a);
PUSH(regs.cc);
- regs.pc = RdMemW(0xFFF8); // And do it!
+ regs.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)...
+ context->cpuFlags &= ~V6808_LINE_IRQ; // Reset the asserted line (IRQ)...
+ regs.cpuFlags &= ~V6808_LINE_IRQ; // Reset the asserted line (IRQ)...
}
}
}
- regs.cc = PACK_FLAGS; // Mash flags back into the CC register
+ regs.cc = PACK_FLAGS; // Mash flags back into the CC register
myMemcpy(context, ®s, sizeof(V6808REGS));
}
//
// Get the clock of the currently executing CPU
//
-uint32 GetCurrentV6808Clock(void)
+uint64_t GetCurrentV6808Clock(void)
{
return regs.clock;
}