mirror of
https://github.com/bradgrantham/apple2e.git
synced 2025-01-03 16:30:07 +00:00
Make instruction timing a lot more correct
Fix up clock timing on absolute-indexed, indirect-indexed, and branch instructions Emitted clock ticks now match up with emulated and video recorded beep sound (code to save off and postprocess ticks not checked in)
This commit is contained in:
parent
873aeb596f
commit
4085189d9f
128
apple2e.cpp
128
apple2e.cpp
@ -41,7 +41,7 @@ struct system_clock
|
|||||||
unsigned long long value = 0;
|
unsigned long long value = 0;
|
||||||
operator unsigned long long() const { return value; }
|
operator unsigned long long() const { return value; }
|
||||||
unsigned long long operator+=(unsigned long long i) { return value += i; }
|
unsigned long long operator+=(unsigned long long i) { return value += i; }
|
||||||
unsigned long long operator++() { return value ++; }
|
unsigned long long operator++(int) { unsigned long long v = value; value ++; return v; }
|
||||||
} clk;
|
} clk;
|
||||||
|
|
||||||
struct SoftSwitch
|
struct SoftSwitch
|
||||||
@ -349,6 +349,7 @@ struct MAINboard : board_base
|
|||||||
}
|
}
|
||||||
if(addr == 0xC030) {
|
if(addr == 0xC030) {
|
||||||
if(debug & DEBUG_RW) printf("read SPKR, force 0x00\n");
|
if(debug & DEBUG_RW) printf("read SPKR, force 0x00\n");
|
||||||
|
// printf("%llu\n", clk.value); <-- clock is more or less correct at this moment
|
||||||
// click
|
// click
|
||||||
data = 0x00;
|
data = 0x00;
|
||||||
return true;
|
return true;
|
||||||
@ -819,32 +820,93 @@ struct CPU6502
|
|||||||
|
|
||||||
case 0x10: { // BPL
|
case 0x10: { // BPL
|
||||||
int rel = (read_pc_inc(bus) + 128) % 256 - 128;
|
int rel = (read_pc_inc(bus) + 128) % 256 - 128;
|
||||||
if(!isset(N))
|
if(!isset(N)) {
|
||||||
|
clk++;
|
||||||
|
if((pc + rel) / 256 != pc / 256)
|
||||||
|
clk++;
|
||||||
pc += rel;
|
pc += rel;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x50: { // BVC
|
case 0x50: { // BVC
|
||||||
int rel = (read_pc_inc(bus) + 128) % 256 - 128;
|
int rel = (read_pc_inc(bus) + 128) % 256 - 128;
|
||||||
if(!isset(V))
|
if(!isset(V)) {
|
||||||
|
clk++;
|
||||||
|
if((pc + rel) / 256 != pc / 256)
|
||||||
|
clk++;
|
||||||
pc += rel;
|
pc += rel;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x70: { // BVS
|
case 0x70: { // BVS
|
||||||
int rel = (read_pc_inc(bus) + 128) % 256 - 128;
|
int rel = (read_pc_inc(bus) + 128) % 256 - 128;
|
||||||
if(isset(V))
|
if(isset(V)) {
|
||||||
|
clk++;
|
||||||
|
if((pc + rel) / 256 != pc / 256)
|
||||||
|
clk++;
|
||||||
pc += rel;
|
pc += rel;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x30: { // BMI
|
case 0x30: { // BMI
|
||||||
int rel = (read_pc_inc(bus) + 128) % 256 - 128;
|
int rel = (read_pc_inc(bus) + 128) % 256 - 128;
|
||||||
if(isset(N))
|
if(isset(N)) {
|
||||||
|
clk++;
|
||||||
|
if((pc + rel) / 256 != pc / 256)
|
||||||
|
clk++;
|
||||||
pc += rel;
|
pc += rel;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 0x90: { // BCC
|
||||||
|
int rel = (read_pc_inc(bus) + 128) % 256 - 128;
|
||||||
|
if(!isset(C)) {
|
||||||
|
clk++;
|
||||||
|
if((pc + rel) / 256 != pc / 256)
|
||||||
|
clk++;
|
||||||
|
pc += rel;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0xB0: { // BCS
|
||||||
|
int rel = (read_pc_inc(bus) + 128) % 256 - 128;
|
||||||
|
if(isset(C)) {
|
||||||
|
clk++;
|
||||||
|
if((pc + rel) / 256 != pc / 256)
|
||||||
|
clk++;
|
||||||
|
pc += rel;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0xD0: { // BNE
|
||||||
|
int rel = (read_pc_inc(bus) + 128) % 256 - 128;
|
||||||
|
if(!isset(Z)) {
|
||||||
|
clk++;
|
||||||
|
if((pc + rel) / 256 != pc / 256)
|
||||||
|
clk++;
|
||||||
|
pc += rel;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0xF0: { // BEQ
|
||||||
|
int rel = (read_pc_inc(bus) + 128) % 256 - 128;
|
||||||
|
if(isset(Z)) {
|
||||||
|
clk++;
|
||||||
|
if((pc + rel) / 256 != pc / 256)
|
||||||
|
clk++;
|
||||||
|
pc += rel;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
case 0xA1: { // LDA (ind, X)
|
case 0xA1: { // LDA (ind, X)
|
||||||
unsigned char zpg = (read_pc_inc(bus) + x) & 0xFF;
|
unsigned char zpg = (read_pc_inc(bus) + x) & 0xFF;
|
||||||
int addr = bus.read(zpg) + bus.read((zpg + 1) & 0xFF) * 256;
|
int addr = bus.read(zpg) + bus.read((zpg + 1) & 0xFF) * 256;
|
||||||
@ -862,6 +924,8 @@ struct CPU6502
|
|||||||
case 0xB1: { // LDA ind, Y
|
case 0xB1: { // LDA ind, Y
|
||||||
unsigned char zpg = read_pc_inc(bus);
|
unsigned char zpg = read_pc_inc(bus);
|
||||||
int addr = bus.read(zpg) + bus.read((zpg + 1) & 0xFF) * 256 + y;
|
int addr = bus.read(zpg) + bus.read((zpg + 1) & 0xFF) * 256 + y;
|
||||||
|
if((addr - y) / 256 != addr / 256)
|
||||||
|
clk++;
|
||||||
set_flags(N | Z, a = bus.read(addr));
|
set_flags(N | Z, a = bus.read(addr));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -875,6 +939,8 @@ struct CPU6502
|
|||||||
case 0xDD: { // CMP abs, X
|
case 0xDD: { // CMP abs, X
|
||||||
int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256;
|
int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256;
|
||||||
m = bus.read(addr + x);
|
m = bus.read(addr + x);
|
||||||
|
if((addr + x) / 256 != addr / 256)
|
||||||
|
clk++;
|
||||||
flag_change(C, m <= a);
|
flag_change(C, m <= a);
|
||||||
set_flags(N | Z, m = a - m);
|
set_flags(N | Z, m = a - m);
|
||||||
break;
|
break;
|
||||||
@ -883,6 +949,8 @@ struct CPU6502
|
|||||||
case 0xD9: { // CMP abs, Y
|
case 0xD9: { // CMP abs, Y
|
||||||
int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256;
|
int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256;
|
||||||
m = bus.read(addr + y);
|
m = bus.read(addr + y);
|
||||||
|
if((addr + y) / 256 != addr / 256)
|
||||||
|
clk++;
|
||||||
flag_change(C, m <= a);
|
flag_change(C, m <= a);
|
||||||
set_flags(N | Z, m = a - m);
|
set_flags(N | Z, m = a - m);
|
||||||
break;
|
break;
|
||||||
@ -891,12 +959,16 @@ struct CPU6502
|
|||||||
case 0xB9: { // LDA abs, Y
|
case 0xB9: { // LDA abs, Y
|
||||||
int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256;
|
int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256;
|
||||||
set_flags(N | Z, a = bus.read(addr + y));
|
set_flags(N | Z, a = bus.read(addr + y));
|
||||||
|
if((addr + y) / 256 != addr / 256)
|
||||||
|
clk++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0xBD: { // LDA abs, X
|
case 0xBD: { // LDA abs, X
|
||||||
int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256;
|
int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256;
|
||||||
set_flags(N | Z, a = bus.read(addr + x));
|
set_flags(N | Z, a = bus.read(addr + x));
|
||||||
|
if((addr + x) / 256 != addr / 256)
|
||||||
|
clk++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -923,6 +995,8 @@ struct CPU6502
|
|||||||
case 0xF1: { // SBC ind, Y
|
case 0xF1: { // SBC ind, Y
|
||||||
unsigned char zpg = read_pc_inc(bus);
|
unsigned char zpg = read_pc_inc(bus);
|
||||||
int addr = bus.read(zpg) + bus.read((zpg + 1) & 0xff) * 256 + y;
|
int addr = bus.read(zpg) + bus.read((zpg + 1) & 0xff) * 256 + y;
|
||||||
|
if((addr - y) / 256 != addr / 256)
|
||||||
|
clk++;
|
||||||
m = bus.read(addr);
|
m = bus.read(addr);
|
||||||
int borrow = isset(C) ? 0 : 1;
|
int borrow = isset(C) ? 0 : 1;
|
||||||
flag_change(C, !(a < (m + borrow)));
|
flag_change(C, !(a < (m + borrow)));
|
||||||
@ -933,6 +1007,8 @@ struct CPU6502
|
|||||||
|
|
||||||
case 0xFD: { // SBC abs, X
|
case 0xFD: { // SBC abs, X
|
||||||
int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256 + x;
|
int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256 + x;
|
||||||
|
if((addr - x) / 256 != addr / 256)
|
||||||
|
clk++;
|
||||||
unsigned char m = bus.read(addr);
|
unsigned char m = bus.read(addr);
|
||||||
int borrow = isset(C) ? 0 : 1;
|
int borrow = isset(C) ? 0 : 1;
|
||||||
flag_change(C, !(a < (m + borrow)));
|
flag_change(C, !(a < (m + borrow)));
|
||||||
@ -972,6 +1048,8 @@ struct CPU6502
|
|||||||
|
|
||||||
case 0x79: { // ADC abs, Y
|
case 0x79: { // ADC abs, Y
|
||||||
int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256 + y;
|
int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256 + y;
|
||||||
|
if((addr - y) / 256 != addr / 256)
|
||||||
|
clk++;
|
||||||
m = bus.read(addr);
|
m = bus.read(addr);
|
||||||
int carry = isset(C) ? 1 : 0;
|
int carry = isset(C) ? 1 : 0;
|
||||||
flag_change(C, (int)(a + m + carry) > 0xFF);
|
flag_change(C, (int)(a + m + carry) > 0xFF);
|
||||||
@ -1059,6 +1137,8 @@ struct CPU6502
|
|||||||
case 0x11: { // ORA (ind), Y
|
case 0x11: { // ORA (ind), Y
|
||||||
unsigned char zpg = read_pc_inc(bus);
|
unsigned char zpg = read_pc_inc(bus);
|
||||||
int addr = bus.read(zpg) + bus.read((zpg + 1) & 0xFF) * 256 + y;
|
int addr = bus.read(zpg) + bus.read((zpg + 1) & 0xFF) * 256 + y;
|
||||||
|
if((addr - y) / 256 != addr / 256)
|
||||||
|
clk++;
|
||||||
m = bus.read(addr);
|
m = bus.read(addr);
|
||||||
set_flags(N | Z, a = a | m);
|
set_flags(N | Z, a = a | m);
|
||||||
break;
|
break;
|
||||||
@ -1144,9 +1224,8 @@ struct CPU6502
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x4C: {
|
case 0x4C: { // JMP
|
||||||
int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256;
|
int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256;
|
||||||
// JMP
|
|
||||||
pc = addr;
|
pc = addr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1221,6 +1300,8 @@ struct CPU6502
|
|||||||
|
|
||||||
case 0xBE: { // LDX
|
case 0xBE: { // LDX
|
||||||
int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256 + y;
|
int addr = read_pc_inc(bus) + read_pc_inc(bus) * 256 + y;
|
||||||
|
if((addr - y) / 256 != addr / 256)
|
||||||
|
clk++;
|
||||||
set_flags(N | Z, x = bus.read(addr));
|
set_flags(N | Z, x = bus.read(addr));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1304,6 +1385,8 @@ struct CPU6502
|
|||||||
case 0x51: { // EOR
|
case 0x51: { // EOR
|
||||||
unsigned char zpg = read_pc_inc(bus);
|
unsigned char zpg = read_pc_inc(bus);
|
||||||
int addr = bus.read(zpg) + bus.read((zpg + 1) & 0xFF) * 256 + y;
|
int addr = bus.read(zpg) + bus.read((zpg + 1) & 0xFF) * 256 + y;
|
||||||
|
if((addr - y) / 256 != addr / 256)
|
||||||
|
clk++;
|
||||||
m = bus.read(addr);
|
m = bus.read(addr);
|
||||||
set_flags(N | Z, a = a ^ m);
|
set_flags(N | Z, a = a ^ m);
|
||||||
break;
|
break;
|
||||||
@ -1312,6 +1395,8 @@ struct CPU6502
|
|||||||
case 0xD1: { // CMP
|
case 0xD1: { // CMP
|
||||||
unsigned char zpg = read_pc_inc(bus);
|
unsigned char zpg = read_pc_inc(bus);
|
||||||
int addr = bus.read(zpg) + bus.read((zpg + 1) & 0xFF) * 256 + y;
|
int addr = bus.read(zpg) + bus.read((zpg + 1) & 0xFF) * 256 + y;
|
||||||
|
if((addr - y) / 256 != addr / 256)
|
||||||
|
clk++;
|
||||||
m = bus.read(addr);
|
m = bus.read(addr);
|
||||||
flag_change(C, m <= a);
|
flag_change(C, m <= a);
|
||||||
set_flags(N | Z, m = a - m);
|
set_flags(N | Z, m = a - m);
|
||||||
@ -1365,34 +1450,6 @@ struct CPU6502
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x90: { // BCC
|
|
||||||
int rel = (read_pc_inc(bus) + 128) % 256 - 128;
|
|
||||||
if(!isset(C))
|
|
||||||
pc += rel;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 0xB0: { // BCS
|
|
||||||
int rel = (read_pc_inc(bus) + 128) % 256 - 128;
|
|
||||||
if(isset(C))
|
|
||||||
pc += rel;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 0xD0: { // BNE
|
|
||||||
int rel = (read_pc_inc(bus) + 128) % 256 - 128;
|
|
||||||
if(!isset(Z))
|
|
||||||
pc += rel;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 0xF0: { // BEQ
|
|
||||||
int rel = (read_pc_inc(bus) + 128) % 256 - 128;
|
|
||||||
if(isset(Z))
|
|
||||||
pc += rel;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 0x85: { // STA
|
case 0x85: { // STA
|
||||||
unsigned char zpg = read_pc_inc(bus);
|
unsigned char zpg = read_pc_inc(bus);
|
||||||
bus.write(zpg, a);
|
bus.write(zpg, a);
|
||||||
@ -1814,7 +1871,6 @@ int main(int argc, char **argv)
|
|||||||
step6502();
|
step6502();
|
||||||
else
|
else
|
||||||
cpu.cycle(bus);
|
cpu.cycle(bus);
|
||||||
printf("clock = %llu\n", clk.value);
|
|
||||||
|
|
||||||
APPLE2Einterface::DisplayMode mode = mainboard->TEXT ? APPLE2Einterface::TEXT : (mainboard->HIRES ? APPLE2Einterface::HIRES : APPLE2Einterface::LORES);
|
APPLE2Einterface::DisplayMode mode = mainboard->TEXT ? APPLE2Einterface::TEXT : (mainboard->HIRES ? APPLE2Einterface::HIRES : APPLE2Einterface::LORES);
|
||||||
int page = mainboard->PAGE2 ? 1 : 0;
|
int page = mainboard->PAGE2 ? 1 : 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user