45 uint8_t lo =
read(0xfffe);
46 uint8_t hi =
read(0xffff);
81 static int entry_log = 0;
82 if ((
PC >= 0xFFF0 &&
PC <= 0xFFFF) && entry_log++ < 5) {
83 LOG_DEBUG(
"SPC",
"RunOpcode ENTRY: PC=$%04X step=%d bstep=%d",
PC,
step,
110 static int spc_exec_count = 0;
111 bool in_critical_range = (
PC >= 0xFFCF &&
PC <= 0xFFFF);
112 bool is_transfer_loop = (
PC >= 0xFFD6 &&
PC <= 0xFFED);
115 if (in_critical_range && spc_exec_count++ < 5) {
116 LOG_DEBUG(
"SPC",
"Execute: PC=$%04X step=0 bstep=%d Y=%02X A=%02X",
PC,
119 if (is_transfer_loop && spc_exec_count < 10) {
125 "TRANSFER LOOP: PC=$%04X Y=%02X A=%02X F4=%02X F5=%02X "
126 "RAM0=%02X bstep=%d",
127 PC,
Y,
A, f4_val, f5_val, ram0_val,
bstep);
136 if (spc_exec_count < 5) {
138 "Continuing multi-step: PC=$%04X bstep=%d opcode=$%02X",
PC,
150 static int exec_log = 0;
151 if ((
PC >= 0xFFF0 &&
PC <= 0xFFFF) && exec_log++ < 5) {
154 "About to ExecuteInstructions: PC=$%04X step=%d bstep=%d opcode=$%02X",
160 static int reset_log = 0;
163 if ((
PC >= 0xFFF0 &&
PC <= 0xFFFF) && reset_log++ < 5) {
164 LOG_DEBUG(
"SPC",
"Resetting step: PC=$%04X opcode=$%02X bstep=%d",
PC,
169 if ((
PC >= 0xFFF0 &&
PC <= 0xFFFF) && reset_log++ < 5) {
170 LOG_DEBUG(
"SPC",
"NOT resetting step: PC=$%04X opcode=$%02X bstep=%d",
204 uint16_t
adr = 0xffde - (2 * (
opcode >> 4));
281 uint16_t dst =
dp_dp(&src);
310 uint8_t result =
A + (val ^ 0xff) + 1;
311 PSW.
Z = (result == 0);
312 PSW.
N = (result & 0x80);
348 uint16_t dst =
dp_imm(&src);
361 uint16_t value =
read(low) - 1;
362 write(low, value & 0xff);
363 value +=
read(high) << 8;
364 write(high, value >> 8);
366 PSW.
N = value & 0x8000;
425 uint16_t dst =
dp_dp(&src);
451 uint8_t val =
read(
dp()) ^ 0xff;
453 uint8_t result =
A + val + 1;
483 uint16_t dst =
dp_imm(&src);
496 uint16_t value =
read(low) + 1;
497 write(low, value & 0xff);
498 value +=
read(high) << 8;
499 write(high, value >> 8);
501 PSW.
N = value & 0x8000;
510 bool newC =
A & 0x80;
564 uint16_t dst =
dp_dp(&src);
592 uint8_t result =
A + (val ^ 0xff) + 1;
593 PSW.
Z = (result == 0);
594 PSW.
N = (result & 0x80);
628 uint16_t dst =
dp_imm(&src);
641 uint16_t value =
read_word(low) ^ 0xffff;
642 uint16_t ya =
A | (
Y << 8);
643 int result = ya + value + 1;
644 PSW.
C = result > 0xffff;
645 PSW.
Z = (result & 0xffff) == 0;
646 PSW.
N = result & 0x8000;
703 uint16_t dst =
dp_dp(&src);
729 uint8_t result =
read(
adr) - 1;
766 int result = val -
imm;
768 PSW.
Z = (result == 0);
769 PSW.
N = (result & 0x80);
781 uint8_t vall =
read(low);
783 uint16_t value = vall | (
read(high) << 8);
784 uint16_t ya =
A | (
Y << 8);
785 int result = ya + value;
786 PSW.
V = (ya & 0x8000) == (value & 0x8000) &&
787 (value & 0x8000) != (result & 0x8000);
788 PSW.
H = ((ya & 0xfff) + (value & 0xfff)) > 0xfff;
789 PSW.
C = result > 0xffff;
790 PSW.
Z = (result & 0xffff) == 0;
791 PSW.
N = result & 0x8000;
803 A = (
A >> 1) | (
PSW.
C << 7);
854 uint16_t dst =
dp_dp(&src);
885 uint16_t dst =
dp_imm(&val);
912 uint16_t dst =
dp_imm(&src);
925 uint8_t vall =
read(low);
927 uint16_t value = (vall | (
read(high) << 8)) ^ 0xffff;
928 uint16_t ya =
A | (
Y << 8);
929 int result = ya + value + 1;
930 PSW.
V = (ya & 0x8000) == (value & 0x8000) &&
931 (value & 0x8000) != (result & 0x8000);
932 PSW.
H = ((ya & 0xfff) + (value & 0xfff) + 1) > 0xfff;
933 PSW.
C = result > 0xffff;
934 PSW.
Z = (result & 0xffff) == 0;
935 PSW.
N = result & 0x8000;
960 for (
int i = 0;
i < 10;
i++)
962 PSW.
H = (
X & 0xf) <= (
Y & 0xf);
963 int yva = (
Y << 8) |
A;
965 for (
int i = 0;
i < 9;
i++) {
967 yva |= (yva & 0x20000) ? 1 : 0;
987 A = (
A >> 4) | (
A << 4);
1020 uint16_t dst =
dp_dp(&src);
1076 uint16_t dst =
dp_imm(&src);
1088 uint16_t high =
dp_word(&low);
1089 uint8_t vall =
read(low);
1091 uint16_t val = vall | (
read(high) << 8);
1095 PSW.
N = val & 0x8000;
1118 if (
A > 0x99 || !
PSW.
C) {
1122 if ((
A & 0xf) > 9 || !
PSW.
H) {
1144 uint16_t
adr =
dp();
1171 uint8_t result = (
read(
adr) & (~(1 << bit))) | (
PSW.
C << bit);
1199 for (
int i = 0;
i < 7;
i++)
1201 uint16_t result =
A *
Y;
1243 uint16_t high =
dp_word(&low);
1268 uint8_t val =
read(
dpx()) ^ 0xff;
1270 uint8_t result =
A + val + 1;
1277 if (
A > 0x99 ||
PSW.
C) {
1281 if ((
A & 0xf) > 9 ||
PSW.
H) {
1367 static int sleep_log = 0;
1368 if (sleep_log++ < 5) {
1369 LOG_DEBUG(
"SPC",
"SLEEP executed at PC=$%04X - entering low power mode",
1373 for (
int i = 0;
i < 4; ++
i)
1407 uint16_t dst =
dp_dp(&val);
1422 static int incy_log = 0;
1423 if (
PC >= 0xFFE4 &&
PC <= 0xFFE6 && incy_log++ < 10) {
1425 "INC Y executed at PC=$%04X: Y changed from $%02X to $%02X "
1453 throw std::runtime_error(
"Unknown SPC opcode: " + std::to_string(
opcode));
1461 std::stringstream ss;
1462 ss <<
"$" << std::hex << std::setw(4) << std::setfill(
'0') << initial_pc
1463 <<
": 0x" << std::setw(2) << std::setfill(
'0') <<
static_cast<int>(
opcode)
1464 <<
" " << mnemonic <<
" A:" << std::setw(2) << std::setfill(
'0')
1465 << std::hex << static_cast<int>(
A) <<
" X:" << std::setw(2)
1466 << std::setfill(
'0') << std::hex << static_cast<int>(
X)
1467 <<
" Y:" << std::setw(2) << std::setfill(
'0') << std::hex
1468 <<
static_cast<int>(
Y);
1478 stream.write(
reinterpret_cast<const char*
>(&
opcode),
sizeof(
opcode));
1479 stream.write(
reinterpret_cast<const char*
>(&
step),
sizeof(
step));
1480 stream.write(
reinterpret_cast<const char*
>(&
bstep),
sizeof(
bstep));
1481 stream.write(
reinterpret_cast<const char*
>(&
adr),
sizeof(
adr));
1482 stream.write(
reinterpret_cast<const char*
>(&
adr1),
sizeof(
adr1));
1483 stream.write(
reinterpret_cast<const char*
>(&
dat),
sizeof(
dat));
1484 stream.write(
reinterpret_cast<const char*
>(&
dat16),
sizeof(
dat16));
1485 stream.write(
reinterpret_cast<const char*
>(&
param),
sizeof(
param));
1489 stream.write(
reinterpret_cast<const char*
>(&
A),
sizeof(
A));
1490 stream.write(
reinterpret_cast<const char*
>(&
X),
sizeof(
X));
1491 stream.write(
reinterpret_cast<const char*
>(&
Y),
sizeof(
Y));
1492 stream.write(
reinterpret_cast<const char*
>(&
YA),
sizeof(
YA));
1493 stream.write(
reinterpret_cast<const char*
>(&
PC),
sizeof(
PC));
1494 stream.write(
reinterpret_cast<const char*
>(&
SP),
sizeof(
SP));
1495 stream.write(
reinterpret_cast<const char*
>(&
PSW),
sizeof(
PSW));
1502 stream.read(
reinterpret_cast<char*
>(&
opcode),
sizeof(
opcode));
1503 stream.read(
reinterpret_cast<char*
>(&
step),
sizeof(
step));
1504 stream.read(
reinterpret_cast<char*
>(&
bstep),
sizeof(
bstep));
1505 stream.read(
reinterpret_cast<char*
>(&
adr),
sizeof(
adr));
1506 stream.read(
reinterpret_cast<char*
>(&
adr1),
sizeof(
adr1));
1507 stream.read(
reinterpret_cast<char*
>(&
dat),
sizeof(
dat));
1508 stream.read(
reinterpret_cast<char*
>(&
dat16),
sizeof(
dat16));
1509 stream.read(
reinterpret_cast<char*
>(&
param),
sizeof(
param));
1513 stream.read(
reinterpret_cast<char*
>(&
A),
sizeof(
A));
1514 stream.read(
reinterpret_cast<char*
>(&
X),
sizeof(
X));
1515 stream.read(
reinterpret_cast<char*
>(&
Y),
sizeof(
Y));
1516 stream.read(
reinterpret_cast<char*
>(&
YA),
sizeof(
YA));
1517 stream.read(
reinterpret_cast<char*
>(&
PC),
sizeof(
PC));
1518 stream.read(
reinterpret_cast<char*
>(&
SP),
sizeof(
SP));
1519 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