From 312f231d5d3b4523a5763eb01981885d0a66b8cd Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 20 Nov 2023 13:23:48 -0300 Subject: and, asl, enable/disable flags --- CPU.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- CPU.h | 14 ++++++++++++++ opcode_pc.h | 19 ++++++++++++++++++- 3 files changed, 77 insertions(+), 3 deletions(-) diff --git a/CPU.c b/CPU.c index db7948c..b44a84c 100644 --- a/CPU.c +++ b/CPU.c @@ -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; } diff --git a/CPU.h b/CPU.h index 6157914..4600621 100644 --- a/CPU.h +++ b/CPU.h @@ -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 -- cgit v1.2.3