56 uint8_t lo =
read(0xfffe);
57 uint8_t hi =
read(0xffff);
92 static int entry_log = 0;
93 if ((
PC >= 0xFFF0 &&
PC <= 0xFFFF) && entry_log++ < 5) {
94 LOG_DEBUG(
"SPC",
"RunOpcode ENTRY: PC=$%04X step=%d bstep=%d",
PC,
step,
121 static int spc_exec_count = 0;
122 bool in_critical_range = (
PC >= 0xFFCF &&
PC <= 0xFFFF);
123 bool is_transfer_loop = (
PC >= 0xFFD6 &&
PC <= 0xFFED);
126 if (in_critical_range && spc_exec_count++ < 5) {
127 LOG_DEBUG(
"SPC",
"Execute: PC=$%04X step=0 bstep=%d Y=%02X A=%02X",
PC,
130 if (is_transfer_loop && spc_exec_count < 10) {
136 "TRANSFER LOOP: PC=$%04X Y=%02X A=%02X F4=%02X F5=%02X "
137 "RAM0=%02X bstep=%d",
138 PC,
Y,
A, f4_val, f5_val, ram0_val,
bstep);
147 if (spc_exec_count < 5) {
149 "Continuing multi-step: PC=$%04X bstep=%d opcode=$%02X",
PC,
161 static int exec_log = 0;
162 if ((
PC >= 0xFFF0 &&
PC <= 0xFFFF) && exec_log++ < 5) {
165 "About to ExecuteInstructions: PC=$%04X step=%d bstep=%d opcode=$%02X",
171 static int reset_log = 0;
174 if ((
PC >= 0xFFF0 &&
PC <= 0xFFFF) && reset_log++ < 5) {
175 LOG_DEBUG(
"SPC",
"Resetting step: PC=$%04X opcode=$%02X bstep=%d",
PC,
180 if ((
PC >= 0xFFF0 &&
PC <= 0xFFFF) && reset_log++ < 5) {
181 LOG_DEBUG(
"SPC",
"NOT resetting step: PC=$%04X opcode=$%02X bstep=%d",
215 uint16_t
adr = 0xffde - (2 * (
opcode >> 4));
292 uint16_t dst =
dp_dp(&src);
321 uint8_t result =
A + (val ^ 0xff) + 1;
322 PSW.
Z = (result == 0);
323 PSW.
N = (result & 0x80);
359 uint16_t dst =
dp_imm(&src);
372 uint16_t value =
read(low) - 1;
373 write(low, value & 0xff);
374 value +=
read(high) << 8;
375 write(high, value >> 8);
377 PSW.
N = value & 0x8000;
436 uint16_t dst =
dp_dp(&src);
462 uint8_t val =
read(
dp()) ^ 0xff;
464 uint8_t result =
A + val + 1;
494 uint16_t dst =
dp_imm(&src);
507 uint16_t value =
read(low) + 1;
508 write(low, value & 0xff);
509 value +=
read(high) << 8;
510 write(high, value >> 8);
512 PSW.
N = value & 0x8000;
521 bool newC =
A & 0x80;
575 uint16_t dst =
dp_dp(&src);
603 uint8_t result =
A + (val ^ 0xff) + 1;
604 PSW.
Z = (result == 0);
605 PSW.
N = (result & 0x80);
639 uint16_t dst =
dp_imm(&src);
652 uint16_t value =
read_word(low) ^ 0xffff;
653 uint16_t ya =
A | (
Y << 8);
654 int result = ya + value + 1;
655 PSW.
C = result > 0xffff;
656 PSW.
Z = (result & 0xffff) == 0;
657 PSW.
N = result & 0x8000;
714 uint16_t dst =
dp_dp(&src);
740 uint8_t result =
read(
adr) - 1;
777 int result = val -
imm;
779 PSW.
Z = (result == 0);
780 PSW.
N = (result & 0x80);
792 uint8_t vall =
read(low);
794 uint16_t value = vall | (
read(high) << 8);
795 uint16_t ya =
A | (
Y << 8);
796 int result = ya + value;
797 PSW.
V = (ya & 0x8000) == (value & 0x8000) &&
798 (value & 0x8000) != (result & 0x8000);
799 PSW.
H = ((ya & 0xfff) + (value & 0xfff)) > 0xfff;
800 PSW.
C = result > 0xffff;
801 PSW.
Z = (result & 0xffff) == 0;
802 PSW.
N = result & 0x8000;
814 A = (
A >> 1) | (
PSW.
C << 7);
865 uint16_t dst =
dp_dp(&src);
896 uint16_t dst =
dp_imm(&val);
923 uint16_t dst =
dp_imm(&src);
936 uint8_t vall =
read(low);
938 uint16_t value = (vall | (
read(high) << 8)) ^ 0xffff;
939 uint16_t ya =
A | (
Y << 8);
940 int result = ya + value + 1;
941 PSW.
V = (ya & 0x8000) == (value & 0x8000) &&
942 (value & 0x8000) != (result & 0x8000);
943 PSW.
H = ((ya & 0xfff) + (value & 0xfff) + 1) > 0xfff;
944 PSW.
C = result > 0xffff;
945 PSW.
Z = (result & 0xffff) == 0;
946 PSW.
N = result & 0x8000;
971 for (
int i = 0;
i < 10;
i++)
973 PSW.
H = (
X & 0xf) <= (
Y & 0xf);
974 int yva = (
Y << 8) |
A;
976 for (
int i = 0;
i < 9;
i++) {
978 yva |= (yva & 0x20000) ? 1 : 0;
998 A = (
A >> 4) | (
A << 4);
1031 uint16_t dst =
dp_dp(&src);
1087 uint16_t dst =
dp_imm(&src);
1099 uint16_t high =
dp_word(&low);
1100 uint8_t vall =
read(low);
1102 uint16_t val = vall | (
read(high) << 8);
1106 PSW.
N = val & 0x8000;
1129 if (
A > 0x99 || !
PSW.
C) {
1133 if ((
A & 0xf) > 9 || !
PSW.
H) {
1155 uint16_t
adr =
dp();
1182 uint8_t result = (
read(
adr) & (~(1 << bit))) | (
PSW.
C << bit);
1210 for (
int i = 0;
i < 7;
i++)
1212 uint16_t result =
A *
Y;
1254 uint16_t high =
dp_word(&low);
1279 uint8_t val =
read(
dpx()) ^ 0xff;
1281 uint8_t result =
A + val + 1;
1288 if (
A > 0x99 ||
PSW.
C) {
1292 if ((
A & 0xf) > 9 ||
PSW.
H) {
1378 static int sleep_log = 0;
1379 if (sleep_log++ < 5) {
1380 LOG_DEBUG(
"SPC",
"SLEEP executed at PC=$%04X - entering low power mode",
1384 for (
int i = 0;
i < 4; ++
i)
1418 uint16_t dst =
dp_dp(&val);
1433 static int incy_log = 0;
1434 if (
PC >= 0xFFE4 &&
PC <= 0xFFE6 && incy_log++ < 10) {
1436 "INC Y executed at PC=$%04X: Y changed from $%02X to $%02X "
1464 throw std::runtime_error(
"Unknown SPC opcode: " + std::to_string(
opcode));
1472 std::stringstream ss;
1473 ss <<
"$" << std::hex << std::setw(4) << std::setfill(
'0') << initial_pc
1474 <<
": 0x" << std::setw(2) << std::setfill(
'0') <<
static_cast<int>(
opcode)
1475 <<
" " << mnemonic <<
" A:" << std::setw(2) << std::setfill(
'0')
1476 << std::hex << static_cast<int>(
A) <<
" X:" << std::setw(2)
1477 << std::setfill(
'0') << std::hex << static_cast<int>(
X)
1478 <<
" Y:" << std::setw(2) << std::setfill(
'0') << std::hex
1479 <<
static_cast<int>(
Y);
1490 stream.write(
reinterpret_cast<const char*
>(&
opcode),
sizeof(
opcode));
1491 stream.write(
reinterpret_cast<const char*
>(&
step),
sizeof(
step));
1492 stream.write(
reinterpret_cast<const char*
>(&
bstep),
sizeof(
bstep));
1493 stream.write(
reinterpret_cast<const char*
>(&
adr),
sizeof(
adr));
1494 stream.write(
reinterpret_cast<const char*
>(&
adr1),
sizeof(
adr1));
1495 stream.write(
reinterpret_cast<const char*
>(&
dat),
sizeof(
dat));
1496 stream.write(
reinterpret_cast<const char*
>(&
dat16),
sizeof(
dat16));
1497 stream.write(
reinterpret_cast<const char*
>(&
param),
sizeof(
param));
1503 stream.write(
reinterpret_cast<const char*
>(&
A),
sizeof(
A));
1504 stream.write(
reinterpret_cast<const char*
>(&
X),
sizeof(
X));
1505 stream.write(
reinterpret_cast<const char*
>(&
Y),
sizeof(
Y));
1506 stream.write(
reinterpret_cast<const char*
>(&
YA),
sizeof(
YA));
1507 stream.write(
reinterpret_cast<const char*
>(&
PC),
sizeof(
PC));
1508 stream.write(
reinterpret_cast<const char*
>(&
SP),
sizeof(
SP));
1509 stream.write(
reinterpret_cast<const char*
>(&
PSW),
sizeof(
PSW));
1516 stream.read(
reinterpret_cast<char*
>(&
opcode),
sizeof(
opcode));
1517 stream.read(
reinterpret_cast<char*
>(&
step),
sizeof(
step));
1518 stream.read(
reinterpret_cast<char*
>(&
bstep),
sizeof(
bstep));
1519 stream.read(
reinterpret_cast<char*
>(&
adr),
sizeof(
adr));
1520 stream.read(
reinterpret_cast<char*
>(&
adr1),
sizeof(
adr1));
1521 stream.read(
reinterpret_cast<char*
>(&
dat),
sizeof(
dat));
1522 stream.read(
reinterpret_cast<char*
>(&
dat16),
sizeof(
dat16));
1523 stream.read(
reinterpret_cast<char*
>(&
param),
sizeof(
param));
1528 stream.read(
reinterpret_cast<char*
>(&
A),
sizeof(
A));
1529 stream.read(
reinterpret_cast<char*
>(&
X),
sizeof(
X));
1530 stream.read(
reinterpret_cast<char*
>(&
Y),
sizeof(
Y));
1531 stream.read(
reinterpret_cast<char*
>(&
YA),
sizeof(
YA));
1532 stream.read(
reinterpret_cast<char*
>(&
PC),
sizeof(
PC));
1533 stream.read(
reinterpret_cast<char*
>(&
SP),
sizeof(
SP));
1534 stream.read(
reinterpret_cast<char*
>(&
PSW),
sizeof(
PSW));
const std::unordered_map< uint8_t, std::string > spc_opcode_map
void CMPM(uint16_t dst, uint8_t value)
uint8_t read(uint16_t address)
uint8_t abs_bit(uint16_t *adr)
void ANDM(uint16_t dest, uint8_t operand)
void EORM(uint16_t dest, uint8_t operand)
void DEC(uint16_t operand)
uint16_t ind_ind(uint8_t *srcVal)
void SBCM(uint16_t &dest, uint8_t operand)
void Reset(bool hard=false)
void LoadState(std::istream &stream)
void push_byte(uint8_t value)
uint8_t FlagsToByte(Flags flags)
void LogInstruction(uint16_t initial_pc, uint8_t opcode)
uint16_t dp_imm(uint8_t *srcVal)
uint16_t ReadOpcodeWord()
uint16_t dp_dp(uint8_t *src)
void ROL(uint16_t operand)
void write(uint16_t address, uint8_t value)
void SaveState(std::ostream &stream)
uint16_t dp_word(uint16_t *low)
void push_word(uint16_t value)
uint16_t read_word(uint16_t address)
void ASL(uint16_t operand)
void ADCM(uint16_t &dest, uint8_t operand)
void DoBranch(uint8_t value, bool check)
void ExecuteInstructions(uint8_t opcode)
void ORM(uint16_t dest, uint8_t operand)
Flags ByteToFlags(uint8_t byte)
static LogManager & instance()
void log(LogLevel level, absl::string_view category, absl::string_view message)
The primary logging function.
#define LOG_DEBUG(category, format,...)
constexpr int spc700_cycles[256]
std::function< void(bool)> idle
std::function< uint8_t(uint16_t)> read