summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorleo <leo@azuminha.com>2023-11-20 13:23:48 -0300
committerleo <leo@azuminha.com>2023-11-20 13:23:48 -0300
commit312f231d5d3b4523a5763eb01981885d0a66b8cd (patch)
tree1e7ade8b82f95fc56d12a4e41f16535634042eff
parent3dec06f9af2854969805cc3267a6095158a298dd (diff)
and, asl, enable/disable flags
-rw-r--r--CPU.c47
-rw-r--r--CPU.h14
-rw-r--r--opcode_pc.h19
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