From 6b1e55697c2fefe8215b64b1ff49ac447065eadc Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 31 Oct 2023 22:16:59 -0300 Subject: nao sei oq adicionei --- CPU.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 4 deletions(-) diff --git a/CPU.c b/CPU.c index de8a0a7..75178b3 100644 --- a/CPU.c +++ b/CPU.c @@ -6,11 +6,25 @@ struct CPU{ uint8_t register_a; uint8_t register_x; + uint8_t register_y; uint8_t status; uint16_t pc; uint8_t memory[0xFFFF]; }; +enum adressing_mode{ + Immediate = 1, + ZeroPage, + ZeroPage_X, + ZeroPage_Y, + Absolute, + Absolute_X, + Absolute_Y, + Indirect_X, + Indirect_Y, + NoneAddressing, +}; + struct CPU create_cpu(); int array_size(uint8_t *program); uint8_t mem_read(struct CPU *cpu, uint16_t addr); @@ -19,14 +33,16 @@ void load(struct CPU *cpu, uint8_t *program); void load_and_run(struct CPU *cpu, uint8_t *program); void reset_cpu(struct CPU *cpu); void update_zero_and_negative_flags(struct CPU *cpu, uint8_t result); -void lda(struct CPU *cpu, uint8_t value); +void lda(struct CPU *cpu, enum adressing_mode mode); void interpret(struct CPU *cpu); uint16_t mem_read_u16(struct CPU *cpu, uint16_t pos); +uint16_t get_operand_address(struct CPU *cpu, enum adressing_mode mode); struct CPU create_cpu(){ struct CPU cpu = { .register_a = 0, .register_x = 0, + .register_y = 0, .status = 0, .pc = 0 }; @@ -79,6 +95,71 @@ void reset_cpu(struct CPU *cpu){ (*cpu).pc = mem_read_u16(cpu, 0xfffc); } +uint16_t get_operand_address(struct CPU *cpu, enum adressing_mode mode){ + switch(mode){ + case Immediate: + return cpu->pc; + case ZeroPage: + return (uint16_t)mem_read(cpu, cpu->pc); + + case Absolute: + return mem_read_u16(cpu, cpu->pc); + + case ZeroPage_X: + { + uint8_t pos = mem_read(cpu, cpu->pc); + uint16_t addr = (pos + cpu->register_x) % 0x100; + return addr; + } + + case ZeroPage_Y: + { + uint8_t pos = mem_read(cpu, cpu->pc); + uint16_t addr = (pos + cpu->register_y) % 0x100; + return addr; + } + + case Absolute_X: + { + uint16_t pos = mem_read_u16(cpu, cpu->pc); + uint16_t addr = (pos + (uint16_t)cpu->register_x) % 0x10000; + return addr; + } + + case Absolute_Y: + { + uint16_t pos = mem_read_u16(cpu, cpu->pc); + uint16_t addr = (pos + (uint16_t)cpu->register_y) % 0x10000; + return addr; + } + + case Indirect_X: + { + uint8_t pos = mem_read(cpu, cpu->pc); + + uint8_t ptr = (pos + cpu->register_x) % 0x100; + uint8_t lo = mem_read(cpu, (uint16_t)ptr); + uint8_t hi = mem_read(cpu, (uint16_t)((ptr+1) % 0x100)); + return ((uint16_t)hi << 8) | ((uint16_t)lo); + } + + case Indirect_Y: + { + uint8_t pos = mem_read(cpu, cpu->pc); + + uint8_t lo = mem_read(cpu, (uint16_t)pos); + uint8_t hi = mem_read(cpu, (uint16_t)((pos+1) % 0x100)); + uint16_t deref_pos = ((uint16_t)hi << 8) | (uint16_t)lo; + uint16_t deref = (deref_pos + (uint16_t)cpu->register_y) % 0x10000; + return deref; + } + + case NoneAddressing: + exit(1); + break; + } +} + void update_zero_and_negative_flags(struct CPU *cpu, uint8_t result){ if(result == 0) cpu->status |= 0b00000010; @@ -91,9 +172,14 @@ void update_zero_and_negative_flags(struct CPU *cpu, uint8_t result){ cpu->status &= 0b01111111; } -void lda(struct CPU *cpu, uint8_t value){ +void lda(struct CPU *cpu, enum adressing_mode mode/*uint8_t value*/){ + uint16_t addr = get_operand_address(cpu, mode); + uint8_t value = mem_read(cpu, addr); + cpu->register_a = value; update_zero_and_negative_flags(cpu, cpu->register_a); + // cpu->register_a = value; + // update_zero_and_negative_flags(cpu, cpu->register_a); } void interpret(struct CPU *cpu){ @@ -111,11 +197,19 @@ void interpret(struct CPU *cpu){ break; case 0xA9: - uint8_t param = mem_read(cpu, cpu->pc); + lda(cpu, Immediate); + //uint8_t param = mem_read(cpu, cpu->pc); cpu->pc += 1; - lda(cpu, param); + //lda(cpu, param); break; + case 0xA5: + lda(cpu, ZeroPage); + cpu->pc += 1; + break; + case 0xAD: + lda(cpu, Absolute); + cpu->pc += 2; case 0xE8: cpu->register_x++; update_zero_and_negative_flags(cpu, cpu->register_x); @@ -166,4 +260,12 @@ int main(){ load_and_run(&cpu_5, program_5); assert(cpu_5.register_x == 1); printf("PASSED\n"); + + printf("test_lda_from_memory: "); + struct CPU cpu_6 = create_cpu(); + mem_write(&cpu_6, 0x10, 0x55); + uint8_t program_6[] = {0xa5, 0x10, 0x00}; + load_and_run(&cpu_6, program_6); + assert(cpu_6.register_a == 0x55); + printf("PASSED\n"); } \ No newline at end of file -- cgit v1.2.3