// We have a start... ;-)
//
-#define __DEBUG__
+//#define __DEBUG__
#include "v6809.h"
#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
regs.pc += 2;
return w;
}
-//
-// Fetch word function
-//
-/*uint16 FetchW(void)
-{
- return (uint16)(regs.RdMem(regs.pc++) << 8) | regs.RdMem(regs.pc++);
-}*/
//
// Read word from memory function
addr = RdMemW(woff);
break;
case 5:
-// woff = DecodeReg(reg) + SignedB(regs.b);
woff = DecodeReg(reg) + (int16)(int8)regs.b;
addr = RdMemW(woff);
break;
case 6:
-// woff = DecodeReg(reg) + SignedB(regs.a);
woff = DecodeReg(reg) + (int16)(int8)regs.a;
addr = RdMemW(woff);
break;
case 8:
-// woff = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++));
woff = DecodeReg(reg) + (int16)(int8)regs.RdMem(regs.pc++);
addr = RdMemW(woff);
break;
case 9:
-// woff = DecodeReg(reg) + SignedW(FetchW());
woff = DecodeReg(reg) + FetchW();
addr = RdMemW(woff);
break;
case 11:
-// woff = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b);
woff = DecodeReg(reg) + ((regs.a << 8) | regs.b);
addr = RdMemW(woff);
break;
case 12:
-// woff = regs.pc + SignedB(regs.RdMem(regs.pc++));
woff = regs.pc + (int16)(int8)regs.RdMem(regs.pc++);
addr = RdMemW(woff);
break;
case 13:
-// woff = regs.pc + SignedW(FetchW());
woff = regs.pc + FetchW();
addr = RdMemW(woff);
break;
}
addr = DecodeReg(reg); break; }
case 4: { addr = DecodeReg(reg); break; }
-// case 5: { addr = DecodeReg(reg) + SignedB(regs.b); break; }
case 5: { addr = DecodeReg(reg) + (int16)(int8)regs.b; break; }
-// case 6: { addr = DecodeReg(reg) + SignedB(regs.a); break; }
case 6: { addr = DecodeReg(reg) + (int16)(int8)regs.a; break; }
-// case 8: { addr = DecodeReg(reg) + SignedB(regs.RdMem(regs.pc++)); break; }
case 8: { addr = DecodeReg(reg) + (int16)(int8)regs.RdMem(regs.pc++); break; }
-// case 9: { addr = DecodeReg(reg) + SignedW(FetchW()); break; }
case 9: { addr = DecodeReg(reg) + FetchW(); break; }
-// case 11: { addr = DecodeReg(reg) + SignedW((regs.a << 8) | regs.b); break; }
case 11: { addr = DecodeReg(reg) + ((regs.a << 8) | regs.b); break; }
-// case 12: { addr = regs.pc + SignedB(regs.RdMem(regs.pc++)); break; }
case 12: { addr = regs.pc + (int16)(int8)regs.RdMem(regs.pc++); break; }
-// case 13: { addr = regs.pc + SignedW(FetchW()); break; }
case 13: { addr = regs.pc + FetchW(); break; }
}
}
{
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
+ (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 Op0E(void) // JMP DP
regs.a += 0x60; regs.cc |= 0x01; // Then adjust & set carry
}
regs.cc &= 0xF1; // CL NZV
- if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
+ if (regs.a == 0) regs.cc |= 0x04; // Adjust Zero flag
if (regs.a&0x80) regs.cc |= 0x08; // Adjust Negative flag
regs.clock += 2;
}
{
}
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&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
regs.clock += 2;
}
-static void Op49(void) // ROLA
+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.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
static void Op5C(void) // INCB
{
regs.b++;
- (regs.b == 0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // Adjust oVerflow flag
+ (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;
regs.clock += 2;
}
static void Op60(void) // NEG IDX
- {
+ {
addr = DecodeIDX(regs.RdMem(regs.pc++));
tmp = regs.RdMem(addr); uint8 res = 256 - tmp;
regs.WrMem(addr, res);
regs.clock += 6;
}
static void Op6C(void) // INC IDX
- {
+ {
addr = DecodeIDX(regs.RdMem(regs.pc++));
tmp = regs.RdMem(addr) + 1;
regs.WrMem(addr, tmp);
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
+ (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.clock += 6;
}
static void Op70(void) // NEG ABS
- {
+ {
addr = FetchW();
tmp = regs.RdMem(addr); uint8 res = 256 - tmp;
regs.WrMem(addr, res);
regs.clock += 7;
}
static void Op7C(void) // INC ABS
- {
+ {
uint8 tmp; uint16 addr;
addr = FetchW();
tmp = regs.RdMem(addr) + 1;
{
uint8 tmp = regs.RdMem(FetchW());
- (tmp == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
- (tmp&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
+ (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;
}
regs.clock += 7;
}
static void Op80(void) // SUBA #
-{
- uint8 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
+{
+ uint8 tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
regs.a -= tmp;
(as < tmp ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
}
static void Op82(void) // SBCA #
{
- tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
+ tmp = regs.RdMem(regs.pc++); uint8 as = regs.a;
regs.a = regs.a - tmp - (regs.cc&0x01);
(as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
- ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ ((regs.a^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 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^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 += 3;
}
static void Op90(void) // SUBA DP
- {
- tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a;
+ {
+ tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a;
regs.a -= tmp;
(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
}
static void Op92(void) // SBCA DP
{
- tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a;
+ tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 as = regs.a;
regs.a = regs.a - tmp - (regs.cc&0x01);
(as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry
((regs.a^tmp^addr)&0x10 ? regs.cc |= 0x20 : regs.cc &= 0xDF); // Set Half carry
- ((regs.a^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
+ ((regs.a^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 Op9B(void) // ADDA DP
-{
+{
tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
addr = (uint16)regs.a + (uint16)tmp;
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.a^tmp^addr)&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^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;
}
static void OpA0(void) // SUBA IDX
- {
- tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
+ {
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
regs.a -= tmp;
(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
}
static void OpA2(void) // SBCA IDX
{
- tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 as = regs.a;
regs.a = regs.a - tmp - (regs.cc&0x01);
(as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.a^tmp^addr)&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^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 OpAB(void) // ADDA IDX
-{
+{
tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
addr = (uint16)regs.a + (uint16)tmp;
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.a^tmp^addr)&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^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;
}
static void OpB0(void) // SUBA ABS
- {
- tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
+ {
+ tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
regs.a -= tmp;
(regs.a == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
(regs.a&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
}
static void OpB2(void) // SBCA ABS
{
- tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
+ tmp = regs.RdMem(FetchW()); uint8 as = regs.a;
regs.a = regs.a - tmp - (regs.cc&0x01);
(as < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
((as^tmp^regs.a^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
addr = (uint16)regs.a + (uint16)tmp + (uint16)(regs.cc&0x01);
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.a^tmp^addr)&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^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;
}
static void OpBB(void) // ADDA ABS
-{
+{
tmp = regs.RdMem(FetchW());
addr = (uint16)regs.a + (uint16)tmp;
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
{
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.pc = addr; // Go to absolute address (Not indir)
regs.clock += 8;
}
}
static void OpC0(void) // SUBB #
- {
- tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
+ {
+ tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
regs.b -= tmp;
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
}
static void OpC2(void) // SBCB #
{
- tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
+ tmp = regs.RdMem(regs.pc++); uint8 bs = regs.b;
regs.b = regs.b - tmp - (regs.cc&0x01);
(bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.b^tmp^addr)&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^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 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^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 += 3;
}
static void OpD0(void) // SUBB DP
-{
- tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b;
+{
+ tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b;
regs.b -= tmp;
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
}
static void OpD2(void) // SBCB DP
{
- tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b;
+ tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++)); uint8 bs = regs.b;
regs.b = regs.b - tmp - (regs.cc&0x01);
(bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.b^tmp^addr)&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^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 OpDB(void) // ADDB DP
-{
+{
tmp = regs.RdMem((regs.dp<<8)|regs.RdMem(regs.pc++));
addr = (uint16)regs.b + (uint16)tmp;
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.b^tmp^addr)&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^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 += 5;
}
static void OpE0(void) // SUBB IDX
-{
- tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
+{
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
regs.b -= tmp;
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
}
static void OpE2(void) // SBCB IDX
{
- tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
+ tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++))); uint8 bs = regs.b;
regs.b = regs.b - tmp - (regs.cc&0x01);
(bs < (tmp+(regs.cc&0x01)) ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Adjust Carry flag
((bs^tmp^regs.b^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflow
addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.b^tmp^addr)&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^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 OpEB(void) // ADDB IDX
-{
+{
tmp = regs.RdMem(DecodeIDX(regs.RdMem(regs.pc++)));
addr = (uint16)regs.b + (uint16)tmp;
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.b^tmp^addr)&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^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 += 5;
}
static void OpF0(void) // SUBB ABS
- {
- tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
+ {
+ tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
regs.b -= tmp;
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
}
static void OpF2(void) // SBCB ABS
{
- tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
+ tmp = regs.RdMem(FetchW()); uint8 bs = regs.b;
regs.b = regs.b - tmp - (regs.cc&0x01);
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Adjust Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Adjust Negative flag
addr = (uint16)regs.b + (uint16)tmp + (uint16)(regs.cc&0x01);
(addr > 0x00FF ? regs.cc |= 0x01 : regs.cc &= 0xFE); // Set Carry flag
((regs.b^tmp^addr)&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^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.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)regs.b + (uint16)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^tmp^addr^(regs.cc<<7))&0x80 ? regs.cc |= 0x02 : regs.cc &= 0xFD); // oVerflo
regs.b = addr & 0xFF; // Set accumulator
(regs.b == 0 ? regs.cc |= 0x04 : regs.cc &= 0xFB); // Set Zero flag
(regs.b&0x80 ? regs.cc |= 0x08 : regs.cc &= 0xF7); // Set Negative flag
regs.cc &= 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;
+ regs.clock += 6;
}
static void Op10DF(void) // STS DP
{
//
// Function to execute 6809 instructions
//
+//#define DEBUG_ILLEGAL
+#ifdef DEBUG_ILLEGAL
+#include "log.h"
+#include "dis6809.h"
+uint8 btPtr = 0;
+uint8 backTrace[256];
+V6809REGS btRegs[256];
+bool tripped = false;
+#endif
void Execute6809(V6809REGS * context, uint32 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!
+ return;
+
myMemcpy(®s, context, sizeof(V6809REGS));
// Execute here...
- while (regs.clock < cycles)
+
+ // 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 endCycles = regs.clock + (uint64)(cycles - regs.clockOverrun);
+
+ while (regs.clock < endCycles)
+ {
+#ifdef DEBUG_ILLEGAL
+if (!tripped)
+{
+ backTrace[btPtr] = regs.RdMem(regs.pc);
+ btRegs[btPtr] = regs;
+ btPtr = (btPtr + 1) & 0xFF;
+
+ if (regs.cpuFlags & V6809_STATE_ILLEGAL_INST)
{
+ WriteLog("V6809: Executed illegal instruction!!!!\n\nBacktrace:\n\n");
+ regs.cpuFlags &= ~V6809_STATE_ILLEGAL_INST;
+
+ for(uint16 i=btPtr; i<btPtr+256; i++)
+ {
+ Decode6809(btRegs[i & 0xFF].pc);
+// Note that these values are *before* execution, so stale...
+ WriteLog("\n\tA=%02X B=%02X CC=%02X DP=%02X X=%04X Y=%04X S=%04X U=%04X PC=%04X\n",
+ btRegs[i & 0xFF].a, btRegs[i & 0xFF].b, btRegs[i & 0xFF].cc, btRegs[i & 0xFF].dp, btRegs[i & 0xFF].x, btRegs[i & 0xFF].y, btRegs[i & 0xFF].s, btRegs[i & 0xFF].u, btRegs[i & 0xFF].pc);//*/
+ }
+
+ tripped = true;
+ }
+}
+#endif
#ifdef __DEBUG__
//Decode6809(regs.pc);
static bool disasm = false;
regs.cc |= (FLAG_I | FLAG_F); // 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)...
- regs.cpuFlags &= ~V6809_ASSERT_LINE_NMI; // Reset the asserted line (NMI)...
+// context->cpuFlags &= ~V6809_ASSERT_LINE_NMI;// Reset the asserted line (NMI)...
+// regs.cpuFlags &= ~V6809_ASSERT_LINE_NMI; // Reset the asserted line (NMI)...
}
else if (flags & V6809_ASSERT_LINE_FIRQ) // *** FIRQ handler ***
{
regs.cc |= (FLAG_I | FLAG_F); // 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)...
- regs.cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
+// context->cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
+// regs.cpuFlags &= ~V6809_ASSERT_LINE_FIRQ; // Reset the asserted line (FIRQ)...
}
}
else if (flags & V6809_ASSERT_LINE_IRQ) // *** IRQ handler ***
regs.cc |= FLAG_I; // 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;
- context->cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
- regs.cpuFlags &= ~V6809_ASSERT_LINE_IRQ; // Reset the asserted line (IRQ)...
+// Apparently, not done 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__
#endif
}
+ // Keep track of how much we overran so we can adjust on the next run...
+ regs.clockOverrun = (uint32)(regs.clock - endCycles);
+
myMemcpy(context, ®s, sizeof(V6809REGS));
}
//
// Get the clock of the currently executing CPU
//
-uint32 GetCurrentV6809Clock(void)
+uint64 GetCurrentV6809Clock(void)
{
return regs.clock;
}
+
+//
+// Get the PC of the currently executing CPU
+//
+uint16 GetCurrentV6809PC(void)
+{
+ return regs.pc;
+}
+
+// Set a line of the currently executing CPU
+void SetLine(uint32 line)
+{
+ regs.cpuFlags |= line;
+}
+
+// Clear a line of the currently executing CPU
+void ClearLine(uint32 line)
+{
+ regs.cpuFlags &= ~line;
+}