Honor flags more. Deny direct reg access
This commit is contained in:
parent
d91fa7d75b
commit
710b057f54
272
src/cpu.rs
272
src/cpu.rs
@ -1,11 +1,11 @@
|
||||
use super::interconnect;
|
||||
|
||||
const REG_B: usize = 0;
|
||||
const REG_C: usize = 1;
|
||||
const REG_D: usize = 2;
|
||||
const REG_E: usize = 3;
|
||||
const REG_H: usize = 4;
|
||||
const REG_L: usize = 5;
|
||||
//const REG_B: usize = 0;
|
||||
//const REG_C: usize = 1;
|
||||
//const REG_D: usize = 2;
|
||||
//const REG_E: usize = 3;
|
||||
//const REG_H: usize = 4;
|
||||
//const REG_L: usize = 5;
|
||||
const REG_A: usize = 6;
|
||||
|
||||
const REG_N_B: usize = 0;
|
||||
@ -78,7 +78,7 @@ impl CPU {
|
||||
} else if reg_id == REG_N_F {
|
||||
self.flags = value;
|
||||
} else if reg_id == REG_N_HL {
|
||||
let addr: u16 = self.get_pair_value(REG_H, REG_L);
|
||||
let addr: u16 = self.get_pair_value(REG_N_H, REG_N_L);
|
||||
self.interconnect.write_byte(addr, value);
|
||||
} else {
|
||||
self.regs[reg_id] = value;
|
||||
@ -92,7 +92,7 @@ impl CPU {
|
||||
} else if reg_id == REG_N_F {
|
||||
self.flags
|
||||
} else if reg_id == REG_N_HL {
|
||||
let addr: u16 = self.get_pair_value(REG_H, REG_L);
|
||||
let addr: u16 = self.get_pair_value(REG_N_H, REG_N_L);
|
||||
self.interconnect.read_byte(addr)
|
||||
} else {
|
||||
self.regs[reg_id]
|
||||
@ -104,6 +104,42 @@ impl CPU {
|
||||
self.ip += 1;
|
||||
|
||||
match instruction {
|
||||
0x00 ... 0x07 => {
|
||||
let reg_id = (instruction - 0x00) as usize;
|
||||
let val = self.get_8bit_reg(reg_id);
|
||||
if self.debug {
|
||||
println!("RLC {}", REG_NAMES[reg_id]);
|
||||
}
|
||||
|
||||
if val & 0x80 == 0x80 {
|
||||
self.set_flag(FLAG_C);
|
||||
self.set_8bit_reg(reg_id, val << 1 | 1);
|
||||
} else {
|
||||
self.set_8bit_reg(reg_id, val << 1);
|
||||
}
|
||||
|
||||
self.set_clear_flag(FLAG_Z, val == 0);
|
||||
self.clear_flag(FLAG_N);
|
||||
self.clear_flag(FLAG_H);
|
||||
},
|
||||
0x08 ... 0x0F => {
|
||||
let reg_id = (instruction - 0x08) as usize;
|
||||
let val = self.get_8bit_reg(reg_id);
|
||||
if self.debug {
|
||||
println!("RRC {}", REG_NAMES[reg_id]);
|
||||
}
|
||||
|
||||
if val & 1 > 0 {
|
||||
self.set_flag(FLAG_C);
|
||||
self.set_8bit_reg(reg_id, val >> 1 | 0x80);
|
||||
} else {
|
||||
self.set_8bit_reg(reg_id, val >> 1);
|
||||
}
|
||||
|
||||
self.set_clear_flag(FLAG_Z, val == 0);
|
||||
self.clear_flag(FLAG_N);
|
||||
self.clear_flag(FLAG_H);
|
||||
},
|
||||
0x10 ... 0x17 => {
|
||||
let reg_id = (instruction - 0x10) as usize;
|
||||
let val = self.get_8bit_reg(reg_id);
|
||||
@ -152,6 +188,24 @@ impl CPU {
|
||||
self.clear_flag(FLAG_N);
|
||||
self.clear_flag(FLAG_H);
|
||||
},
|
||||
0x20 ... 0x27 => {
|
||||
let reg_id = (instruction - 0x20) as usize;
|
||||
if self.debug {
|
||||
println!("SLA {}", REG_NAMES[reg_id]);
|
||||
}
|
||||
let v: u8 = self.get_8bit_reg(reg_id);
|
||||
self.set_clear_flag(FLAG_C, v & 0x80 > 0);
|
||||
self.set_8bit_reg(reg_id, v << 1);
|
||||
},
|
||||
0x28 ... 0x2F => {
|
||||
let reg_id = (instruction - 0x20) as usize;
|
||||
if self.debug {
|
||||
println!("SRA {}", REG_NAMES[reg_id]);
|
||||
}
|
||||
let v: u8 = self.get_8bit_reg(reg_id);
|
||||
self.set_clear_flag(FLAG_C, v & 1 > 0);
|
||||
self.set_8bit_reg(reg_id, v >> 1);
|
||||
},
|
||||
0x30 ... 0x37 => {
|
||||
let reg_id = (instruction - 0x30) as usize;
|
||||
if self.debug {
|
||||
@ -296,6 +350,7 @@ impl CPU {
|
||||
fn call(&mut self, dst: u16) {
|
||||
let ip = self.ip;
|
||||
self.push(ip);
|
||||
self.dump_stack();
|
||||
self.ip = dst;
|
||||
}
|
||||
|
||||
@ -398,7 +453,7 @@ impl CPU {
|
||||
let val = self.get_8bit_reg(reg_id).wrapping_add(1);
|
||||
self.set_8bit_reg(reg_id, val);
|
||||
self.set_clear_flag(FLAG_Z, val == 0);
|
||||
self.set_clear_flag(FLAG_C, val == 0);
|
||||
// self.set_clear_flag(FLAG_C, val == 0);
|
||||
self.clear_flag(FLAG_N);
|
||||
4
|
||||
}
|
||||
@ -418,7 +473,7 @@ impl CPU {
|
||||
self.set_8bit_reg(reg_id, val);
|
||||
|
||||
self.set_clear_flag(FLAG_Z, val == 0);
|
||||
self.set_clear_flag(FLAG_C, val == 255);
|
||||
// self.set_clear_flag(FLAG_C, val == 255);
|
||||
self.set_flag(FLAG_N);
|
||||
4
|
||||
}
|
||||
@ -460,6 +515,7 @@ impl CPU {
|
||||
|
||||
fn ret(&mut self) {
|
||||
let new_ip: u16 = self.pop();
|
||||
self.dump_stack();
|
||||
self.ip = new_ip;
|
||||
}
|
||||
|
||||
@ -544,13 +600,20 @@ impl CPU {
|
||||
20
|
||||
}
|
||||
0x09 => self.add_rr_rr(REG_N_H, REG_N_L, REG_N_B, REG_N_C),
|
||||
0x0A => {
|
||||
if self.debug {
|
||||
println!("LD A, (BC)");
|
||||
}
|
||||
self.regs[REG_A] = self.interconnect.read_byte(self.get_pair_value(REG_N_B, REG_N_C));
|
||||
8
|
||||
},
|
||||
0x0B => self.dec_rr(REG_N_B, REG_N_C),
|
||||
0x0C => self.reg_inc(REG_N_C),
|
||||
0x0D => self.reg_dec(REG_N_C),
|
||||
0x0E => self.ld_r_v(REG_N_C),
|
||||
0x11 => self.ld_rr_vv(REG_N_D, REG_N_E),
|
||||
0x12 => self.ld_dref_rr_a(REG_D, REG_E),
|
||||
0x13 => self.inc_rr(REG_D, REG_E),
|
||||
0x12 => self.ld_dref_rr_a(REG_N_D, REG_N_E),
|
||||
0x13 => self.inc_rr(REG_N_D, REG_N_E),
|
||||
0x14 => self.reg_inc(REG_N_D),
|
||||
0x15 => self.reg_dec(REG_N_D),
|
||||
0x16 => self.ld_r_v(REG_N_D),
|
||||
@ -559,16 +622,11 @@ impl CPU {
|
||||
println!("RLA");
|
||||
}
|
||||
let carry = self.flags & FLAG_C > 0;
|
||||
let val = self.regs[REG_A];
|
||||
self.set_clear_flag(FLAG_C, val & 0x80 == 0x80);
|
||||
if !carry {
|
||||
// No carry before, now we got a carry => set it
|
||||
if self.regs[REG_A] & 0x80 == 0x80 {
|
||||
self.set_flag(FLAG_C);
|
||||
}
|
||||
self.regs[REG_A] = self.regs[REG_A] << 1;
|
||||
} else {
|
||||
if self.regs[REG_A] & 0x80 == 0 {
|
||||
self.clear_flag(FLAG_C);
|
||||
}
|
||||
self.regs[REG_A] = self.regs[REG_A] << 1 | 1;
|
||||
}
|
||||
self.clear_flag(FLAG_Z);
|
||||
@ -594,28 +652,23 @@ impl CPU {
|
||||
if self.debug {
|
||||
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_N_D, REG_N_E));
|
||||
8
|
||||
},
|
||||
0x1B => self.dec_rr(REG_N_D, REG_N_E),
|
||||
0x1C => self.reg_inc(REG_N_E),
|
||||
0x1D => self.reg_dec(REG_N_E),
|
||||
0x1E => self.ld_r_v(REG_N_E),
|
||||
0x1F => { // UNTESTED
|
||||
0x1F => {
|
||||
if self.debug {
|
||||
println!("RRA");
|
||||
}
|
||||
let carry = self.flags & FLAG_C > 0;
|
||||
let val = self.regs[REG_A];
|
||||
self.set_clear_flag(FLAG_C, val & 1 == 1);
|
||||
if !carry {
|
||||
// No carry before, now we got a carry => set it
|
||||
if self.regs[REG_A] & 1 == 1 {
|
||||
self.set_flag(FLAG_C);
|
||||
}
|
||||
self.regs[REG_A] = self.regs[REG_A] >> 1;
|
||||
} else {
|
||||
if self.regs[REG_A] & 1 == 0 {
|
||||
self.clear_flag(FLAG_C);
|
||||
}
|
||||
self.regs[REG_A] = self.regs[REG_A] >> 1 | 0x80;
|
||||
}
|
||||
self.clear_flag(FLAG_Z);
|
||||
@ -645,12 +698,12 @@ impl CPU {
|
||||
if self.debug {
|
||||
println!("LD (HL+), A");
|
||||
}
|
||||
let addr: u16 = self.get_pair_value(REG_H, REG_L);
|
||||
let addr: u16 = self.get_pair_value(REG_N_H, REG_N_L);
|
||||
self.interconnect.write_byte(addr, self.regs[REG_A]);
|
||||
self.set_pair_value(REG_H, REG_L, addr.wrapping_add(1));
|
||||
self.set_pair_value(REG_N_H, REG_N_L, addr.wrapping_add(1));
|
||||
8
|
||||
},
|
||||
0x23 => self.inc_rr(REG_H, REG_L),
|
||||
0x23 => self.inc_rr(REG_N_H, REG_N_L),
|
||||
0x24 => self.reg_inc(REG_N_H),
|
||||
0x25 => self.reg_dec(REG_N_H),
|
||||
0x26 => self.ld_r_v(REG_N_H),
|
||||
@ -677,9 +730,9 @@ impl CPU {
|
||||
if self.debug {
|
||||
println!("LD A, (HL+)");
|
||||
}
|
||||
let addr: u16 = self.get_pair_value(REG_H, REG_L);
|
||||
let addr: u16 = self.get_pair_value(REG_N_H, REG_N_L);
|
||||
self.regs[REG_A] = self.interconnect.read_byte(addr);
|
||||
self.set_pair_value(REG_H, REG_L, addr+1);
|
||||
self.set_pair_value(REG_N_H, REG_N_L, addr.wrapping_add(1));
|
||||
8
|
||||
},
|
||||
0x2B => self.dec_rr(REG_N_H, REG_N_L),
|
||||
@ -691,6 +744,8 @@ impl CPU {
|
||||
println!("CPL");
|
||||
}
|
||||
self.regs[REG_A] = !self.regs[REG_A];
|
||||
self.set_flag(FLAG_N);
|
||||
self.set_flag(FLAG_H);
|
||||
4
|
||||
},
|
||||
0x30 => {
|
||||
@ -722,20 +777,30 @@ impl CPU {
|
||||
if self.debug {
|
||||
println!("LD (HL-), A");
|
||||
}
|
||||
let mut addr = self.get_pair_value(REG_H, REG_L);
|
||||
let mut addr = self.get_pair_value(REG_N_H, REG_N_L);
|
||||
self.interconnect.write_byte(addr, self.regs[REG_A]);
|
||||
|
||||
addr -= 1;
|
||||
self.set_pair_value(REG_H, REG_L, addr);
|
||||
self.set_pair_value(REG_N_H, REG_N_L, addr.wrapping_sub(1));
|
||||
8
|
||||
},
|
||||
0x33 => {
|
||||
if self.debug {
|
||||
println!("INC SP");
|
||||
}
|
||||
let sp = self.sp.wrapping_add(1);
|
||||
self.sp = sp;
|
||||
self.set_clear_flag(FLAG_Z, sp == 0);
|
||||
self.set_clear_flag(FLAG_C, sp == 0);
|
||||
self.clear_flag(FLAG_N);
|
||||
8
|
||||
}
|
||||
0x34 => self.reg_inc(REG_N_HL),
|
||||
0x35 => self.reg_dec(REG_N_HL),
|
||||
0x36 => {
|
||||
let args = self.load_args(1);
|
||||
if self.debug {
|
||||
println!("LD (HL), {:02x}", args[0]);
|
||||
}
|
||||
let addr = self.get_pair_value(REG_H, REG_L);
|
||||
let addr = self.get_pair_value(REG_N_H, REG_N_L);
|
||||
self.interconnect.write_byte(addr, args[0]);
|
||||
12
|
||||
},
|
||||
@ -744,6 +809,8 @@ impl CPU {
|
||||
println!("SCF");
|
||||
}
|
||||
self.set_flag(FLAG_C);
|
||||
self.clear_flag(FLAG_N);
|
||||
self.clear_flag(FLAG_H);
|
||||
4
|
||||
},
|
||||
0x38 => {
|
||||
@ -768,8 +835,24 @@ impl CPU {
|
||||
println!("ADD HL, SP");
|
||||
}
|
||||
let sp = self.sp;
|
||||
let v = self.get_pair_value(REG_N_H, REG_N_L).wrapping_add(sp);
|
||||
let old = self.get_pair_value(REG_N_H, REG_N_L);
|
||||
let v = old.wrapping_add(sp);
|
||||
self.set_pair_value(REG_N_H, REG_N_L, v);
|
||||
|
||||
self.clear_flag(FLAG_N);
|
||||
self.set_clear_flag(FLAG_C, old > v);
|
||||
|
||||
8
|
||||
},
|
||||
0x3B => {
|
||||
if self.debug {
|
||||
println!("DEC SP");
|
||||
}
|
||||
let sp = self.sp.wrapping_sub(1);
|
||||
self.sp = sp;
|
||||
self.set_clear_flag(FLAG_Z, sp == 0);
|
||||
self.set_clear_flag(FLAG_C, sp == 0xFFFF);
|
||||
self.set_flag(FLAG_N);
|
||||
8
|
||||
}
|
||||
0x3C => self.reg_inc(REG_N_A),
|
||||
@ -780,6 +863,7 @@ impl CPU {
|
||||
println!("CCF");
|
||||
}
|
||||
self.flags ^= FLAG_C;
|
||||
self.clear_flag(FLAG_N);
|
||||
4
|
||||
}
|
||||
|
||||
@ -808,9 +892,14 @@ impl CPU {
|
||||
if self.debug {
|
||||
println!("ADD {}", REG_NAMES[reg_id]);
|
||||
}
|
||||
self.regs[REG_A] = self.regs[REG_A].wrapping_add(self.get_8bit_reg(reg_id));
|
||||
let old = self.regs[REG_A];
|
||||
let new = old.wrapping_add(self.get_8bit_reg(reg_id));
|
||||
self.regs[REG_A] = new;
|
||||
|
||||
self.clear_flag(FLAG_N);
|
||||
self.set_clear_flag(FLAG_Z, new == 0);
|
||||
self.set_clear_flag(FLAG_C, new < old);
|
||||
// TODO: H
|
||||
4
|
||||
}
|
||||
|
||||
@ -818,12 +907,18 @@ impl CPU {
|
||||
0x88 ... 0x8F => {
|
||||
let reg_id = (instruction - 0x88) as usize;
|
||||
println!("ADC {}", REG_NAMES[reg_id]);
|
||||
self.regs[REG_A] = self.regs[REG_A].wrapping_add(self.get_8bit_reg(reg_id));
|
||||
if self.flags & FLAG_C == FLAG_C {
|
||||
self.regs[REG_A] = self.regs[REG_A].wrapping_add(1);
|
||||
}
|
||||
|
||||
self.set_flag(FLAG_N);
|
||||
let old = self.regs[REG_A];
|
||||
let mut new = old.wrapping_add(self.get_8bit_reg(reg_id));
|
||||
if self.flags & FLAG_C > 0 {
|
||||
new = new.wrapping_add(1);
|
||||
}
|
||||
self.regs[REG_A] = new;
|
||||
|
||||
self.clear_flag(FLAG_N);
|
||||
self.set_clear_flag(FLAG_Z, new == 0);
|
||||
self.set_clear_flag(FLAG_C, new < old);
|
||||
// TODO: H
|
||||
4
|
||||
}
|
||||
|
||||
@ -833,14 +928,13 @@ impl CPU {
|
||||
if self.debug {
|
||||
println!("SUB {}", REG_NAMES[reg_id]);
|
||||
}
|
||||
self.regs[REG_A] = self.regs[REG_A].wrapping_sub(self.get_8bit_reg(reg_id));
|
||||
let old = self.regs[REG_A];
|
||||
let new = old.wrapping_sub(self.get_8bit_reg(reg_id));
|
||||
self.regs[REG_A] = new;
|
||||
self.set_flag(FLAG_N);
|
||||
if self.regs[REG_A] == 0 {
|
||||
self.set_flag(FLAG_Z);
|
||||
} else {
|
||||
self.clear_flag(FLAG_Z);
|
||||
}
|
||||
// TODO: H, C
|
||||
self.set_clear_flag(FLAG_Z, new == 0);
|
||||
self.set_clear_flag(FLAG_C, new > old);
|
||||
// TODO: H
|
||||
4
|
||||
}
|
||||
|
||||
@ -850,16 +944,16 @@ impl CPU {
|
||||
if self.debug {
|
||||
println!("SBC {}", REG_NAMES[reg_id]);
|
||||
}
|
||||
self.regs[REG_A] = self.regs[REG_A].wrapping_sub(self.get_8bit_reg(reg_id));
|
||||
if self.flags & FLAG_C == FLAG_C {
|
||||
self.regs[REG_A] = self.regs[REG_A].wrapping_sub(1);
|
||||
let old = self.regs[REG_A];
|
||||
let mut new = old.wrapping_sub(self.get_8bit_reg(reg_id));
|
||||
if self.flags & FLAG_C > 0 {
|
||||
new = new.wrapping_sub(1);
|
||||
}
|
||||
self.regs[REG_A] = new;
|
||||
|
||||
self.set_flag(FLAG_N);
|
||||
if self.regs[REG_A] == 0 {
|
||||
self.set_flag(FLAG_Z);
|
||||
} else {
|
||||
self.clear_flag(FLAG_Z);
|
||||
}
|
||||
self.set_clear_flag(FLAG_Z, new == 0);
|
||||
self.set_clear_flag(FLAG_C, new > old);
|
||||
4
|
||||
}
|
||||
|
||||
@ -876,6 +970,9 @@ impl CPU {
|
||||
} else {
|
||||
self.clear_flag(FLAG_Z);
|
||||
}
|
||||
self.clear_flag(FLAG_N);
|
||||
self.set_flag(FLAG_H);
|
||||
self.clear_flag(FLAG_C);
|
||||
4
|
||||
}
|
||||
|
||||
@ -905,12 +1002,12 @@ impl CPU {
|
||||
println!("OR {}", REG_NAMES[reg_id]);
|
||||
}
|
||||
self.regs[REG_A] |= self.get_8bit_reg(reg_id);
|
||||
let v = self.regs[REG_A];
|
||||
|
||||
self.set_clear_flag(FLAG_Z, v == 0);
|
||||
self.clear_flag(FLAG_C);
|
||||
self.clear_flag(FLAG_N);
|
||||
if self.regs[REG_A] == 0 {
|
||||
self.set_flag(FLAG_Z);
|
||||
} else {
|
||||
self.clear_flag(FLAG_Z);
|
||||
}
|
||||
self.clear_flag(FLAG_H);
|
||||
4
|
||||
}
|
||||
|
||||
@ -939,7 +1036,7 @@ impl CPU {
|
||||
8
|
||||
}
|
||||
},
|
||||
0xC1 => self.pop_rr(REG_B, REG_C),
|
||||
0xC1 => self.pop_rr(REG_N_B, REG_N_C),
|
||||
0xC2 => {
|
||||
let addr: u16 = to_u16(self.load_args(2));
|
||||
if self.debug {
|
||||
@ -972,7 +1069,7 @@ impl CPU {
|
||||
12
|
||||
}
|
||||
},
|
||||
0xC5 => self.push_rr(REG_B, REG_C),
|
||||
0xC5 => self.push_rr(REG_N_B, REG_N_C),
|
||||
0xC6 => {
|
||||
let val = self.load_args(1)[0];
|
||||
if self.debug {
|
||||
@ -1056,8 +1153,8 @@ impl CPU {
|
||||
8
|
||||
}
|
||||
},
|
||||
0xD1 => self.pop_rr(REG_D, REG_E),
|
||||
0xD5 => self.push_rr(REG_D, REG_E),
|
||||
0xD1 => self.pop_rr(REG_N_D, REG_N_E),
|
||||
0xD5 => self.push_rr(REG_N_D, REG_N_E),
|
||||
0xD6 => {
|
||||
let val = self.load_args(1)[0];
|
||||
if self.debug {
|
||||
@ -1083,7 +1180,8 @@ impl CPU {
|
||||
} else {
|
||||
8
|
||||
}
|
||||
}
|
||||
},
|
||||
0xD9 => self.reti(),
|
||||
0xDE => {
|
||||
let arg = self.load_args(1)[0];
|
||||
if self.debug {
|
||||
@ -1115,12 +1213,12 @@ impl CPU {
|
||||
0xE2 => {
|
||||
if self.debug {
|
||||
println!("LD (C), 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]);
|
||||
let addr = 0xFF00 + self.get_8bit_reg(REG_N_C);
|
||||
self.interconnect.write_byte(0xFF00 + addr as u16, self.regs[REG_A]);
|
||||
8
|
||||
},
|
||||
0xE5 => self.push_rr(REG_H, REG_L),
|
||||
0xE5 => self.push_rr(REG_N_H, REG_N_L),
|
||||
0xE6 => {
|
||||
let val = self.load_args(1)[0];
|
||||
if self.debug {
|
||||
@ -1130,6 +1228,19 @@ impl CPU {
|
||||
8
|
||||
},
|
||||
0xE7 => self.rst(0x20),
|
||||
0xE8 => {
|
||||
let arg = self.load_args(1)[0];
|
||||
if self.debug {
|
||||
println!("ADD SP, {:02X}", arg);
|
||||
}
|
||||
let t = self.sp.wrapping_add(arg as u16);
|
||||
let sp = self.sp;
|
||||
self.clear_flag(FLAG_N);
|
||||
self.clear_flag(FLAG_Z);
|
||||
self.set_clear_flag(FLAG_C, t < sp);
|
||||
self.sp = t;
|
||||
16
|
||||
}
|
||||
0xE9 => {
|
||||
if self.debug {
|
||||
println!("JP (HL)");
|
||||
@ -1176,7 +1287,8 @@ impl CPU {
|
||||
if self.debug{
|
||||
println!("LD A, (C)");
|
||||
}
|
||||
self.regs[REG_A] = self.interconnect.read_byte(0xFF00 + self.regs[REG_C] as u16);
|
||||
let addr = 0xFF00 + self.get_8bit_reg(REG_N_C) as u16;
|
||||
self.regs[REG_A] = self.interconnect.read_byte(addr);
|
||||
8
|
||||
},
|
||||
0xF3 => {
|
||||
@ -1196,6 +1308,18 @@ impl CPU {
|
||||
8
|
||||
},
|
||||
0xF7 => self.rst(0x30),
|
||||
0xF8 => {
|
||||
let arg = self.load_args(1)[0];
|
||||
if self.debug {
|
||||
println!("LD HL, SP+{:02X}", arg);
|
||||
}
|
||||
|
||||
let v = self.sp.wrapping_add(arg as u16);
|
||||
self.clear_flag(FLAG_N);
|
||||
self.clear_flag(FLAG_Z);
|
||||
self.set_pair_value(REG_N_H, REG_N_L, v);
|
||||
12
|
||||
}
|
||||
0xFB => {
|
||||
// Enable interrupts - TODO
|
||||
if self.debug {
|
||||
|
||||
@ -88,7 +88,7 @@ impl Display {
|
||||
windowx: 0,
|
||||
windowy: 0,
|
||||
curline: 0,
|
||||
lyc: 255,
|
||||
lyc: 0,
|
||||
|
||||
current_ticks: 0,
|
||||
current_mode: DisplayMode::default(),
|
||||
@ -175,10 +175,8 @@ impl Display {
|
||||
// Do we want to have a time delta here?
|
||||
pub fn tick(&mut self, ticks: u16) {
|
||||
self.current_ticks += ticks;
|
||||
if self.curline == self.lyc {
|
||||
self.stat_fired = true;
|
||||
self.stat_interrupt = true;
|
||||
}
|
||||
self.status &= 0xFC;
|
||||
|
||||
match self.current_mode {
|
||||
DisplayMode::Scanline => {
|
||||
if self.current_ticks > TICKS_END_SCANLINE {
|
||||
@ -187,6 +185,7 @@ impl Display {
|
||||
self.current_ticks = 0;
|
||||
self.current_mode = DisplayMode::Readmode;
|
||||
}
|
||||
self.status |= 3;
|
||||
},
|
||||
DisplayMode::Readmode => {
|
||||
if self.current_ticks > TICKS_END_READMODE {
|
||||
@ -194,6 +193,7 @@ impl Display {
|
||||
self.current_mode = DisplayMode::HBlank;
|
||||
self.renderscan();
|
||||
}
|
||||
self.status |= 2;
|
||||
},
|
||||
DisplayMode::HBlank => {
|
||||
if self.current_ticks > TICKS_END_HBLANK {
|
||||
@ -207,6 +207,8 @@ impl Display {
|
||||
self.current_mode = DisplayMode::Scanline;
|
||||
}
|
||||
}
|
||||
self.status &= 0xFC;
|
||||
self.status |= 0;
|
||||
},
|
||||
DisplayMode::VBlank => {
|
||||
if self.current_ticks > TICKS_END_VBLANK {
|
||||
@ -220,8 +222,18 @@ impl Display {
|
||||
self.curline = 0;
|
||||
}
|
||||
}
|
||||
self.status |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the status register
|
||||
if self.curline == self.lyc {
|
||||
self.status |= 1 << 2;
|
||||
self.stat_fired = true;
|
||||
self.stat_interrupt = true;
|
||||
} else {
|
||||
self.status &= !(1 << 2);
|
||||
}
|
||||
}
|
||||
|
||||
fn renderscan(&mut self) {
|
||||
|
||||
@ -142,9 +142,19 @@ impl Interconnect {
|
||||
0xFF10 ... 0xFF26 => {
|
||||
self.sound.write_byte(addr, val);
|
||||
},
|
||||
0xFF40 ... 0xFF4B => {
|
||||
// Exclude DMA transfer, we will do this below
|
||||
0xFF40 ... 0xFF45 | 0xFF47 ... 0xFF4B => {
|
||||
self.display.write_byte(addr, val);
|
||||
},
|
||||
0xFF46 => {
|
||||
println!("DMA transfer: ");
|
||||
for x in 0x00 .. 0x9F {
|
||||
let dma_b = self.read_byte(((val as u16) << 8) | x);
|
||||
self.write_byte(0xFE00 | x, dma_b);
|
||||
print!("{:02X} ", val);
|
||||
}
|
||||
println!("");
|
||||
}
|
||||
0xFF50 => {
|
||||
println!("Disabling boot rom.");
|
||||
self.disable_bootrom = val;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user