diff --git a/emulator b/emulator index bd7e067..bf0dc74 100755 Binary files a/emulator and b/emulator differ diff --git a/emulator.c b/emulator.c index 565ab09..cfff66b 100644 --- a/emulator.c +++ b/emulator.c @@ -3,13 +3,13 @@ #include #include -#define NEGATIVE 1 << 7 -#define OVERFLOW 1 << 6 -#define BREAK 1 << 4 -#define DECIMAL 1 << 3 -#define INTERRUPT 1 << 2 -#define ZERO 1 << 1 -#define CARRY 1 << 0 +uint8_t N = 1 << 7; +uint8_t V = 1 << 6; +uint8_t B = 1 << 4; +uint8_t D = 1 << 3; +uint8_t I = 1 << 2; +uint8_t Z = 1 << 1; +uint8_t C = 1 << 0; typedef struct { uint8_t A; @@ -21,7 +21,23 @@ typedef struct { } CPU; CPU cpu = { 0 }; -uint8_t* memory; +uint8_t* memory; + +void add_flag(uint8_t flag) { + cpu.P |= flag; +} + +void clear_flag(uint8_t flag) { + cpu.P &= ~flag; +} + +void set_flag(uint8_t flag, int condition) { + if(condition == 1) { + add_flag(flag); + } else if(condition == 0) { + clear_flag(flag); + } +} int main(int argc, char** argv) { assert(argc > 1); @@ -44,13 +60,6 @@ int main(int argc, char** argv) { printf("%d: 0x%02X (h_nib: 0x%X, l_nib: 0x%X)\n", cpu.PC, opcode, h_nib, l_nib); switch(h_nib) { - case 0x0: - switch(l_nib) { - case 0x0: - printf("%c", cpu.A); - break; - } - break; case 0x8: switch(l_nib) { case 0x1: @@ -76,6 +85,10 @@ int main(int argc, char** argv) { case 0xA: printf(" ∟ TXA\n"); cpu.A = cpu.X; + + set_flag(N, cpu.A & 0x80 != 0); + set_flag(Z, cpu.A == 0); + break; case 0xC: printf(" ∟ STY $%04X\n", word); @@ -120,6 +133,10 @@ int main(int argc, char** argv) { case 0x8: printf(" ∟ TYA\n"); cpu.A = cpu.Y; + + set_flag(N, cpu.A & 0x80 != 0); + set_flag(Z, cpu.A == 0); + break; case 0x9: printf(" ∟ STA $%04X, Y\n", word); @@ -142,61 +159,108 @@ int main(int argc, char** argv) { case 0x0: printf(" ∟ LDY #$%02X\n", one); cpu.Y = one; + + set_flag(N, cpu.Y & 0x80 != 0); + set_flag(Z, cpu.Y == 0); + cpu.PC++; break; case 0x1: printf(" ∟ LDA ($%02X, X)\n", one); cpu.A = memory[memory[one + cpu.X]]; - printf("addr: %x val: %x\n", memory[one + cpu.X], cpu.A); + + set_flag(N, cpu.A & 0x80 != 0); + set_flag(Z, cpu.A == 0); + cpu.PC++; break; case 0x2: printf(" ∟ LDX #$%02X\n", one); cpu.X = one; + + set_flag(N, cpu.X & 0x80 != 0); + set_flag(Z, cpu.X == 0); + cpu.PC++; break; case 0x4: printf(" ∟ LDY $%02X\n", one); cpu.Y = memory[one]; + + set_flag(N, cpu.Y & 0x80 != 0); + set_flag(Z, cpu.Y == 0); + cpu.PC++; break; case 0x5: printf(" ∟ LDA $%02X\n", one); cpu.A = memory[one]; + + set_flag(N, cpu.A & 0x80 != 0); + set_flag(Z, cpu.A == 0); + cpu.PC++; break; case 0x6: printf(" ∟ LDX $%02X\n", one); cpu.X = memory[one]; + + set_flag(N, cpu.X & 0x80 != 0); + set_flag(Z, cpu.X == 0); + cpu.PC++; break; case 0x8: printf(" ∟ TAY\n"); cpu.Y = cpu.A; + + set_flag(N, cpu.Y & 0x80 != 0); + set_flag(Z, cpu.Y == 0); + break; case 0x9: printf(" ∟ LDA #$%02X\n", one); cpu.A = one; + + set_flag(N, cpu.A & 0x80 != 0); + set_flag(Z, cpu.A == 0); + cpu.PC++; break; case 0xA: printf(" ∟ TAX\n"); cpu.X = cpu.A; + + set_flag(N, cpu.X & 0x80 != 0); + set_flag(Z, cpu.X == 0); + break; case 0xC: printf(" ∟ LDY $%04X\n", word); cpu.Y = memory[word]; + + set_flag(N, cpu.Y & 0x80 != 0); + set_flag(Z, cpu.Y == 0); + cpu.PC += 2; break; case 0xD: printf(" ∟ LDA $%04X\n", word); cpu.A = memory[word]; + + set_flag(N, cpu.A & 0x80 != 0); + set_flag(Z, cpu.A == 0); + cpu.PC += 2; break; case 0xE: printf(" ∟ LDX $%04X\n", word); cpu.X = memory[word]; + + set_flag(N, cpu.X & 0x80 != 0); + set_flag(Z, cpu.X == 0); + cpu.PC += 2; break; } @@ -206,53 +270,81 @@ int main(int argc, char** argv) { case 0x1: printf(" ∟ LDA ($%02X), Y\n", one); cpu.A = memory[memory[one] + cpu.Y]; - printf("addr: %x val: %x\n", memory[one] + cpu.Y, cpu.A); + + set_flag(N, cpu.A & 0x80 != 0); + set_flag(Z, cpu.A == 0); + cpu.PC++; break; case 0x4: printf(" ∟ LDY $%02X, X\n", one); cpu.Y = memory[one + cpu.X]; - printf("addr: %x val: %x\n", one + cpu.X, cpu.Y); + + set_flag(N, cpu.Y & 0x80 != 0); + set_flag(Z, cpu.Y == 0); + cpu.PC++; break; case 0x5: printf(" ∟ LDA $%02X, X\n", one); cpu.A = memory[one + cpu.X]; - printf("addr: %x val: %x\n", one + cpu.X, cpu.A); + + set_flag(N, cpu.A & 0x80 != 0); + set_flag(Z, cpu.A == 0); + cpu.PC++; break; case 0x6: printf(" ∟ LDX $%02X, Y\n", one); cpu.X = memory[one + cpu.Y]; - printf("addr: %x val: %x\n", one + cpu.Y, cpu.X); + + set_flag(N, cpu.X & 0x80 != 0); + set_flag(Z, cpu.X == 0); + cpu.PC++; break; case 0x9: printf(" ∟ LDA $%04X, Y\n", word); cpu.A = memory[word + cpu.Y]; - printf("addr: %x val: %x\n", word + cpu.Y, cpu.A); + + set_flag(N, cpu.A & 0x80 != 0); + set_flag(Z, cpu.A == 0); + cpu.PC++; break; case 0xA: printf("TSX\n"); cpu.X = cpu.SP; + + set_flag(N, cpu.X & 0x80 != 0); + set_flag(Z, cpu.X == 0); + break; case 0xC: printf(" ∟ LDY $%04X, X\n", word); cpu.Y = memory[word + cpu.X]; - printf("addr: %x val: %x\n", word + cpu.X, cpu.Y); + + set_flag(N, cpu.Y & 0x80 != 0); + set_flag(Z, cpu.Y == 0); + cpu.PC += 2; break; case 0xD: printf(" ∟ LDA $%04X, X\n", word); cpu.A = memory[word + cpu.X]; - printf("addr: %x val: %x\n", word + cpu.X, cpu.A); + + set_flag(N, cpu.A & 0x80 != 0); + set_flag(Z, cpu.A == 0); + cpu.PC += 2; break; case 0xE: printf(" ∟ LDX $%04X, Y\n", word); cpu.X = memory[word + cpu.Y]; - printf("addr: %x val: %x\n", word + cpu.Y, cpu.X); + + set_flag(N, cpu.X & 0x80 != 0); + set_flag(Z, cpu.X == 0); + cpu.PC += 2; break; } @@ -262,6 +354,10 @@ int main(int argc, char** argv) { case 0x8: printf(" ∟ INY\n"); cpu.Y++; + + set_flag(N, cpu.Y & 0x80 != 0); + set_flag(Z, cpu.Y == 0); + break; } break; @@ -270,11 +366,19 @@ int main(int argc, char** argv) { case 0x6: printf(" ∟ INC $%02X\n", one); memory[one]++; + + set_flag(N, memory[one] & 0x80 != 0); + set_flag(Z, memory[one] == 0); + cpu.PC++; break; case 0x8: printf(" ∟ INX\n"); cpu.X++; + + set_flag(N, cpu.X & 0x80 != 0); + set_flag(Z, cpu.X == 0); + break; case 0xA: printf(" ∟ NOP\n"); @@ -282,6 +386,10 @@ int main(int argc, char** argv) { case 0xE: printf(" ∟ INC $%04X\n", word); memory[word]++; + + set_flag(N, memory[word] & 0x80 != 0); + set_flag(Z, memory[word] == 0); + cpu.PC += 2; break; } @@ -290,12 +398,22 @@ int main(int argc, char** argv) { switch(l_nib) { case 0x6: printf(" ∟ INC $%02X, X\n", one); - memory[one + cpu.X]++; + uint8_t addr = one + cpu.X; + memory[addr]++; + + set_flag(N, memory[addr] & 0x80 != 0); + set_flag(Z, memory[addr] == 0); + cpu.PC++; break; case 0xE: printf(" ∟ INC $%04X, X\n", word); - memory[word + cpu.X]++; + uint16_t addr = word + cpu.X; + memory[addr]++; + + set_flag(N, memory[addr] & 0x80 != 0); + set_flag(Z, cpu.Y == 0); + cpu.PC += 2; break; } diff --git a/hello b/hello index 91e08f7..a126b35 100644 Binary files a/hello and b/hello differ diff --git a/hello.asm b/hello.asm index d02624e..d442a17 100644 --- a/hello.asm +++ b/hello.asm @@ -1,27 +1,5 @@ -LDX #0 -LDA hello, X -BRK -INX -LDA hello, X -BRK -INX -LDA hello, X -BRK -INX -LDA hello, X -BRK -INX -LDA hello, X -BRK -INX -LDA hello, X -BRK -INX -LDA hello, X -BRK -INX -LDA hello, X -BRK - -.DATA -hello: .byte "hello\n", 0 +LDY #$10 +LDY #$f9 +LDY #$10 +LDY #$0 +LDY #$ff diff --git a/hello.o b/hello.o index 2858793..aab3117 100644 Binary files a/hello.o and b/hello.o differ diff --git a/implemented.txt b/implemented.txt index d704d1d..194e95b 100644 --- a/implemented.txt +++ b/implemented.txt @@ -1,23 +1,23 @@ ==== LDA (completed) ==== LDA # -LDA $ (Z) +- LDA $ (Z) LDA $ (A) LDA $, X (Z) LDA $, X (A) LDA $, Y (A) -LDA ($, X) +- LDA ($, X) LDA ($), Y ==== LDX (completed) ==== -LDX # -LDX $ (Z) +- LDX # +- LDX $ (Z) LDX $ (A) LDX $, Y (Z) LDX $, Y (A) ==== LDY (completed) ==== -LDY # -LDY $ (Z) +- LDY # +- LDY $ (Z) LDY $ (A) LDY $, X (Z) LDY $, X (A)