Even more cleanup

This commit is contained in:
Kevin Hamacher 2016-05-26 20:25:44 +02:00
parent 79d2c99c06
commit 0fdfa9ae63
3 changed files with 151 additions and 244 deletions

View File

@ -8,6 +8,14 @@ const REG_H: usize = 4;
const REG_L: usize = 5; const REG_L: usize = 5;
const REG_A: usize = 6; const REG_A: usize = 6;
const REG_N_B: usize = 0;
const REG_N_C: usize = 1;
const REG_N_D: usize = 2;
const REG_N_E: usize = 3;
const REG_N_H: usize = 4;
const REG_N_L: usize = 5;
const REG_N_HL: usize = 6;
const REG_N_A: usize = 7;
const REG_NAMES: [&'static str; 8] = ["B", "C", "D", "E", "H", "L", "(HL)", "A"]; const REG_NAMES: [&'static str; 8] = ["B", "C", "D", "E", "H", "L", "(HL)", "A"];
const FLAG_Z: u8 = 1 << 7; const FLAG_Z: u8 = 1 << 7;
@ -35,8 +43,6 @@ fn to_u16(bytes: Box<[u8]>) -> u16 {
impl CPU { impl CPU {
pub fn new(interconnect: interconnect::Interconnect) -> CPU { pub fn new(interconnect: interconnect::Interconnect) -> CPU {
// Ugly patch ^.^
// interconnect.write_byte(0xFF44 as u16, 0x90);
CPU { CPU {
flags: 0, flags: 0,
regs: [0, 0, 0, 0, 0, 0, 0], regs: [0, 0, 0, 0, 0, 0, 0],
@ -223,15 +229,49 @@ impl CPU {
} }
} }
fn reg_inc(&mut self, reg_id: usize) { fn push_rr(&mut self, r1: usize, r2: usize) -> u8 {
if self.debug {
println!("PUSH {}{}", REG_NAMES[r1], REG_NAMES[r2]);
}
let val: u16 = self.get_pair_value(r1, r2);
self.push(val);
16
}
fn push(&mut self, val: u16) {
self.interconnect.write_word(self.sp - 2, val);
self.sp -= 2;
}
fn ld_r_r(&mut self, reg_dst: usize, reg_src: usize) -> u8 {
if self.debug {
println!("LD {}, {}", REG_NAMES[reg_dst], REG_NAMES[reg_src])
}
let sv = self.get_8bit_reg(reg_src);
self.set_8bit_reg(reg_dst, sv);
if reg_dst == REG_N_HL || reg_src == REG_N_HL {
8
} else {
4
}
}
fn reg_inc(&mut self, reg_id: usize) -> u8 {
if self.debug {
println!("INC {}", REG_NAMES[reg_id]);
}
self.regs[reg_id] = self.regs[reg_id].wrapping_add(1); self.regs[reg_id] = self.regs[reg_id].wrapping_add(1);
if self.regs[reg_id] == 0 { if self.regs[reg_id] == 0 {
self.flags |= FLAG_Z; self.flags |= FLAG_Z;
} }
self.flags &= !FLAG_N; self.flags &= !FLAG_N;
4
} }
fn reg_dec(&mut self, reg_id: usize) { fn reg_dec(&mut self, reg_id: usize) -> u8 {
if self.debug {
println!("DEC {}", REG_NAMES[reg_id]);
}
self.regs[reg_id] = self.regs[reg_id].wrapping_sub(1); self.regs[reg_id] = self.regs[reg_id].wrapping_sub(1);
if self.regs[reg_id] == 0 { if self.regs[reg_id] == 0 {
self.flags |= FLAG_Z; self.flags |= FLAG_Z;
@ -239,6 +279,7 @@ impl CPU {
self.flags &= !FLAG_Z; self.flags &= !FLAG_Z;
} }
self.flags |= FLAG_N; self.flags |= FLAG_N;
4
} }
fn set_flag(&mut self, flag: u8) { fn set_flag(&mut self, flag: u8) {
@ -268,14 +309,12 @@ impl CPU {
} }
self.ip += 1; self.ip += 1;
let cycles: u16; let cycles: u8 = match instruction {
match instruction {
0x00 => { 0x00 => {
if self.debug { if self.debug {
println!("NOP"); println!("NOP");
} }
cycles = 4; 4
}, },
0x01 => { 0x01 => {
if self.debug { if self.debug {
@ -284,7 +323,7 @@ impl CPU {
let addr: u16 = self.get_pair_value(REG_B, REG_C); let addr: u16 = self.get_pair_value(REG_B, REG_C);
let val: u8 = self.regs[REG_A]; let val: u8 = self.regs[REG_A];
self.interconnect.write_byte(addr, val); self.interconnect.write_byte(addr, val);
cycles = 12; 12
}, },
0x02 => { 0x02 => {
if self.debug { if self.debug {
@ -293,51 +332,27 @@ impl CPU {
let addr: u16 = self.get_pair_value(REG_B, REG_C); let addr: u16 = self.get_pair_value(REG_B, REG_C);
let val: u8 = self.regs[REG_A]; let val: u8 = self.regs[REG_A];
self.interconnect.write_byte(addr, val); self.interconnect.write_byte(addr, val);
cycles = 8; 8
},
0x04 => {
if self.debug{
println!("INC B");
}
self.reg_inc(REG_B);
cycles = 4;
},
0x05 => {
if self.debug {
println!("DEC B");
}
self.reg_dec(REG_B);
cycles = 4;
}, },
0x04 => self.reg_inc(REG_B),
0x05 => self.reg_dec(REG_B),
0x06 => { 0x06 => {
let args = self.load_args(1); let args = self.load_args(1);
if self.debug { if self.debug {
println!("LD B, {:02x}", args[0]); println!("LD B, {:02x}", args[0]);
} }
self.regs[REG_B] = args[0]; self.regs[REG_B] = args[0];
cycles = 8; 8
},
0x0C => {
if self.debug {
println!("INC C");
}
self.reg_inc(REG_C);
cycles = 4;
},
0x0D => {
if self.debug {
println!("DEC C");
}
self.reg_dec(REG_C);
cycles = 4;
}, },
0x0C => self.reg_inc(REG_C),
0x0D => self.reg_dec(REG_C),
0x0E => { 0x0E => {
let args = self.load_args(1); let args = self.load_args(1);
if self.debug { if self.debug {
println!("LD C, {:02x}", args[0]); println!("LD C, {:02x}", args[0]);
} }
self.regs[REG_C] = args[0]; self.regs[REG_C] = args[0];
cycles = 8; 8
}, },
0x11 => { 0x11 => {
let args = self.load_args(2); let args = self.load_args(2);
@ -346,7 +361,7 @@ impl CPU {
println!("LD DE, {:04x}", val); println!("LD DE, {:04x}", val);
} }
self.set_pair_value(REG_D, REG_E, val); self.set_pair_value(REG_D, REG_E, val);
cycles = 12; 12
}, },
0x12 => { 0x12 => {
if self.debug { if self.debug {
@ -355,7 +370,7 @@ impl CPU {
let addr: u16 = self.get_pair_value(REG_D, REG_E); let addr: u16 = self.get_pair_value(REG_D, REG_E);
let val: u8 = self.regs[REG_A]; let val: u8 = self.regs[REG_A];
self.interconnect.write_byte(addr, val); self.interconnect.write_byte(addr, val);
cycles = 12; 12
}, },
0x13 => { 0x13 => {
if self.debug { if self.debug {
@ -363,29 +378,17 @@ impl CPU {
} }
let old_value = self.get_pair_value(REG_D, REG_E); let old_value = self.get_pair_value(REG_D, REG_E);
self.set_pair_value(REG_D, REG_E, old_value + 1); self.set_pair_value(REG_D, REG_E, old_value + 1);
cycles = 8; 8
},
0x14 => {
if self.debug {
println!("INC D");
}
self.reg_inc(REG_D);
cycles = 4;
},
0x15 => {
if self.debug {
println!("DEC D");
}
self.reg_dec(REG_D);
cycles = 4;
}, },
0x14 => self.reg_inc(REG_D),
0x15 => self.reg_dec(REG_D),
0x16 => { 0x16 => {
let args = self.load_args(1); let args = self.load_args(1);
if self.debug { if self.debug {
println!("LD D, {:02x}", args[0]); println!("LD D, {:02x}", args[0]);
} }
self.regs[REG_D] = args[0]; self.regs[REG_D] = args[0];
cycles = 8; 8
}, },
0x17 => { 0x17 => {
if self.debug { if self.debug {
@ -404,7 +407,7 @@ impl CPU {
} }
self.regs[REG_A] = self.regs[REG_A] << 1 | 1; self.regs[REG_A] = self.regs[REG_A] << 1 | 1;
} }
cycles = 4; 4
}, },
0x18 => { 0x18 => {
let args = self.load_args(1); let args = self.load_args(1);
@ -417,36 +420,24 @@ impl CPU {
} else { } else {
self.ip += off as u16; self.ip += off as u16;
} }
cycles = 12; 12
}, },
0x1A => { 0x1A => {
if self.debug { if self.debug {
println!("LD A, (DE)"); println!("LD A, (DE)");
} }
self.regs[REG_A] = self.interconnect.read_byte(self.get_pair_value(REG_D, REG_E)); self.regs[REG_A] = self.interconnect.read_byte(self.get_pair_value(REG_D, REG_E));
cycles = 8; 8
},
0x1C => {
if self.debug {
println!("INC E");
}
self.reg_inc(REG_E);
cycles = 4;
},
0x1D => {
if self.debug {
println!("DEC E");
}
self.reg_dec(REG_E);
cycles = 4;
}, },
0x1C => self.reg_inc(REG_E),
0x1D => self.reg_dec(REG_E),
0x1E => { 0x1E => {
let args = self.load_args(1); let args = self.load_args(1);
if self.debug { if self.debug {
println!("LD E, {:02x}", args[0]); println!("LD E, {:02x}", args[0]);
} }
self.regs[REG_E] = args[0]; self.regs[REG_E] = args[0];
cycles = 8; 8
}, },
0x20 => { 0x20 => {
let args = self.load_args(1); let args = self.load_args(1);
@ -460,9 +451,9 @@ impl CPU {
} else { } else {
self.ip += offset as u16; self.ip += offset as u16;
} }
cycles = 12; 12
} else { } else {
cycles = 8; 8
} }
} }
0x21 => { 0x21 => {
@ -471,7 +462,7 @@ impl CPU {
println!("LD HL, {:04x}", value); println!("LD HL, {:04x}", value);
} }
self.set_pair_value(REG_H, REG_L, value); self.set_pair_value(REG_H, REG_L, value);
cycles = 12; 12
}, },
0x22 => { 0x22 => {
if self.debug { if self.debug {
@ -480,7 +471,7 @@ impl CPU {
let addr: u16 = self.get_pair_value(REG_H, REG_L); let addr: u16 = self.get_pair_value(REG_H, REG_L);
self.interconnect.write_byte(addr, self.regs[REG_A]); self.interconnect.write_byte(addr, self.regs[REG_A]);
self.set_pair_value(REG_H, REG_L, addr + 1); self.set_pair_value(REG_H, REG_L, addr + 1);
cycles = 8; 8
}, },
0x23 => { 0x23 => {
if self.debug { if self.debug {
@ -488,29 +479,17 @@ impl CPU {
} }
let old_value = self.get_pair_value(REG_H, REG_L); let old_value = self.get_pair_value(REG_H, REG_L);
self.set_pair_value(REG_H, REG_L, old_value + 1); self.set_pair_value(REG_H, REG_L, old_value + 1);
cycles = 8; 8
},
0x24 => {
if self.debug {
println!("INC H");
}
self.reg_inc(REG_H);
cycles = 4;
},
0x25 => {
if self.debug {
println!("DEC H");
}
self.reg_dec(REG_H);
cycles = 4;
}, },
0x24 => self.reg_inc(REG_H),
0x25 => self.reg_dec(REG_H),
0x26 => { 0x26 => {
let args = self.load_args(1); let args = self.load_args(1);
if self.debug { if self.debug {
println!("LD H, {:02x}", args[0]); println!("LD H, {:02x}", args[0]);
} }
self.regs[REG_H] = args[0]; self.regs[REG_H] = args[0];
cycles = 8; 8
}, },
0x28 => { 0x28 => {
let args = self.load_args(1); let args = self.load_args(1);
@ -525,9 +504,9 @@ impl CPU {
} }
if self.flags & FLAG_Z > 0 { if self.flags & FLAG_Z > 0 {
self.ip = target; self.ip = target;
cycles = 12; 12
} else { } else {
cycles = 8; 8
} }
}, },
0x2A => { 0x2A => {
@ -536,29 +515,17 @@ impl CPU {
} }
let addr: u16 = self.get_pair_value(REG_H, REG_L); let addr: u16 = self.get_pair_value(REG_H, REG_L);
self.regs[REG_A] = self.interconnect.read_byte(addr); self.regs[REG_A] = self.interconnect.read_byte(addr);
cycles = 8; 8
},
0x2C => {
if self.debug {
println!("INC L");
}
self.reg_inc(REG_L);
cycles = 4;
},
0x2D => {
if self.debug {
println!("DEC L");
}
self.reg_dec(REG_L);
cycles = 4;
}, },
0x2C => self.reg_inc(REG_L),
0x2D => self.reg_dec(REG_L),
0x2E => { 0x2E => {
let args = self.load_args(1); let args = self.load_args(1);
if self.debug { if self.debug {
println!("LD L, {:02x}", args[0]); println!("LD L, {:02x}", args[0]);
} }
self.regs[REG_L] = args[0]; self.regs[REG_L] = args[0];
cycles = 8; 8
}, },
0x31 => { 0x31 => {
let args = self.load_args(2); let args = self.load_args(2);
@ -566,7 +533,7 @@ impl CPU {
if self.debug { if self.debug {
println!("LD SP, {:02x}", self.sp); println!("LD SP, {:02x}", self.sp);
} }
cycles = 12; 12
}, },
0x32 => { 0x32 => {
if self.debug { if self.debug {
@ -577,7 +544,7 @@ impl CPU {
addr -= 1; addr -= 1;
self.set_pair_value(REG_H, REG_L, addr); self.set_pair_value(REG_H, REG_L, addr);
cycles = 8; 8
}, },
0x36 => { 0x36 => {
let args = self.load_args(1); let args = self.load_args(1);
@ -586,99 +553,28 @@ impl CPU {
} }
let addr = self.get_pair_value(REG_H, REG_L); let addr = self.get_pair_value(REG_H, REG_L);
self.interconnect.write_byte(addr, args[0]); self.interconnect.write_byte(addr, args[0]);
cycles = 12; 12
}, },
0x3C => { 0x3C => self.reg_inc(REG_A),
if self.debug { 0x3D => self.reg_dec(REG_A),
println!("INC A");
}
self.reg_inc(REG_A);
cycles = 4;
}
0x3D => {
if self.debug {
println!("DEC A");
}
self.reg_dec(REG_A);
cycles = 4;
}
0x3E => { 0x3E => {
let args = self.load_args(1); let args = self.load_args(1);
if self.debug { if self.debug {
println!("LD A, {:02x}", args[0]); println!("LD A, {:02x}", args[0]);
} }
self.regs[REG_A] = args[0]; self.regs[REG_A] = args[0];
cycles = 8; 8
}, },
// LDs // LDs
0x40 ... 0x47 => { 0x40 ... 0x47 => self.ld_r_r(REG_N_B, (instruction - 0x40) as usize),
let reg_id = (instruction - 0x40) as usize; 0x48 ... 0x4F => self.ld_r_r(REG_N_C, (instruction - 0x48) as usize),
if self.debug { 0x50 ... 0x57 => self.ld_r_r(REG_N_D, (instruction - 0x50) as usize),
println!("LD B, {}", REG_NAMES[reg_id]); 0x58 ... 0x5F => self.ld_r_r(REG_N_E, (instruction - 0x58) as usize),
} 0x60 ... 0x67 => self.ld_r_r(REG_N_H, (instruction - 0x60) as usize),
self.regs[REG_B] = self.get_8bit_reg(reg_id); 0x68 ... 0x6F => self.ld_r_r(REG_N_L, (instruction - 0x68) as usize),
cycles = 4; 0x70 ... 0x75 | 0x77 => self.ld_r_r(REG_N_HL, (instruction - 0x70) as usize),
}, 0x78 ... 0x7F => self.ld_r_r(REG_N_A, (instruction - 0x78) as usize),
0x48 ... 0x4F => {
let reg_id = (instruction - 0x48) as usize;
if self.debug {
println!("LD C, {}", REG_NAMES[reg_id]);
}
self.regs[REG_C] = self.get_8bit_reg(reg_id);
cycles = 4;
},
0x50 ... 0x57 => {
let reg_id = (instruction - 0x50) as usize;
if self.debug {
println!("LD D, {}", REG_NAMES[reg_id]);
}
self.regs[REG_D] = self.get_8bit_reg(reg_id);
cycles = 4;
},
0x58 ... 0x5F => {
let reg_id = (instruction - 0x58) as usize;
if self.debug {
println!("LD E, {}", REG_NAMES[reg_id]);
}
self.regs[REG_E] = self.get_8bit_reg(reg_id);
cycles = 4;
},
0x60 ... 0x67 => {
let reg_id = (instruction - 0x60) as usize;
if self.debug {
println!("LD H, {}", REG_NAMES[reg_id]);
}
self.regs[REG_H] = self.get_8bit_reg(reg_id);
cycles = 4;
},
0x68 ... 0x6F => {
let reg_id = (instruction - 0x68) as usize;
if self.debug {
println!("LD L, {}", REG_NAMES[reg_id]);
}
self.regs[REG_L] = self.get_8bit_reg(reg_id);
cycles = 4;
},
0x70 ... 0x75 | 0x77 => {
let reg_id = (instruction - 0x70) as usize;
if self.debug {
println!("LD (HL), {}", REG_NAMES[reg_id]);
}
let reg_value: u8 = self.get_8bit_reg(reg_id);
let addr: u16 = self.get_pair_value(REG_H, REG_L);
cycles = 8;
self.interconnect.write_byte(addr, reg_value);
},
0x78 ... 0x7F => {
let reg_id = (instruction - 0x78) as usize;
if self.debug {
println!("LD A, {}", REG_NAMES[reg_id]);
}
self.regs[REG_A] = self.get_8bit_reg(reg_id);
cycles = 4;
},
// ADD // ADD
0x80 ... 0x87 => { 0x80 ... 0x87 => {
@ -689,7 +585,7 @@ impl CPU {
self.regs[REG_A] = self.regs[REG_A].wrapping_add(self.get_8bit_reg(reg_id)); self.regs[REG_A] = self.regs[REG_A].wrapping_add(self.get_8bit_reg(reg_id));
self.clear_flag(FLAG_N); self.clear_flag(FLAG_N);
cycles = 4; 4
} }
// ADC // ADC
@ -702,7 +598,7 @@ impl CPU {
} }
self.set_flag(FLAG_N); self.set_flag(FLAG_N);
cycles = 4; 4
} }
// SUBs // SUBs
@ -719,7 +615,7 @@ impl CPU {
self.clear_flag(FLAG_Z); self.clear_flag(FLAG_Z);
} }
// TODO: H, C // TODO: H, C
cycles = 4; 4
} }
// SBC // SBC
@ -738,7 +634,7 @@ impl CPU {
} else { } else {
self.clear_flag(FLAG_Z); self.clear_flag(FLAG_Z);
} }
cycles = 4; 4
} }
// XOR // XOR
@ -757,7 +653,7 @@ impl CPU {
self.clear_flag(FLAG_C); self.clear_flag(FLAG_C);
self.clear_flag(FLAG_N); self.clear_flag(FLAG_N);
self.clear_flag(FLAG_H); self.clear_flag(FLAG_H);
cycles = 4; 4
}, },
// CP // CP
@ -779,7 +675,7 @@ impl CPU {
self.clear_flag(FLAG_C); self.clear_flag(FLAG_C);
self.clear_flag(FLAG_Z); self.clear_flag(FLAG_Z);
} }
cycles = 4; 4
}, },
0xC1 => { 0xC1 => {
if self.debug { if self.debug {
@ -788,7 +684,7 @@ impl CPU {
let val: u16 = self.interconnect.read_word(self.sp); let val: u16 = self.interconnect.read_word(self.sp);
self.sp += 2; self.sp += 2;
self.set_pair_value(REG_B, REG_C, val); self.set_pair_value(REG_B, REG_C, val);
cycles = 12; 12
}, },
0xC2 => { 0xC2 => {
let addr: u16 = to_u16(self.load_args(2)); let addr: u16 = to_u16(self.load_args(2));
@ -797,9 +693,9 @@ impl CPU {
} }
if self.flags & FLAG_Z == 0 { if self.flags & FLAG_Z == 0 {
self.ip = addr; self.ip = addr;
cycles = 16; 16
} else { } else {
cycles = 12; 12
} }
}, },
0xC3 => { 0xC3 => {
@ -808,7 +704,7 @@ impl CPU {
println!("JP {:04X}", addr); println!("JP {:04X}", addr);
} }
self.ip = addr; self.ip = addr;
cycles = 16; 16
} }
0xC4 => { 0xC4 => {
let target = to_u16(self.load_args(2)); let target = to_u16(self.load_args(2));
@ -817,36 +713,28 @@ impl CPU {
} }
if self.flags & FLAG_Z == 0 { if self.flags & FLAG_Z == 0 {
// Push current IP to the stack // Push current IP to the stack
self.interconnect.write_word(self.sp - 1, self.ip); let ip = self.ip;
self.sp -= 2; self.push(ip);
self.ip = target; self.ip = target;
cycles = 24; 24
} else { } else {
cycles = 12; 12
} }
}, },
0xC5 => { 0xC5 => self.push_rr(REG_B, REG_C),
if self.debug {
println!("PUSH BC");
}
let val: u16 = self.get_pair_value(REG_B, REG_C);
self.interconnect.write_word(self.sp - 2, val);
self.sp -= 2;
cycles = 16;
},
0xC9 => { 0xC9 => {
if self.debug { if self.debug {
println!("RET"); println!("RET");
self.dump_stack();
} }
self.dump_stack();
self.ip = self.interconnect.read_word(self.sp+1); self.ip = self.interconnect.read_word(self.sp+1);
self.sp += 2; self.sp += 2;
cycles = 16; 16
}, },
0xCB => { 0xCB => {
// Prefix CB. This is annoying. // Prefix CB. This is annoying.
self.run_prefix_instruction(); self.run_prefix_instruction();
cycles = 12; // TODO: Verify that this is the case for all prefix instructions. 12 // TODO: Verify that this is the case for all prefix instructions.
}, },
0xCC => { 0xCC => {
let target = to_u16(self.load_args(2)); let target = to_u16(self.load_args(2));
@ -858,9 +746,9 @@ impl CPU {
self.interconnect.write_word(self.sp - 1, self.ip); self.interconnect.write_word(self.sp - 1, self.ip);
self.sp -= 2; self.sp -= 2;
self.ip = target; self.ip = target;
cycles = 24; 24
} else { } else {
cycles = 12; 12
} }
}, },
0xCD => { 0xCD => {
@ -872,7 +760,7 @@ impl CPU {
self.interconnect.write_word(self.sp - 1, self.ip); self.interconnect.write_word(self.sp - 1, self.ip);
self.sp -= 2; self.sp -= 2;
self.ip = target; self.ip = target;
cycles = 24; 24
}, },
0xE0 => { 0xE0 => {
let args = self.load_args(1); let args = self.load_args(1);
@ -880,7 +768,7 @@ impl CPU {
println!("LDH {:02X}, A", args[0]); println!("LDH {:02X}, A", args[0]);
} }
self.interconnect.write_byte(0xFF00 + args[0] as u16, self.regs[REG_A]); self.interconnect.write_byte(0xFF00 + args[0] as u16, self.regs[REG_A]);
cycles = 12; 12
}, },
0xE2 => { 0xE2 => {
if self.debug { if self.debug {
@ -888,7 +776,7 @@ impl CPU {
println!("[{:04X}] = {:02X}", 0xFF00 + self.regs[REG_C] as u16, self.regs[REG_A]); println!("[{:04X}] = {:02X}", 0xFF00 + self.regs[REG_C] as u16, self.regs[REG_A]);
} }
self.interconnect.write_byte(0xFF00 + self.regs[REG_C] as u16, self.regs[REG_A]); self.interconnect.write_byte(0xFF00 + self.regs[REG_C] as u16, self.regs[REG_A]);
cycles = 8; 8
}, },
0xEA => { 0xEA => {
let addr = to_u16(self.load_args(2)); let addr = to_u16(self.load_args(2));
@ -896,7 +784,7 @@ impl CPU {
println!("LD ({:04X}), A", addr); println!("LD ({:04X}), A", addr);
} }
self.interconnect.write_byte(addr, self.regs[REG_A]); self.interconnect.write_byte(addr, self.regs[REG_A]);
cycles = 16; 16
} }
0xF0 => { 0xF0 => {
let args = self.load_args(1); let args = self.load_args(1);
@ -904,21 +792,21 @@ impl CPU {
println!("LDH A, {:02X}", args[0]); println!("LDH A, {:02X}", args[0]);
} }
self.regs[REG_A] = self.interconnect.read_byte(0xFF00 + args[0] as u16); self.regs[REG_A] = self.interconnect.read_byte(0xFF00 + args[0] as u16);
cycles = 12; 12
}, },
0xF2 => { 0xF2 => {
if self.debug{ if self.debug{
println!("LD A, (C)"); println!("LD A, (C)");
} }
self.regs[REG_A] = self.interconnect.read_byte(0xFF00 + self.regs[REG_C] as u16); self.regs[REG_A] = self.interconnect.read_byte(0xFF00 + self.regs[REG_C] as u16);
cycles = 8; 8
}, },
0xF3 => { 0xF3 => {
if self.debug { if self.debug {
println!("DI"); println!("DI");
} }
self.interrupts_enabled = false; self.interrupts_enabled = false;
cycles = 4; 4
} }
0xFB => { 0xFB => {
// Enable interrupts - TODO // Enable interrupts - TODO
@ -926,8 +814,8 @@ impl CPU {
println!("EI"); println!("EI");
} }
self.interrupts_enabled = true; self.interrupts_enabled = true;
cycles = 4;
panic!("ENABLING INTERRUPTS - TODO"); panic!("ENABLING INTERRUPTS - TODO");
4
}, },
0xFE => { 0xFE => {
let args = self.load_args(1); let args = self.load_args(1);
@ -947,10 +835,10 @@ impl CPU {
} }
// TODO H // TODO H
cycles = 8; 8
} }
_ => panic!("Unknown instruction: {:02x}", instruction) _ => panic!("Unknown instruction: {:02x}", instruction)
} };
// self.dump_stack(); // self.dump_stack();
self.interconnect.tick(cycles); self.interconnect.tick(cycles);
} }

View File

@ -70,7 +70,7 @@ impl Display {
let sdl_ctx = sdl2::init().unwrap(); let sdl_ctx = sdl2::init().unwrap();
let video_ctx = sdl_ctx.video().unwrap(); let video_ctx = sdl_ctx.video().unwrap();
let wnd = video_ctx.window("RustBoy", (GB_PIXELS_X * SCALE) as u32, (GB_PIXELS_Y * SCALE) as u32).position_centered().build().expect("Failed to create window :<"); let wnd = video_ctx.window("RustBoy", (GB_PIXELS_X * SCALE) as u32, (GB_PIXELS_Y * SCALE) as u32).position_centered().build().expect("Failed to create window :<");
let mut renderer = wnd.renderer().build().expect("Could not build renderer"); let renderer = wnd.renderer().build().expect("Could not build renderer");
Display { Display {
control: 0, control: 0,
@ -199,7 +199,25 @@ impl Display {
// Render background // Render background
if self.control & CTRL_BG_DISPLAY > 0 { if self.control & CTRL_BG_DISPLAY > 0 {
print!("Drawing tiles: ");
// Draw borders first.
for t_x in 0 .. 160/8 {
self.renderer.set_draw_color(sdl2::pixels::Color::RGB(0xFF, 10, 0xFF));
// Awesome effects:
/*
let RX: i32 = (t_x as i32)*8 + map_offset_x as i32;
let RY: i32 = (render_y as i32) & 0xFFFFFFF8 + map_offset_y as i32;
let TS: u32 = 8u32 * (SCALE as u32);
*/
let RX: i32 = (t_x as i32)*8 + map_offset_x as i32;
let RY: i32 = ((render_y as u32) & 0xFFFFFFF8) as i32 - map_offset_y as i32;
let TS: u32 = 8u32 * (SCALE as u32);
self.renderer.draw_rect(
sdl2::rect::Rect::new(RX * SCALE as i32, RY * SCALE as i32, TS, TS)
);
}
// Render pixels (20 tiles) // Render pixels (20 tiles)
for render_x in 0 .. 160 { for render_x in 0 .. 160 {
// Absolute render coordinates // Absolute render coordinates
@ -219,7 +237,7 @@ impl Display {
// println!("vram offset: {:04X}", vram_offset); // println!("vram offset: {:04X}", vram_offset);
if tile_id != 0 { if tile_id != 0 {
// println!("Drawing tile {:02X}", tile_id); // println!("Drawing tile {:02X}", tile_id);
print!("{:02X} ", tile_id); // print!("{:02X} ", tile_id);
} }
// Obtain tile information // Obtain tile information
@ -230,7 +248,7 @@ impl Display {
tile_base_addr = 0x0800; tile_base_addr = 0x0800;
// This set goes from -127 to 127. // This set goes from -127 to 127.
let s_tid: i8 = tile_id as i8; let s_tid: i8 = tile_id as i8;
tile_id = (128 + s_tid) as u8; tile_id = (128u8 as i8 + s_tid) as u8;
panic!("OH MY GOD, this wasn't tested yet"); panic!("OH MY GOD, this wasn't tested yet");
} }
@ -252,9 +270,9 @@ impl Display {
// Draw stuff. We're currently only in monochrome mode // Draw stuff. We're currently only in monochrome mode
self.set_pixel(render_x, render_y, sdl2::pixels::Color::RGB(factor, factor, factor)); self.set_pixel(render_x, render_y, sdl2::pixels::Color::RGB(factor, factor, factor));
} }
} }
println!("");
} }
pub fn vblank_interrupt(&mut self) { pub fn vblank_interrupt(&mut self) {

View File

@ -44,8 +44,8 @@ impl Interconnect {
} }
// Somehow we need different timers for this. // Somehow we need different timers for this.
pub fn tick(&mut self, cycles: u16) { pub fn tick(&mut self, cycles: u8) {
self.display.tick(cycles * 4); self.display.tick(cycles as u16 * 4);
} }
pub fn display_blank_interrupt(&mut self) { pub fn display_blank_interrupt(&mut self) {
@ -138,6 +138,7 @@ impl Interconnect {
self.display.write_byte(addr, val); self.display.write_byte(addr, val);
}, },
0xFF50 => { 0xFF50 => {
println!("Disabling boot rom.");
self.disable_bootrom = val; self.disable_bootrom = val;
}, },
0xFF56 => { 0xFF56 => {