diff options
author | leo <leo@azuminha.com> | 2023-11-20 13:23:48 -0300 |
---|---|---|
committer | leo <leo@azuminha.com> | 2023-11-20 13:23:48 -0300 |
commit | 312f231d5d3b4523a5763eb01981885d0a66b8cd (patch) | |
tree | 1e7ade8b82f95fc56d12a4e41f16535634042eff | |
parent | 3dec06f9af2854969805cc3267a6095158a298dd (diff) |
and, asl, enable/disable flags
-rw-r--r-- | CPU.c | 47 | ||||
-rw-r--r-- | CPU.h | 14 | ||||
-rw-r--r-- | opcode_pc.h | 19 |
3 files changed, 77 insertions, 3 deletions
@@ -129,9 +129,9 @@ uint16_t get_operand_address(struct CPU *cpu, enum adressing_mode mode){ void update_zero_and_negative_flags(struct CPU *cpu, uint8_t result){ if(result == 0) - cpu->status |= 0b00000010; + enable_flag(cpu, ZERO);//cpu->status |= 0b00000010; else - cpu->status &= 0b11111101; + disable_flag(cpu, ZERO);//cpu->status &= 0b11111101; if((result & 0b10000000) != 0) cpu->status |= 0b10000000; @@ -154,6 +154,34 @@ void sta(struct CPU *cpu, enum adressing_mode mode){ mem_write(cpu, addr, cpu->register_a); } +void and(struct CPU *cpu, enum adressing_mode mode){ + 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); +} + +void enable_flag(struct CPU *cpu, uint8_t flag){ + cpu->status |= flag; +} + +void disable_flag(struct CPU *cpu, uint8_t flag){ + cpu->status &= !flag; +} + +void asl(struct CPU *cpu, enum adressing_mode mode){ + uint16_t addr = get_operand_address(cpu, mode); + uint8_t value = mem_read(cpu, addr); + + if(value >> 7 == 1) enable_flag(cpu, CARRY); + else disable_flag(cpu, CARRY); + + value = value << 1; + mem_write(cpu, addr, value); + update_zero_and_negative_flags(cpu, value); +} + void interpret(struct CPU *cpu){ while(1){ @@ -179,6 +207,21 @@ void interpret(struct CPU *cpu){ cpu->register_x++; update_zero_and_negative_flags(cpu, cpu->register_x); break; + case AND: + and(cpu, OPCODE[opcode].mode); + cpu->pc += OPCODE[opcode].bytes - 1; + break; + case ASL: + if(OPCODE[opcode].mode == NoneAddressing){ + uint8_t value = cpu->register_a; + if(value >> 7 == 1) enable_flag(cpu, CARRY); + else disable_flag(cpu, CARRY); + cpu->register_a = value << 1; + update_zero_and_negative_flags(cpu, cpu->register_a); + }else{ + asl(cpu, OPCODE[opcode].mode); + } + cpu->pc += OPCODE[opcode].bytes - 1; default: break; } @@ -1,6 +1,15 @@ #ifndef _CPU #define _CPU +#define CARRY 0b00000001 +#define ZERO 0b00000010 +#define INTERRUPT_DISABLE 0b00000100 +#define DECIMAL_MODE 0b00001000 +#define BREAK 0b00010000 +#define BREAK2 0b00100000 +#define OVERFLOW 0b01000000 +#define NEGATIV 0b10000000 + struct CPU{ uint8_t register_a; uint8_t register_x; @@ -37,5 +46,10 @@ 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); +void and(struct CPU *cpu, enum adressing_mode mode); +void enable_flag(struct CPU *cpu, uint8_t flag); +void disable_flag(struct CPU *cpu, uint8_t flag); +void asl(struct CPU *cpu, enum adressing_mode mode); + #endif
\ No newline at end of file diff --git a/opcode_pc.h b/opcode_pc.h index 8a95db8..7a79bbe 100644 --- a/opcode_pc.h +++ b/opcode_pc.h @@ -9,12 +9,14 @@ enum _INSTRUCTION{ BRK, STA, INX, + AND, + ASL, }; struct _OPCODE{ enum _INSTRUCTION instruction; enum adressing_mode mode; - int bytes; + uint8_t bytes; }OPCODE[0xFF]; void init_opcode_pc(){ @@ -41,6 +43,21 @@ void init_opcode_pc(){ OPCODE[0x91] = (struct _OPCODE){STA, Indirect_Y, 2}; /*INX*/ OPCODE[0xE8] = (struct _OPCODE){INX, NoneAddressing, 1}; + /*AND*/ + OPCODE[0x29] = (struct _OPCODE){AND, Immediate, 2}; + OPCODE[0x25] = (struct _OPCODE){AND, ZeroPage, 2}; + OPCODE[0x35] = (struct _OPCODE){AND, ZeroPage_X, 2}; + OPCODE[0x2D] = (struct _OPCODE){AND, Absolute, 3}; + OPCODE[0x3D] = (struct _OPCODE){AND, Absolute_X, 3}; + OPCODE[0x39] = (struct _OPCODE){AND, Absolute_Y, 3}; + OPCODE[0x21] = (struct _OPCODE){AND, Indirect_X, 2}; + OPCODE[0x31] = (struct _OPCODE){AND, Indirect_Y, 2}; + /*ASL*/ + OPCODE[0x0A] = (struct _OPCODE){ASL, NoneAddressing, 1}; + OPCODE[0x06] = (struct _OPCODE){ASL, ZeroPage, 2}; + OPCODE[0x16] = (struct _OPCODE){ASL, ZeroPage_X, 2}; + OPCODE[0x0E] = (struct _OPCODE){ASL, Absolute, 3}; + OPCODE[0x1E] = (struct _OPCODE){ASL, Absolute_X, 3}; } #endif
\ No newline at end of file |