44 uint8_t lo =
read(0xfffe);
45 uint8_t hi =
read(0xffff);
64 int cycles = spc700_accurate_cycles[
opcode];
75 static int entry_log = 0;
76 if ((
PC >= 0xFFF0 &&
PC <= 0xFFFF) && entry_log++ < 5) {
103 static int spc_exec_count = 0;
104 bool in_critical_range = (
PC >= 0xFFCF &&
PC <= 0xFFFF);
105 bool is_transfer_loop = (
PC >= 0xFFD6 &&
PC <= 0xFFED);
108 if (in_critical_range && spc_exec_count++ < 5) {
111 if (is_transfer_loop && spc_exec_count < 10) {
116 LOG_DEBUG(
"SPC",
"TRANSFER LOOP: PC=$%04X Y=%02X A=%02X F4=%02X F5=%02X RAM0=%02X bstep=%d",
117 PC,
Y,
A, f4_val, f5_val, ram0_val,
bstep);
126 if (spc_exec_count < 5) {
138 static int exec_log = 0;
139 if ((
PC >= 0xFFF0 &&
PC <= 0xFFFF) && exec_log++ < 5) {
145 static int reset_log = 0;
148 if ((
PC >= 0xFFF0 &&
PC <= 0xFFFF) && reset_log++ < 5) {
153 if ((
PC >= 0xFFF0 &&
PC <= 0xFFFF) && reset_log++ < 5) {
187 uint16_t
adr = 0xffde - (2 * (
opcode >> 4));
264 uint16_t dst =
dp_dp(&src);
293 uint8_t result =
A + (val ^ 0xff) + 1;
294 PSW.
Z = (result == 0);
295 PSW.
N = (result & 0x80);
331 uint16_t dst =
dp_imm(&src);
344 uint16_t value =
read(low) - 1;
345 write(low, value & 0xff);
346 value +=
read(high) << 8;
347 write(high, value >> 8);
349 PSW.
N = value & 0x8000;
408 uint16_t dst =
dp_dp(&src);
434 uint8_t val =
read(
dp()) ^ 0xff;
436 uint8_t result =
A + val + 1;
466 uint16_t dst =
dp_imm(&src);
479 uint16_t value =
read(low) + 1;
480 write(low, value & 0xff);
481 value +=
read(high) << 8;
482 write(high, value >> 8);
484 PSW.
N = value & 0x8000;
493 bool newC =
A & 0x80;
547 uint16_t dst =
dp_dp(&src);
575 uint8_t result =
A + (val ^ 0xff) + 1;
576 PSW.
Z = (result == 0);
577 PSW.
N = (result & 0x80);
611 uint16_t dst =
dp_imm(&src);
624 uint16_t value =
read_word(low) ^ 0xffff;
625 uint16_t ya =
A | (
Y << 8);
626 int result = ya + value + 1;
627 PSW.
C = result > 0xffff;
628 PSW.
Z = (result & 0xffff) == 0;
629 PSW.
N = result & 0x8000;
686 uint16_t dst =
dp_dp(&src);
712 uint8_t result =
read(
adr) - 1;
749 int result = val -
imm;
751 PSW.
Z = (result == 0);
752 PSW.
N = (result & 0x80);
764 uint8_t vall =
read(low);
766 uint16_t value = vall | (
read(high) << 8);
767 uint16_t ya =
A | (
Y << 8);
768 int result = ya + value;
769 PSW.
V = (ya & 0x8000) == (value & 0x8000) &&
770 (value & 0x8000) != (result & 0x8000);
771 PSW.
H = ((ya & 0xfff) + (value & 0xfff)) > 0xfff;
772 PSW.
C = result > 0xffff;
773 PSW.
Z = (result & 0xffff) == 0;
774 PSW.
N = result & 0x8000;
786 A = (
A >> 1) | (
PSW.
C << 7);
837 uint16_t dst =
dp_dp(&src);
868 uint16_t dst =
dp_imm(&val);
895 uint16_t dst =
dp_imm(&src);
908 uint8_t vall =
read(low);
910 uint16_t value = (vall | (
read(high) << 8)) ^ 0xffff;
911 uint16_t ya =
A | (
Y << 8);
912 int result = ya + value + 1;
913 PSW.
V = (ya & 0x8000) == (value & 0x8000) &&
914 (value & 0x8000) != (result & 0x8000);
915 PSW.
H = ((ya & 0xfff) + (value & 0xfff) + 1) > 0xfff;
916 PSW.
C = result > 0xffff;
917 PSW.
Z = (result & 0xffff) == 0;
918 PSW.
N = result & 0x8000;
944 PSW.
H = (
X & 0xf) <= (
Y & 0xf);
945 int yva = (
Y << 8) |
A;
947 for (
int i = 0;
i < 9;
i++) {
949 yva |= (yva & 0x20000) ? 1 : 0;
951 if (yva >= x) yva ^= 1;
952 if (yva & 1) yva -= x;
967 A = (
A >> 4) | (
A << 4);
1000 uint16_t dst =
dp_dp(&src);
1056 uint16_t dst =
dp_imm(&src);
1068 uint16_t high =
dp_word(&low);
1069 uint8_t vall =
read(low);
1071 uint16_t val = vall | (
read(high) << 8);
1075 PSW.
N = val & 0x8000;
1098 if (
A > 0x99 || !
PSW.
C) {
1102 if ((
A & 0xf) > 9 || !
PSW.
H) {
1124 uint16_t
adr =
dp();
1151 uint8_t result = (
read(
adr) & (~(1 << bit))) | (
PSW.
C << bit);
1180 uint16_t result =
A *
Y;
1221 uint16_t high =
dp_word(&low);
1246 uint8_t val =
read(
dpx()) ^ 0xff;
1248 uint8_t result =
A + val + 1;
1255 if (
A > 0x99 ||
PSW.
C) {
1259 if ((
A & 0xf) > 9 ||
PSW.
H) {
1345 static int sleep_log = 0;
1346 if (sleep_log++ < 5) {
1347 LOG_DEBUG(
"SPC",
"SLEEP executed at PC=$%04X - entering low power mode",
PC - 1);
1383 uint16_t dst =
dp_dp(&val);
1398 static int incy_log = 0;
1399 if (
PC >= 0xFFE4 &&
PC <= 0xFFE6 && incy_log++ < 10) {
1400 LOG_DEBUG(
"SPC",
"INC Y executed at PC=$%04X: Y changed from $%02X to $%02X (Z=%d N=%d)",
1427 throw std::runtime_error(
"Unknown SPC opcode: " + std::to_string(
opcode));
1435 std::stringstream ss;
1436 ss <<
"$" << std::hex << std::setw(4) << std::setfill(
'0') << initial_pc
1437 <<
": 0x" << std::setw(2) << std::setfill(
'0')
1438 <<
static_cast<int>(
opcode) <<
" " << mnemonic
1439 <<
" A:" << std::setw(2) << std::setfill(
'0') << std::hex
1440 <<
static_cast<int>(
A)
1441 <<
" X:" << std::setw(2) << std::setfill(
'0') << std::hex
1442 <<
static_cast<int>(
X)
1443 <<
" Y:" << std::setw(2) << std::setfill(
'0') << std::hex
1444 <<
static_cast<int>(
Y);
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 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)
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,...)
Main namespace for the application.
std::function< void(bool)> idle
std::function< uint8_t(uint16_t)> read