mirror of
https://github.com/bradgrantham/apple2e.git
synced 2024-12-27 01:32:14 +00:00
import from stella
This commit is contained in:
parent
df7a4df305
commit
836e348f60
200
cpu6502.h
200
cpu6502.h
@ -25,8 +25,11 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <vector>
|
||||
|
||||
#ifndef EMULATE_65C02
|
||||
#define EMULATE_65C02 1
|
||||
#endif /* EMULATE_65C02 */
|
||||
|
||||
template<class CLK, class BUS>
|
||||
struct CPU6502
|
||||
@ -55,9 +58,11 @@ struct CPU6502
|
||||
INT,
|
||||
} exception;
|
||||
|
||||
std::vector<std::pair<uint16_t, uint8_t>> writes;
|
||||
|
||||
void stack_push(uint8_t d)
|
||||
{
|
||||
bus.write(0x100 + s--, d);
|
||||
writes.push_back(std::make_pair(0x100 + s--, d));
|
||||
}
|
||||
|
||||
uint8_t stack_pull()
|
||||
@ -96,7 +101,7 @@ struct CPU6502
|
||||
|
||||
bool isset(uint8_t flag)
|
||||
{
|
||||
return (p & flag) != 0;
|
||||
return p & flag;
|
||||
}
|
||||
|
||||
void set_flags(uint8_t flags, uint8_t v)
|
||||
@ -287,14 +292,14 @@ struct CPU6502
|
||||
case 0xC6: { // DEC zpg
|
||||
uint8_t zpg = read_pc_inc();
|
||||
set_flags(N | Z, m = bus.read(zpg) - 1);
|
||||
bus.write(zpg, m);
|
||||
writes.push_back(std::make_pair(zpg, m));
|
||||
break;
|
||||
}
|
||||
|
||||
case 0xD6: { // DEC zpg, X
|
||||
uint8_t zpg = (read_pc_inc() + x) % 0xFF;
|
||||
set_flags(N | Z, m = bus.read(zpg) - 1);
|
||||
bus.write(zpg, m);
|
||||
writes.push_back(std::make_pair(zpg, m));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -303,7 +308,7 @@ struct CPU6502
|
||||
uint8_t high = read_pc_inc();
|
||||
uint16_t addr = low + high * 256 + x;
|
||||
set_flags(N | Z, m = bus.read(addr) - 1);
|
||||
bus.write(addr, m);
|
||||
writes.push_back(std::make_pair(addr, m));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -312,7 +317,7 @@ struct CPU6502
|
||||
uint8_t high = read_pc_inc();
|
||||
uint16_t addr = low + high * 256;
|
||||
set_flags(N | Z, m = bus.read(addr) - 1);
|
||||
bus.write(addr, m);
|
||||
writes.push_back(std::make_pair(addr, m));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -328,7 +333,7 @@ struct CPU6502
|
||||
if((addr - x) / 256 != addr / 256)
|
||||
clk.add_cpu_cycles(1);
|
||||
set_flags(N | Z, m = bus.read(addr) + 1);
|
||||
bus.write(addr, m);
|
||||
writes.push_back(std::make_pair(addr, m));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -337,21 +342,21 @@ struct CPU6502
|
||||
uint8_t high = read_pc_inc();
|
||||
uint16_t addr = low + high * 256;
|
||||
set_flags(N | Z, m = bus.read(addr) + 1);
|
||||
bus.write(addr, m);
|
||||
writes.push_back(std::make_pair(addr, m));
|
||||
break;
|
||||
}
|
||||
|
||||
case 0xE6: { // INC zpg
|
||||
uint8_t zpg = read_pc_inc();
|
||||
set_flags(N | Z, m = bus.read(zpg) + 1);
|
||||
bus.write(zpg, m);
|
||||
writes.push_back(std::make_pair(zpg, m));
|
||||
break;
|
||||
}
|
||||
|
||||
case 0xF6: { // INC zpg, X
|
||||
uint8_t zpg = (read_pc_inc() + x) & 0xFF;
|
||||
set_flags(N | Z, m = bus.read(zpg) + 1);
|
||||
bus.write(zpg, m);
|
||||
writes.push_back(std::make_pair(zpg, m));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -729,7 +734,7 @@ struct CPU6502
|
||||
flag_change(C, ((uint16_t)bcd + (uint16_t)m + carry) > 99);
|
||||
flag_change(V, adc_overflow_d(bcd, m, carry));
|
||||
set_flags(N | Z, bcd = bcd + m + carry);
|
||||
a = bcd / 10 * 16 + bcd % 10;
|
||||
a = bcd / 10 * 16 + bcd % 10 - (isset(C) ? 0xA0 : 0);
|
||||
} else {
|
||||
flag_change(C, ((uint16_t)a + (uint16_t)m + carry) > 0xFF);
|
||||
flag_change(V, adc_overflow(a, m, carry));
|
||||
@ -752,7 +757,7 @@ struct CPU6502
|
||||
flag_change(C, ((uint16_t)bcd + (uint16_t)m + carry) > 99);
|
||||
flag_change(V, adc_overflow_d(bcd, m, carry));
|
||||
set_flags(N | Z, bcd = bcd + m + carry);
|
||||
a = bcd / 10 * 16 + bcd % 10;
|
||||
a = bcd / 10 * 16 + bcd % 10 - (isset(C) ? 0xA0 : 0);
|
||||
} else {
|
||||
flag_change(C, ((uint16_t)a + (uint16_t)m + carry) > 0xFF);
|
||||
flag_change(V, adc_overflow(a, m, carry));
|
||||
@ -772,7 +777,7 @@ struct CPU6502
|
||||
flag_change(C, ((uint16_t)bcd + (uint16_t)m + carry) > 99);
|
||||
flag_change(V, adc_overflow_d(bcd, m, carry));
|
||||
set_flags(N | Z, bcd = bcd + m + carry);
|
||||
a = bcd / 10 * 16 + bcd % 10;
|
||||
a = bcd / 10 * 16 + bcd % 10 - (isset(C) ? 0xA0 : 0);
|
||||
} else {
|
||||
flag_change(C, ((uint16_t)a + (uint16_t)m + carry) > 0xFF);
|
||||
flag_change(V, adc_overflow(a, m, carry));
|
||||
@ -790,7 +795,7 @@ struct CPU6502
|
||||
flag_change(C, ((uint16_t)bcd + (uint16_t)m + carry) > 99);
|
||||
flag_change(V, adc_overflow_d(bcd, m, carry));
|
||||
set_flags(N | Z, bcd = bcd + m + carry);
|
||||
a = bcd / 10 * 16 + bcd % 10;
|
||||
a = bcd / 10 * 16 + bcd % 10 - (isset(C) ? 0xA0 : 0);
|
||||
} else {
|
||||
flag_change(C, ((uint16_t)a + (uint16_t)m + carry) > 0xFF);
|
||||
flag_change(V, adc_overflow(a, m, carry));
|
||||
@ -812,7 +817,7 @@ struct CPU6502
|
||||
flag_change(C, ((uint16_t)bcd + (uint16_t)m + carry) > 99);
|
||||
flag_change(V, adc_overflow_d(bcd, m, carry));
|
||||
set_flags(N | Z, bcd = bcd + m + carry);
|
||||
a = bcd / 10 * 16 + bcd % 10;
|
||||
a = bcd / 10 * 16 + bcd % 10 - (isset(C) ? 0xA0 : 0);
|
||||
} else {
|
||||
flag_change(C, ((uint16_t)a + (uint16_t)m + carry) > 0xFF);
|
||||
flag_change(V, adc_overflow(a, m, carry));
|
||||
@ -834,7 +839,7 @@ struct CPU6502
|
||||
flag_change(C, ((uint16_t)bcd + (uint16_t)m + carry) > 99);
|
||||
flag_change(V, adc_overflow_d(bcd, m, carry));
|
||||
set_flags(N | Z, bcd = bcd + m + carry);
|
||||
a = bcd / 10 * 16 + bcd % 10;
|
||||
a = bcd / 10 * 16 + bcd % 10 - (isset(C) ? 0xA0 : 0);
|
||||
} else {
|
||||
flag_change(C, ((uint16_t)a + (uint16_t)m + carry) > 0xFF);
|
||||
flag_change(V, adc_overflow(a, m, carry));
|
||||
@ -851,7 +856,7 @@ struct CPU6502
|
||||
flag_change(C, ((uint16_t)bcd + (uint16_t)m + carry) > 99);
|
||||
flag_change(V, adc_overflow_d(bcd, m, carry));
|
||||
set_flags(N | Z, bcd = bcd + m + carry);
|
||||
a = bcd / 10 * 16 + bcd % 10;
|
||||
a = bcd / 10 * 16 + bcd % 10 - (isset(C) ? 0xA0 : 0);
|
||||
} else {
|
||||
flag_change(C, ((uint16_t)a + (uint16_t)m + carry) > 0xFF);
|
||||
flag_change(V, adc_overflow(a, m, carry));
|
||||
@ -865,7 +870,7 @@ struct CPU6502
|
||||
m = bus.read(addr);
|
||||
flag_change(C, m & 0x80);
|
||||
set_flags(N | Z, m = m << 1);
|
||||
bus.write(addr, m);
|
||||
writes.push_back(std::make_pair(addr, m));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -874,7 +879,7 @@ struct CPU6502
|
||||
m = bus.read(addr + x);
|
||||
flag_change(C, m & 0x80);
|
||||
set_flags(N | Z, m = m << 1);
|
||||
bus.write(addr + x, m);
|
||||
writes.push_back(std::make_pair(addr + x, m));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -883,7 +888,7 @@ struct CPU6502
|
||||
m = bus.read(zpg);
|
||||
flag_change(C, m & 0x80);
|
||||
set_flags(N | Z, m = m << 1);
|
||||
bus.write(zpg, m);
|
||||
writes.push_back(std::make_pair(zpg, m));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -909,7 +914,7 @@ struct CPU6502
|
||||
m = bus.read(addr + x);
|
||||
flag_change(C, m & 0x01);
|
||||
set_flags(N | Z, m = m >> 1);
|
||||
bus.write(addr + x, m);
|
||||
writes.push_back(std::make_pair(addr + x, m));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -918,7 +923,7 @@ struct CPU6502
|
||||
m = bus.read(zpg);
|
||||
flag_change(C, m & 0x01);
|
||||
set_flags(N | Z, m = m >> 1);
|
||||
bus.write(zpg, m);
|
||||
writes.push_back(std::make_pair(zpg, m));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -927,7 +932,7 @@ struct CPU6502
|
||||
m = bus.read(zpg & 0xFF);
|
||||
flag_change(C, m & 0x01);
|
||||
set_flags(N | Z, m = m >> 1);
|
||||
bus.write(zpg, m);
|
||||
writes.push_back(std::make_pair(zpg, m));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -938,7 +943,7 @@ struct CPU6502
|
||||
m = bus.read(addr);
|
||||
flag_change(C, m & 0x01);
|
||||
set_flags(N | Z, m = m >> 1);
|
||||
bus.write(addr, m);
|
||||
writes.push_back(std::make_pair(addr, m));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1112,7 +1117,7 @@ struct CPU6502
|
||||
bool c = isset(C);
|
||||
flag_change(C, m & 0x01);
|
||||
set_flags(N | Z, m = (c ? 0x80 : 0x00) | (m >> 1));
|
||||
bus.write(addr + x, m);
|
||||
writes.push_back(std::make_pair(addr + x, m));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1122,7 +1127,7 @@ struct CPU6502
|
||||
bool c = isset(C);
|
||||
flag_change(C, m & 0x80);
|
||||
set_flags(N | Z, m = (c ? 0x01 : 0x00) | (m << 1));
|
||||
bus.write(zpg, m);
|
||||
writes.push_back(std::make_pair(zpg, m));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1135,7 +1140,7 @@ struct CPU6502
|
||||
bool c = isset(C);
|
||||
flag_change(C, m & 0x80);
|
||||
set_flags(N | Z, m = (c ? 0x01 : 0x00) | (m << 1));
|
||||
bus.write(addr + x, m);
|
||||
writes.push_back(std::make_pair(addr + x, m));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1161,7 +1166,7 @@ struct CPU6502
|
||||
bool c = isset(C);
|
||||
flag_change(C, m & 0x01);
|
||||
set_flags(N | Z, m = (c ? 0x80 : 0x00) | (m >> 1));
|
||||
bus.write(addr, m);
|
||||
writes.push_back(std::make_pair(addr, m));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1171,7 +1176,7 @@ struct CPU6502
|
||||
bool c = isset(C);
|
||||
flag_change(C, m & 0x01);
|
||||
set_flags(N | Z, m = (c ? 0x80 : 0x00) | (m >> 1));
|
||||
bus.write(zpg, m);
|
||||
writes.push_back(std::make_pair(zpg, m));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1181,7 +1186,7 @@ struct CPU6502
|
||||
bool c = isset(C);
|
||||
flag_change(C, m & 0x01);
|
||||
set_flags(N | Z, m = (c ? 0x80 : 0x00) | (m >> 1));
|
||||
bus.write(zpg, m);
|
||||
writes.push_back(std::make_pair(zpg, m));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1193,7 +1198,7 @@ struct CPU6502
|
||||
bool c = isset(C);
|
||||
flag_change(C, m & 0x80);
|
||||
set_flags(N | Z, m = (c ? 0x01 : 0x00) | (m << 1));
|
||||
bus.write(addr, m);
|
||||
writes.push_back(std::make_pair(addr, m));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1204,7 +1209,7 @@ struct CPU6502
|
||||
m = bus.read(zpg);
|
||||
flag_change(C, m & 0x80);
|
||||
set_flags(N | Z, m = (c ? 0x01 : 0x00) | (m << 1));
|
||||
bus.write(zpg, m);
|
||||
writes.push_back(std::make_pair(zpg, m));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1231,7 +1236,7 @@ struct CPU6502
|
||||
uint8_t low = read_pc_inc();
|
||||
uint8_t high = read_pc_inc();
|
||||
uint16_t addr = low + high * 256;
|
||||
bus.write(addr + x, a);
|
||||
writes.push_back(std::make_pair(addr + x, a));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1239,7 +1244,7 @@ struct CPU6502
|
||||
uint8_t low = read_pc_inc();
|
||||
uint8_t high = read_pc_inc();
|
||||
uint16_t addr = low + high * 256;
|
||||
bus.write(addr + y, a);
|
||||
writes.push_back(std::make_pair(addr + y, a));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1248,7 +1253,7 @@ struct CPU6502
|
||||
uint8_t low = bus.read(zpg);
|
||||
uint8_t high = bus.read((zpg + 1) & 0xFF);
|
||||
uint16_t addr = low + high * 256 + y;
|
||||
bus.write(addr, a);
|
||||
writes.push_back(std::make_pair(addr, a));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1257,7 +1262,7 @@ struct CPU6502
|
||||
uint8_t low = bus.read(zpg);
|
||||
uint8_t high = bus.read((zpg + 1) & 0xFF);
|
||||
uint16_t addr = low + high * 256;
|
||||
bus.write(addr, a);
|
||||
writes.push_back(std::make_pair(addr, a));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1265,7 +1270,7 @@ struct CPU6502
|
||||
uint8_t low = read_pc_inc();
|
||||
uint8_t high = read_pc_inc();
|
||||
uint16_t addr = low + high * 256;
|
||||
bus.write(addr, a);
|
||||
writes.push_back(std::make_pair(addr, a));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1545,7 +1550,7 @@ struct CPU6502
|
||||
|
||||
case 0x85: { // STA
|
||||
uint8_t zpg = read_pc_inc();
|
||||
bus.write(zpg, a);
|
||||
writes.push_back(std::make_pair(zpg, a));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1580,26 +1585,26 @@ struct CPU6502
|
||||
uint8_t low = read_pc_inc();
|
||||
uint8_t high = read_pc_inc();
|
||||
uint16_t addr = low + high * 256;
|
||||
bus.write(addr, x);
|
||||
writes.push_back(std::make_pair(addr, x));
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x86: { // STX
|
||||
uint8_t zpg = read_pc_inc();
|
||||
bus.write(zpg, x);
|
||||
writes.push_back(std::make_pair(zpg, x));
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x96: { // STX zpg, Y
|
||||
uint8_t zpg = read_pc_inc();
|
||||
uint16_t addr = (zpg + y) & 0xFF;
|
||||
bus.write(addr, x);
|
||||
writes.push_back(std::make_pair(addr, x));
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x84: { // STY
|
||||
uint8_t zpg = read_pc_inc();
|
||||
bus.write(zpg, y);
|
||||
writes.push_back(std::make_pair(zpg, y));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1607,7 +1612,7 @@ struct CPU6502
|
||||
uint8_t low = read_pc_inc();
|
||||
uint8_t high = read_pc_inc();
|
||||
uint16_t addr = low + high * 256;
|
||||
bus.write(addr, y);
|
||||
writes.push_back(std::make_pair(addr, y));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1621,6 +1626,26 @@ struct CPU6502
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x75: { // ADC zpg, X
|
||||
uint8_t zpg = read_pc_inc();
|
||||
uint16_t addr = (zpg + x)& 0xFF;
|
||||
m = bus.read(addr);
|
||||
uint8_t carry = isset(C) ? 1 : 0;
|
||||
if(isset(D)) {
|
||||
uint8_t bcd = a / 16 * 10 + a % 16;
|
||||
flag_change(C, ((uint16_t)bcd + (uint16_t)m + carry) > 99);
|
||||
flag_change(V, adc_overflow_d(bcd, m, carry));
|
||||
set_flags(N | Z, bcd = bcd + m + carry);
|
||||
a = bcd / 10 * 16 + bcd % 10;
|
||||
} else {
|
||||
flag_change(C, ((uint16_t)a + (uint16_t)m + carry) > 0xFF);
|
||||
flag_change(V, adc_overflow(a, m, carry));
|
||||
set_flags(N | Z, a = a + m + carry);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
#if EMULATE_65C02
|
||||
// 65C02 instructions
|
||||
|
||||
@ -1677,7 +1702,7 @@ struct CPU6502
|
||||
|
||||
case 0x64: { // STZ zpg, 65C02
|
||||
uint8_t zpg = read_pc_inc();
|
||||
bus.write(zpg, 0);
|
||||
writes.push_back(std::make_pair(zpg, 0));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1685,7 +1710,7 @@ struct CPU6502
|
||||
uint8_t low = read_pc_inc();
|
||||
uint8_t high = read_pc_inc();
|
||||
uint16_t addr = low + high * 256;
|
||||
bus.write(addr, 0x0);
|
||||
writes.push_back(std::make_pair(addr, 0x0));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1708,7 +1733,7 @@ struct CPU6502
|
||||
uint8_t low = bus.read(zpg);
|
||||
uint8_t high = bus.read((zpg + 1) & 0xFF);
|
||||
uint16_t addr = low + high * 256;
|
||||
bus.write(addr, a);
|
||||
writes.push_back(std::make_pair(addr, a));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1733,25 +1758,6 @@ struct CPU6502
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x75: { // ADC zpg, X
|
||||
uint8_t zpg = read_pc_inc();
|
||||
uint16_t addr = (zpg + x)& 0xFF;
|
||||
m = bus.read(addr);
|
||||
uint8_t carry = isset(C) ? 1 : 0;
|
||||
if(isset(D)) {
|
||||
uint8_t bcd = a / 16 * 10 + a % 16;
|
||||
flag_change(C, ((uint16_t)bcd + (uint16_t)m + carry) > 99);
|
||||
flag_change(V, adc_overflow_d(bcd, m, carry));
|
||||
set_flags(N | Z, bcd = bcd + m + carry);
|
||||
a = bcd / 10 * 16 + bcd % 10;
|
||||
} else {
|
||||
flag_change(C, ((uint16_t)a + (uint16_t)m + carry) > 0xFF);
|
||||
flag_change(V, adc_overflow(a, m, carry));
|
||||
set_flags(N | Z, a = a + m + carry);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x3A: { // DEC, 65C02
|
||||
set_flags(N | Z, a = a - 1);
|
||||
break;
|
||||
@ -1783,39 +1789,39 @@ struct CPU6502
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x1C: { // TRB abs
|
||||
case 0x1C: { // TRB abs, 65C02 instruction
|
||||
uint8_t low = read_pc_inc();
|
||||
uint8_t high = read_pc_inc();
|
||||
uint16_t addr = low + high * 256;
|
||||
m = bus.read(addr);
|
||||
set_flags(Z, m & a);
|
||||
bus.write(addr, m & ~a);
|
||||
writes.push_back(std::make_pair(addr, m & ~a));
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x14: { // TRB zpg
|
||||
case 0x14: { // TRB zpg, 65C02 instruction
|
||||
uint8_t zpgaddr = read_pc_inc();
|
||||
m = bus.read(zpgaddr);
|
||||
set_flags(Z, m & a);
|
||||
bus.write(zpgaddr, m & ~a);
|
||||
writes.push_back(std::make_pair(zpgaddr, m & ~a));
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x0C: { // TSB abs
|
||||
case 0x0C: { // TSB abs, 65C02 instruction
|
||||
uint8_t low = read_pc_inc();
|
||||
uint8_t high = read_pc_inc();
|
||||
uint16_t addr = low + high * 256;
|
||||
m = bus.read(addr);
|
||||
set_flags(Z, m & a);
|
||||
bus.write(addr, m | a);
|
||||
writes.push_back(std::make_pair(addr, m | a));
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x04: { // TRB zpg
|
||||
case 0x04: { // TRB zpg, 65C02 instruction
|
||||
uint8_t zpgaddr = read_pc_inc();
|
||||
m = bus.read(zpgaddr);
|
||||
set_flags(Z, m & a);
|
||||
bus.write(zpgaddr, m | a);
|
||||
writes.push_back(std::make_pair(zpgaddr, m | a));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1863,7 +1869,7 @@ struct CPU6502
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x7C: { // JMP (ind, X)
|
||||
case 0x7C: { // JMP (ind, X), 65C02 instruction
|
||||
uint8_t low = read_pc_inc();
|
||||
uint8_t high = read_pc_inc();
|
||||
uint16_t addr = low + high * 256 + x;
|
||||
@ -1884,11 +1890,20 @@ struct CPU6502
|
||||
uint8_t low = read_pc_inc();
|
||||
uint8_t high = read_pc_inc();
|
||||
uint16_t addr = low + high * 256;
|
||||
bus.write(addr + x, 0);
|
||||
writes.push_back(std::make_pair(addr + x, 0));
|
||||
break;
|
||||
}
|
||||
|
||||
#endif // EMULATE_65C02
|
||||
#else /* ! EMULATE_65C02 */
|
||||
|
||||
case 0x04: { // NOP zpg
|
||||
uint8_t zpgaddr = read_pc_inc();
|
||||
m = bus.read(zpgaddr);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
#endif /* EMULATE_65C02 */
|
||||
|
||||
default:
|
||||
printf("unhandled instruction %02X at %04X\n", inst, pc - 1);
|
||||
@ -1896,13 +1911,23 @@ struct CPU6502
|
||||
exit(1);
|
||||
}
|
||||
assert(cycles[inst] > 0);
|
||||
clk.add_cpu_cycles(cycles[inst]);
|
||||
// Hack for putting writes near the end of the instruction to hopefully
|
||||
// match real timing
|
||||
clk.add_cpu_cycles(cycles[inst] - writes.size());
|
||||
for(size_t i = 0; i < writes.size(); i++) {
|
||||
const auto& write = writes[i];
|
||||
clk.add_cpu_cycles(1);
|
||||
bus.write(write.first, write.second);
|
||||
}
|
||||
writes.clear();
|
||||
}
|
||||
};
|
||||
|
||||
template<class CLK, class BUS>
|
||||
const int32_t CPU6502<CLK, BUS>::cycles[256] =
|
||||
{
|
||||
#if EMULATE_65C02
|
||||
/* 0 1 2 3 4 5 6 7 8 9 0 A B C D E */
|
||||
/* 0x0- */ 7, 6, 2, 1, 5, 3, 5, 0, 3, 2, 2, 1, 6, 4, 6, 5,
|
||||
/* 0x1- */ 2, 5, 5, 1, 5, 4, 6, 0, 2, 4, 2, 1, 6, 4, 7, 5,
|
||||
/* 0x2- */ 6, 6, 2, 1, 3, 3, 5, 0, 4, 2, 2, 1, 4, 4, 6, 5,
|
||||
@ -1917,8 +1942,27 @@ const int32_t CPU6502<CLK, BUS>::cycles[256] =
|
||||
/* 0xB- */ 2, 5, 5, 1, 4, 4, 4, 0, 2, 4, 2, 1, 4, 4, 4, 5,
|
||||
/* 0xC- */ 2, 6, 2, 1, 3, 3, 5, 0, 2, 2, 2, 1, 4, 4, 3, 5,
|
||||
/* 0xD- */ 2, 5, 5, 1, 4, 4, 6, 0, 2, 4, 3, 1, 4, 4, 7, 5,
|
||||
/* 0xE- */ 2, 6, 2, 1, 3, 3, 5, 0, 2, 2, 2, 1, 4, 4, 6, 5,
|
||||
/* 0xE- */ 2, 6, 2, 1, 3, 3, 5, 0, 2, 2, 2, 2, 4, 4, 6, 5,
|
||||
/* 0xF- */ 2, 5, 0, 1, 4, 4, 6, 0, 2, 4, 4, 1, 4, 4, 7, 5,
|
||||
#else /* ! EMULATE_65C02 */
|
||||
/* 0 1 2 3 4 5 6 7 8 9 0 A B C D E */
|
||||
/* 0x0- */ 7, 6, 2, 1, 3, 3, 5, 0, 3, 2, 2, 1, 6, 4, 6, 5,
|
||||
/* 0x1- */ 2, 5, 5, 1, 5, 4, 6, 0, 2, 4, 2, 1, 6, 4, 7, 5,
|
||||
/* 0x2- */ 6, 6, 2, 1, 3, 3, 5, 0, 4, 2, 2, 1, 4, 4, 6, 5,
|
||||
/* 0x3- */ 2, 5, 0, 1, 0, 4, 6, 0, 2, 4, 2, 1, 0, 4, 7, 5,
|
||||
/* 0x4- */ 6, 6, 2, 1, 3, 3, 5, 0, 3, 2, 2, 1, 3, 4, 6, 5,
|
||||
/* 0x5- */ 2, 5, 0, 1, 4, 4, 6, 0, 2, 4, 3, 1, 8, 4, 7, 5,
|
||||
/* 0x6- */ 6, 6, 2, 1, 3, 3, 5, 0, 4, 2, 2, 1, 5, 4, 6, 5,
|
||||
/* 0x7- */ 2, 5, 5, 1, 0, 4, 6, 0, 2, 4, 4, 1, 6, 4, 7, 5,
|
||||
/* 0x8- */ 2, 6, 2, 1, 3, 3, 3, 0, 2, 2, 2, 1, 4, 4, 4, 5,
|
||||
/* 0x9- */ 2, 6, 5, 1, 4, 4, 4, 0, 2, 5, 2, 1, 4, 5, 5, 5,
|
||||
/* 0xA- */ 2, 6, 2, 1, 3, 3, 3, 0, 2, 2, 2, 1, 4, 4, 4, 5,
|
||||
/* 0xB- */ 2, 5, 5, 1, 4, 4, 4, 0, 2, 4, 2, 1, 4, 4, 4, 5,
|
||||
/* 0xC- */ 2, 6, 2, 1, 3, 3, 5, 0, 2, 2, 2, 1, 4, 4, 3, 5,
|
||||
/* 0xD- */ 2, 5, 5, 1, 4, 4, 6, 0, 2, 4, 3, 1, 4, 4, 7, 5,
|
||||
/* 0xE- */ 2, 6, 2, 1, 3, 3, 5, 0, 2, 2, 2, 2, 4, 4, 6, 5,
|
||||
/* 0xF- */ 2, 5, 0, 1, 4, 4, 6, 0, 2, 4, 4, 1, 4, 4, 7, 5,
|
||||
#endif /* EMULATE_65C02 */
|
||||
};
|
||||
|
||||
#endif // CPU6502_H
|
||||
|
Loading…
Reference in New Issue
Block a user