aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cpu/chip.rs131
1 files changed, 104 insertions, 27 deletions
diff --git a/src/cpu/chip.rs b/src/cpu/chip.rs
index b31dd82..7b62a24 100644
--- a/src/cpu/chip.rs
+++ b/src/cpu/chip.rs
@@ -93,7 +93,7 @@ impl Chip {
_ => { }
};
}
- pub fn read_memory(&self, pc: usize) -> u8 {
+ pub fn read_memory(&self, pc: u16) -> u8 {
let address = match pc {
0x0000..=0x3fff => { println!("ROM Bank 0"); self.rom_bank_0[pc as usize] }, //Fixed bank, rom_bank_0
0x4000..=0x7fff => { println!("ROM Bank 1"); self.rom_bank_n[pc as usize - 0x4000] },
@@ -110,9 +110,9 @@ impl Chip {
address
}
pub fn fetch(&mut self) {
- self.instr = self.read_memory(self.pc as usize);
- let arg1 = self.read_memory(self.pc as usize + 1);
- let arg2 = self.read_memory(self.pc as usize + 2);
+ self.instr = self.read_memory(self.pc);
+ let arg1 = self.read_memory(self.pc + 1);
+ let arg2 = self.read_memory(self.pc + 2);
self.byte2 = arg1;
self.byte3 = arg2;
println!("Instr: 0x{:02X}", self.instr);
@@ -137,6 +137,37 @@ impl Chip {
}
}
+
+ fn get_r8_register(&mut self, register_code: u8) -> u8 {
+ match register_code {
+ 0 => { self.b },
+ 1 => { self.c },
+ 2 => { self.d },
+ 3 => { self.e },
+ 4 => { self.h },
+ 5 => { self.l },
+ 6 => { let memory_address = self.get_r16_register_memory_address(0b101); self.read_memory(memory_address) }, //[HL]
+ 7 => { self.a },
+ _ => { panic!("Cannot get register code: Unknown register code {}", register_code) }
+
+ }
+ }
+
+ fn set_r8_register(&mut self, register_code: u8, value: u8) {
+ match register_code {
+ 0 => { self.b = value },
+ 1 => { self.c = value },
+ 2 => { self.d = value },
+ 3 => { self.e = value },
+ 4 => { self.h = value },
+ 5 => { self.l = value },
+ 6 => { let memory_address = self.get_r16_register_memory_address(0b101); self.write_memory(memory_address, value) }, //[HL]
+ 7 => { self.a = value },
+ _ => { panic!("Cannot get register code: Unknown register code {}", register_code) }
+
+ }
+ }
+
// Write a 16 bit value to a pair of registers based on the usual pairing
fn set_r16_register_address(&mut self, register_code: u8, value: u16) {
let high = (value >> 8) as u8;
@@ -182,20 +213,20 @@ impl Chip {
match (oct1, oct2, oct3) {
(0b11, 0b001, 0b001) => { }, //CB-prefixed instructions
(0b00, 0b000, 0b000) => { println!("NOOP") }, //noop
- (0b00, 0b001, 0b000) => { self.ld_xx_sp() }, //LD (u16), SP
+ (0b00, 0b001, 0b000) => { self.ld_u16_sp() }, //LD (u16), SP
(0b00, 0b010, 0b000) => { println!("STOP") }, //STOP
(0b00, 0b011, 0b000) => { self.jr() }, //JR
(0b00, 0b100..=0b111, 0b000) => { self.jr_cond(oct2) }, //JR conditonal
- (0b00,0b000|0b010|0b100|0b110, 0b001) => { self.ld_nn_rr(oct2) }, //LD r16, u16
- (0b00,0b001|0b011|0b101|0b111, 0b001) => { self.add_hl_rr(oct2) }, //ADD HL, r16
+ (0b00,0b000|0b010|0b100|0b110, 0b001) => { self.ld_r16_u16(oct2) }, //LD r16, u16
+ (0b00,0b001|0b011|0b101|0b111, 0b001) => { self.add_hl_r16(oct2) }, //ADD HL, r16
(0b00,0b000|0b010|0b100|0b110, 0b010) => { self.ld_r16_addr_a(oct2) }, //LD (r16), A
- (0b00,0b001|0b011|0b101|0b111, 0b010) => { }, //LD A, (r16)
- (0b00,0b000|0b010|0b100|0b110, 0b011) => { }, //INC r16
- (0b00,0b001|0b011|0b101|0b111, 0b011) => { }, //DEC r16
- (0b00, r8, 0b100) => { }, //INC r8
- (0b00, r8, 0b101) => { }, //DEC r8
- (0b00, r8, 0b110) => { }, //LD r8, u8
- (0b00, opcode, 0b111) => { }, //Opcode grp 1
+ (0b00,0b001|0b011|0b101|0b111, 0b010) => { self.ld_a_r16_addr(oct2) }, //LD A, (r16)
+ (0b00,0b000|0b010|0b100|0b110, 0b011) => { self.inc_r16(oct2) }, //INC r16
+ (0b00,0b001|0b011|0b101|0b111, 0b011) => { self.dec_r16(oct2) }, //DEC r16
+ (0b00, r8, 0b100) => { self.inc_r8(r8) }, //INC r8
+ (0b00, r8, 0b101) => { self.dec_r8(r8) }, //DEC r8
+ (0b00, r8, 0b110) => { self.ld_r8_n8(r8) }, //LD r8, u8
+ (0b00, opcode, 0b111) => { self.special_opcodes(opcode) }, //Opcode grp 1
(0b01, 0b110, 0b110) => { }, //HALT
(0b01, src_r8, dst_r8) => { }, //LD r8, r8
(0b10, op, r8) => { self.alu_a_r8(op, r8); }, //ALU A, r8
@@ -232,34 +263,80 @@ impl Chip {
}
+ //TODO
+ fn special_opcodes(&mut self, opcode: u8) {
+ }
+
+ fn ld_r8_n8(&mut self, r8: u8) {
+ self.set_r8_register(r8, self.byte2);
+ }
+
+
+ //Increment value in register r8 by 1
+ fn inc_r8(&mut self, register_lookup: u8) {
+ let register = self.get_r8_register(register_lookup);
+ let sum = register.wrapping_add(1);
+ if sum == 0 { self.flags.zero = 0 }
+ self.flags.n = 0;
+ if ((0xf & register).wrapping_add(0xf & 1)) & 0x10 == 0x10 { self.flags.h = 1 }
+ self.set_r8_register(register_lookup, sum);
+ }
+
+ //Decrement value in register r8 by 1
+ fn dec_r8(&mut self, register_lookup: u8) {
+ let register = self.get_r8_register(register_lookup);
+ let sum = register.wrapping_sub(1);
+ if sum == 0 { self.flags.zero = 0 }
+ self.flags.n = 1;
+ if ((0xf & register).wrapping_sub(0xf & 1)) & 0x10 == 0x10 { self.flags.h = 1 }
+ self.set_r8_register(register_lookup, sum);
+ }
+
+ //Increment value in register r16 by 1
+ fn inc_r16(&mut self, register_lookup: u8) {
+ let mut register = self.get_r16_register_address(register_lookup);
+ register = register.wrapping_add(1);
+ self.set_r16_register_address(register_lookup, register);
+ }
+
+ //Decrement value in register r16 by 1
+ fn dec_r16(&mut self, register_lookup: u8) {
+ let mut register = self.get_r16_register_address(register_lookup);
+ register = register.wrapping_sub(1);
+ self.set_r16_register_address(register_lookup, register);
+ }
+
+ //Load value pointed in memory by r16 register pair into register A
+ fn ld_a_r16_addr(&mut self, register_lookup: u8) {
+ let memory_address = self.get_r16_register_memory_address(register_lookup);
+ self.a = self.read_memory(memory_address);
+ }
// Load the 8 bit value in register A to the memory address pointed by the register from the
// table
- fn ld_r16_addr_a(&mut self, register: u8) {
- let memory_address = self.get_r16_register_memory_address(register);
+ fn ld_r16_addr_a(&mut self, register_lookup: u8) {
+ let memory_address = self.get_r16_register_memory_address(register_lookup);
self.write_memory(memory_address, self.a);
}
//Add register r16 value to HL
- fn add_hl_rr(&mut self, register: u8) {
- let r16 = self.get_r16_register_address(register);
+ fn add_hl_r16(&mut self, register_lookup: u8) {
+ let r16 = self.get_r16_register_address(register_lookup);
let hl = self.get_r16_register_address(0b101); //0b101 == HL register pair
let (sum, overflow_high) = r16.overflowing_add(hl);
- self.h = (sum >> 8) as u8;
- self.l = (sum & 0xff) as u8;
+ self.set_r16_register_address(0b101, sum);
//Additions reset the n flag
self.flags.n = 0;
//Check 11th to 12th bit overflow
- self.flags.h = (r16 & 0xfff).overflowing_add(hl & 0xfff).1 as u8;
+ if (r16 & 0xfff).overflowing_add(hl & 0xfff).1 as u8 == 1 { self.flags.h = 1 };
//Check 15th to 16th bit overflow
- self.flags.carry = overflow_high as u8;
-
+ if overflow_high { self.flags.carry = overflow_high as u8 };
}
//Load value u16 into register r16
- fn ld_nn_rr(&mut self, register: u8) {
+ fn ld_r16_u16(&mut self, register_lookup: u8) {
let address = (self.byte2 as u16) << 8 | self.byte3 as u16;
- self.set_r16_register_address(register, address);
+ self.set_r16_register_address(register_lookup, address);
}
//Conditional Jump
@@ -285,7 +362,7 @@ impl Chip {
}
//Store SP lower at address u16, and SP upper at address u16 + 1
- fn ld_xx_sp(&mut self) {
+ fn ld_u16_sp(&mut self) {
let address: u16 = (self.byte2 as u16) << 8 | self.byte3 as u16;
self.write_memory(address, (self.sp & 0xff) as u8);
self.write_memory(address + 1, (self.sp >> 8) as u8);
@@ -328,7 +405,7 @@ impl Chip {
5 => { self.l },
6 => {
let ptr = ((self.h as u16) << 8) as u16 | self.l as u16;
- self.read_memory(ptr as usize)
+ self.read_memory(ptr)
},
7 => { self.a },
_ => { panic!("Wrong register read for XOR_R") }