From 3dec06f9af2854969805cc3267a6095158a298dd Mon Sep 17 00:00:00 2001 From: leo Date: Sun, 19 Nov 2023 21:36:31 -0300 Subject: opcodes de maneira mais simples --- CPU.c | 72 ++++++++++++++++--------------------------------------------- CPU.h | 41 +++++++++++++++++++++++++++++++++++ opcode_pc.h | 46 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 53 deletions(-) create mode 100644 CPU.h create mode 100644 opcode_pc.h diff --git a/CPU.c b/CPU.c index 75178b3..db7948c 100644 --- a/CPU.c +++ b/CPU.c @@ -2,41 +2,8 @@ #include #include #include - -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); -void mem_write(struct CPU *cpu, uint16_t addr, uint8_t data); -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, 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); +#include "CPU.h" +#include "opcode_pc.h" struct CPU create_cpu(){ struct CPU cpu = { @@ -182,38 +149,35 @@ void lda(struct CPU *cpu, enum adressing_mode mode/*uint8_t value*/){ // update_zero_and_negative_flags(cpu, cpu->register_a); } +void sta(struct CPU *cpu, enum adressing_mode mode){ + uint16_t addr = get_operand_address(cpu, mode); + mem_write(cpu, addr, cpu->register_a); +} + void interpret(struct CPU *cpu){ while(1){ uint8_t opcode = mem_read(cpu, cpu->pc); cpu->pc += 1; - switch(opcode){ - case 0x00: + switch(OPCODE[opcode].instruction){ + case BRK: return; - case 0xAA: + case TAX: cpu->register_x = cpu->register_a; update_zero_and_negative_flags(cpu, cpu->register_x); - break; - case 0xA9: - lda(cpu, Immediate); - //uint8_t param = mem_read(cpu, cpu->pc); - cpu->pc += 1; - //lda(cpu, param); - + case LDA: + lda(cpu, OPCODE[opcode].mode); + cpu->pc += OPCODE[opcode].bytes - 1; break; - case 0xA5: - lda(cpu, ZeroPage); - cpu->pc += 1; + case STA: + sta(cpu, OPCODE[opcode].mode); + cpu->pc += OPCODE[opcode].bytes - 1; break; - case 0xAD: - lda(cpu, Absolute); - cpu->pc += 2; - case 0xE8: + case INX: cpu->register_x++; update_zero_and_negative_flags(cpu, cpu->register_x); - break; default: break; @@ -224,6 +188,8 @@ void interpret(struct CPU *cpu){ } int main(){ + init_opcode_pc(); + printf("test_0xa9_lda_immediate_load_data: "); struct CPU cpu_1 = create_cpu(); uint8_t program_1[] = {0xa9, 0x05, 0x00}; diff --git a/CPU.h b/CPU.h new file mode 100644 index 0000000..6157914 --- /dev/null +++ b/CPU.h @@ -0,0 +1,41 @@ +#ifndef _CPU +#define _CPU + +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); +void mem_write(struct CPU *cpu, uint16_t addr, uint8_t data); +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, 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); + +#endif \ No newline at end of file diff --git a/opcode_pc.h b/opcode_pc.h new file mode 100644 index 0000000..8a95db8 --- /dev/null +++ b/opcode_pc.h @@ -0,0 +1,46 @@ +#ifndef _OPCODEPC +#define _OPCODEPC +#include "CPU.h" + +enum _INSTRUCTION{ + ADC = 1, + LDA, + TAX, + BRK, + STA, + INX, +}; + +struct _OPCODE{ + enum _INSTRUCTION instruction; + enum adressing_mode mode; + int bytes; +}OPCODE[0xFF]; + +void init_opcode_pc(){ + /*LDA*/ + OPCODE[0xA9] = (struct _OPCODE){LDA, Immediate, 2}; + OPCODE[0xA5] = (struct _OPCODE){LDA, ZeroPage, 2}; + OPCODE[0xB5] = (struct _OPCODE){LDA, ZeroPage_X, 2}; + OPCODE[0XAD] = (struct _OPCODE){LDA, Absolute, 3}; + OPCODE[0xBD] = (struct _OPCODE){LDA, Absolute_X, 3}; + OPCODE[0xB9] = (struct _OPCODE){LDA, Absolute_Y, 3}; + OPCODE[0xA1] = (struct _OPCODE){LDA, Indirect_X, 2}; + OPCODE[0xB1] = (struct _OPCODE){LDA, Indirect_Y, 2}; + /*BRK*/ + OPCODE[0x00] = (struct _OPCODE){BRK, NoneAddressing, 1}; + /*TAX*/ + OPCODE[0xAA] = (struct _OPCODE){TAX, NoneAddressing, 1}; + /*STA*/ + OPCODE[0x85] = (struct _OPCODE){STA, ZeroPage, 2}; + OPCODE[0x95] = (struct _OPCODE){STA, ZeroPage_X, 2}; + OPCODE[0x8D] = (struct _OPCODE){STA, Absolute, 3}; + OPCODE[0x9D] = (struct _OPCODE){STA, Absolute_X, 3}; + OPCODE[0x99] = (struct _OPCODE){STA, Absolute_Y, 3}; + OPCODE[0x81] = (struct _OPCODE){STA, Indirect_X, 2}; + OPCODE[0x91] = (struct _OPCODE){STA, Indirect_Y, 2}; + /*INX*/ + OPCODE[0xE8] = (struct _OPCODE){INX, NoneAddressing, 1}; +} + +#endif \ No newline at end of file -- cgit v1.2.3