From b26428cdee50521ae6910959f6bd191ac87e903a Mon Sep 17 00:00:00 2001 From: raxracks Date: Sat, 27 Jan 2024 00:39:48 +1300 Subject: [PATCH] first commit --- Makefile | 7 ++ config.cfg | 9 ++ emulator | Bin 0 -> 25568 bytes emulator.c | 272 ++++++++++++++++++++++++++++++++++++++++++++++++ game.asm | 40 +++++++ hello | Bin 0 -> 9 bytes hello.asm | 4 + hello.o | Bin 0 -> 304 bytes helloworld.nes | Bin 0 -> 24592 bytes implemented.txt | 39 +++++++ include/slibs | 1 + temp.asm | 6 ++ 12 files changed, 378 insertions(+) create mode 100644 Makefile create mode 100644 config.cfg create mode 100755 emulator create mode 100644 emulator.c create mode 100644 game.asm create mode 100644 hello create mode 100644 hello.asm create mode 100644 hello.o create mode 100644 helloworld.nes create mode 100644 implemented.txt create mode 160000 include/slibs create mode 100644 temp.asm diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6b7af56 --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +emulator: emulator.c + gcc emulator.c -o emulator -g -Iinclude +hello: hello.asm + ca65 hello.asm -o hello.o + ld65 hello.o -o hello -C config.cfg +run: hello emulator + ./emulator hello diff --git a/config.cfg b/config.cfg new file mode 100644 index 0000000..4bf3790 --- /dev/null +++ b/config.cfg @@ -0,0 +1,9 @@ +MEMORY { + RAM: start = $0000, size = $4000, type = rw; + ROM: start = $8000, size = $8000, type = ro; +} + +SEGMENTS { + CODE: load = "ROM", type = ro; + DATA: load = "ROM", type = ro; +} diff --git a/emulator b/emulator new file mode 100755 index 0000000000000000000000000000000000000000..b1686aad18dd61d8c9a3e04f0f6b9dcfb12340b5 GIT binary patch literal 25568 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 literal 0 HcmV?d00001 diff --git a/emulator.c b/emulator.c new file mode 100644 index 0000000..3ffe7d5 --- /dev/null +++ b/emulator.c @@ -0,0 +1,272 @@ +#include +#include +#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 + +typedef struct { + uint8_t A; + uint8_t X; + uint8_t Y; + uint8_t SP; + uint8_t P; + uint16_t PC; +} CPU; + +CPU cpu = { 0 }; +uint8_t* memory; + +int main(int argc, char** argv) { + assert(argc > 1); + + sl_string code = { 0 }; + sl_read_file(argv[1], &code); + + memory = malloc(sizeof(uint8_t) * 0xffff); + memcpy(memory + 0x8000, code.data, code.size); + + for(cpu.PC = 0; cpu.PC < code.size; cpu.PC++) { + uint8_t opcode = code.data[cpu.PC]; + uint8_t one = code.data[cpu.PC + 1]; + uint8_t two = code.data[cpu.PC + 2]; + uint16_t word = (two << 8) | one; + + uint8_t h_nib = (opcode >> 4) & 0xF; + uint8_t l_nib = opcode & 0xF; + + printf("%d: 0x%02X (h_nib: 0x%X, l_nib: 0x%X)\n", cpu.PC, opcode, h_nib, l_nib); + + switch(h_nib) { + case 0x8: + switch(l_nib) { + case 0x1: + printf(" ∟ STA ($%02X, X)\n", one); + memory[memory[one + cpu.X]] = cpu.A; + cpu.PC++; + break; + case 0x5: + printf(" ∟ STA $%02X\n", one); + memory[one] = cpu.A; + cpu.PC++; + break; + case 0x6: + printf(" ∟ STX $%02X\n", one); + memory[one] = cpu.X; + cpu.PC++; + break; + case 0xD: + printf(" ∟ STA $%04X\n", word); + memory[word] = cpu.A; + cpu.PC += 2; + break; + case 0xE: + printf(" ∟ STX $%04X\n", word); + memory[word] = cpu.X; + cpu.PC += 2; + break; + } + break; + case 0x9: + switch(l_nib) { + case 0x1: + printf(" ∟ STA ($%02X), Y\n", one); + memory[memory[one] + cpu.Y] = cpu.A; + cpu.PC++; + break; + + case 0x5: + printf(" ∟ STA $%02X, X\n", word); + memory[one + cpu.X] = cpu.A; + cpu.PC++; + break; + case 0x9: + printf(" ∟ STA $%04X, Y\n", word); + memory[word + cpu.Y] = cpu.A; + cpu.PC += 2; + break; + case 0xD: + printf(" ∟ STA $%04X, X\n", word); + memory[word + cpu.X] = cpu.A; + cpu.PC += 2; + break; + } + break; + case 0xA: + switch(l_nib) { + case 0x0: + printf(" ∟ LDY #$%02X\n", one); + cpu.Y = one; + 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); + cpu.PC++; + break; + + case 0x2: + printf(" ∟ LDX #$%02X\n", one); + cpu.X = one; + cpu.PC++; + break; + case 0x4: + printf(" ∟ LDY $%02X\n", one); + cpu.Y = memory[one]; + cpu.PC++; + break; + case 0x5: + printf(" ∟ LDA $%02X\n", one); + cpu.A = memory[one]; + cpu.PC++; + break; + case 0x6: + printf(" ∟ LDX $%02X\n", one); + cpu.X = memory[one]; + cpu.PC++; + break; + case 0x9: + printf(" ∟ LDA #$%02X\n", one); + cpu.A = one; + cpu.PC++; + break; + case 0xC: + printf(" ∟ LDY $%04X\n", word); + cpu.Y = memory[word]; + cpu.PC += 2; + break; + case 0xD: + printf(" ∟ LDA $%04X\n", word); + cpu.A = memory[word]; + cpu.PC += 2; + break; + case 0xE: + printf(" ∟ LDX $%04X\n", word); + cpu.X = memory[word]; + cpu.PC += 2; + break; + } + break; + case 0xB: + switch(l_nib) { + 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); + 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); + 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); + 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); + 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); + cpu.PC++; + 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); + 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); + 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); + cpu.PC += 2; + break; + } + break; + case 0xC: + switch(l_nib) { + case 0x8: + printf(" ∟ INY\n"); + cpu.Y++; + break; + } + break; + case 0xE: + switch(l_nib) { + case 0x6: + printf(" ∟ INC $%02X\n", one); + memory[one]++; + cpu.PC++; + break; + case 0x8: + printf(" ∟ INX\n"); + cpu.X++; + break; + case 0xE: + printf(" ∟ INC $%04X\n", word); + memory[word]++; + cpu.PC += 2; + break; + } + break; + case 0xF: + switch(l_nib) { + case 0x6: + printf(" ∟ INC $%02X, X\n", one); + memory[one + cpu.X]++; + cpu.PC++; + break; + case 0xE: + printf(" ∟ INC $%04X, X\n", word); + memory[word + cpu.X]++; + cpu.PC += 2; + break; + } + break; + default: + printf(" ∟ Unimplemented\n"); + break; + } + } + + printf("CPU State:\n" + "A\t:\t0x%08X\n" + "X\t:\t0x%08X\n" + "Y\t:\t0x%08X\n" + "SP\t:\t0x%08X\n" + "P\t:\t0x%08X\n" + "PC\t:\t0x%016X\n\n" + , cpu.A, cpu.X, cpu.Y, cpu.SP, cpu.P, cpu.PC); + + printf("Memory State:\n"); + for(int i = 0; i < 0xffff; i++) { + if(memory[i] != 0x0) { + printf("0x%04X: 0x%02X (0b%08b)\n", i, memory[i], memory[i]); + } + } + + return 0; +} diff --git a/game.asm b/game.asm new file mode 100644 index 0000000..fd8d92d --- /dev/null +++ b/game.asm @@ -0,0 +1,40 @@ +.segment "CODE" + + .proc main +main: + ; Initialize PPU + LDA #%10000000 ; Set the bit 7 to $2000 to use $2000-$2FFF for nametables + STA $2000 + LDA #%00011110 ; Enable rendering, enable sprites, and make sure background is visible + STA $2001 + + ; Load sprite data into OAM + LDX #0 ; Initialize X register to zero + LDA SpriteData,X ; Load the first byte of sprite data + STA $0200,X ; Store it in the Object Attribute Memory (OAM) + INX ; Increment X to load the next byte + LDA SpriteData,X ; Load the second byte of sprite data (attributes) + STA $0200,X ; Store it in OAM + INX ; Increment X to load the next byte (X position) + LDA SpriteData,X ; Load the third byte of sprite data (X position) + STA $0200,X ; Store it in OAM + + ; Infinite loop + forever: + JMP forever + + .endproc + +.segment "DATA" + +SpriteData: + .byte $00 ; Tile index for the sprite + .byte $20 ; Attributes (palette, flipping, etc.) + .byte $80 ; X position of the sprite + ; Additional sprite data can be added here + +.segment "BSS" + + ; Define uninitialized memory (if needed) + + diff --git a/hello b/hello new file mode 100644 index 0000000000000000000000000000000000000000..a2d7a75a4e215f34cf74aa20323c90adc737673a GIT binary patch literal 9 QcmZ3i9Voo5=1Y&j|E&$>%AU+1fj6i%GN}mAIOh9}Zh(&?;0TBBEu^vzn zNZlzQ2GROZJ`)p@!-ny|a zGXwKK1_eeYHlPw#pfOAgAQliqSwMF|SsXwXBUl#bW}p}tuz>6ZI}T_85HN!XE(Xqw z)SR4ry~N^NiR45xQ-v@iJwpoxT?O~d5{1;{R5Rl=16IA_%&JrtXMY!0wjh5O#}G$m ar{G`~5Q8JiHON1}(cP8BFVx3}fdK$yOeVts literal 0 HcmV?d00001 diff --git a/helloworld.nes b/helloworld.nes new file mode 100644 index 0000000000000000000000000000000000000000..b56f4aed48069f577a399fa7a9ded98d1dc6a713 GIT binary patch literal 24592 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 X{A6CGjLcid5|4oHTX$pPbqD!hr$lYK literal 0 HcmV?d00001 diff --git a/implemented.txt b/implemented.txt new file mode 100644 index 0000000..fa8d60f --- /dev/null +++ b/implemented.txt @@ -0,0 +1,39 @@ +==== LDA (completed) ==== +LDA # +LDA $ (Z) +LDA $ (A) +LDA $, X (Z) +LDA $, X (A) +LDA $, Y (A) +LDA ($, X) +LDA ($), Y + +==== LDX (completed) ==== +LDX # +LDX $ (Z) +LDX $ (A) +LDX $, Y (Z) +LDX $, Y (A) + +==== LDY (completed) ==== +LDY # +LDY $ (Z) +LDY $ (A) +LDY $, X (Z) +LDY $, X (A) + +==== STA (completed) ==== +STA $ (Z) +STA $ (A) +STA $, X (Z) +STA $, X (A) +STA ($, X) +STA ($), Y + +==== INC (completed) ==== +INX +INY +INC $ (Z) +INC $ (A) +INC $, X (Z) +INC $, X (A) diff --git a/include/slibs b/include/slibs new file mode 160000 index 0000000..63edb93 --- /dev/null +++ b/include/slibs @@ -0,0 +1 @@ +Subproject commit 63edb9343b6787883a667b69ece86bde005ab311 diff --git a/temp.asm b/temp.asm new file mode 100644 index 0000000..136b5a0 --- /dev/null +++ b/temp.asm @@ -0,0 +1,6 @@ +LDA hello, X +INX +LDA hello, X + +.DATA +hello: .byte "hello world", 0