Honor flags more. Deny direct reg access

This commit is contained in:
Kevin Hamacher 2016-05-28 15:41:44 +02:00
parent d91fa7d75b
commit 710b057f54
3 changed files with 226 additions and 80 deletions

View File

@ -1,11 +1,11 @@
use super::interconnect; use super::interconnect;
const REG_B: usize = 0; //const REG_B: usize = 0;
const REG_C: usize = 1; //const REG_C: usize = 1;
const REG_D: usize = 2; //const REG_D: usize = 2;
const REG_E: usize = 3; //const REG_E: usize = 3;
const REG_H: usize = 4; //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_B: usize = 0;
@ -78,7 +78,7 @@ impl CPU {
} else if reg_id == REG_N_F { } else if reg_id == REG_N_F {
self.flags = value; self.flags = value;
} else if reg_id == REG_N_HL { } 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); self.interconnect.write_byte(addr, value);
} else { } else {
self.regs[reg_id] = value; self.regs[reg_id] = value;
@ -92,7 +92,7 @@ impl CPU {
} else if reg_id == REG_N_F { } else if reg_id == REG_N_F {
self.flags self.flags
} else if reg_id == REG_N_HL { } 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) self.interconnect.read_byte(addr)
} else { } else {
self.regs[reg_id] self.regs[reg_id]
@ -104,6 +104,42 @@ impl CPU {
self.ip += 1; self.ip += 1;
match instruction { 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 => { 0x10 ... 0x17 => {
let reg_id = (instruction - 0x10) as usize; let reg_id = (instruction - 0x10) as usize;
let val = self.get_8bit_reg(reg_id); let val = self.get_8bit_reg(reg_id);
@ -152,6 +188,24 @@ impl CPU {
self.clear_flag(FLAG_N); self.clear_flag(FLAG_N);
self.clear_flag(FLAG_H); 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 => { 0x30 ... 0x37 => {
let reg_id = (instruction - 0x30) as usize; let reg_id = (instruction - 0x30) as usize;
if self.debug { if self.debug {
@ -296,6 +350,7 @@ impl CPU {
fn call(&mut self, dst: u16) { fn call(&mut self, dst: u16) {
let ip = self.ip; let ip = self.ip;
self.push(ip); self.push(ip);
self.dump_stack();
self.ip = dst; self.ip = dst;
} }
@ -398,7 +453,7 @@ impl CPU {
let val = self.get_8bit_reg(reg_id).wrapping_add(1); let val = self.get_8bit_reg(reg_id).wrapping_add(1);
self.set_8bit_reg(reg_id, val); self.set_8bit_reg(reg_id, val);
self.set_clear_flag(FLAG_Z, val == 0); 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); self.clear_flag(FLAG_N);
4 4
} }
@ -418,7 +473,7 @@ impl CPU {
self.set_8bit_reg(reg_id, val); self.set_8bit_reg(reg_id, val);
self.set_clear_flag(FLAG_Z, val == 0); 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); self.set_flag(FLAG_N);
4 4
} }
@ -460,6 +515,7 @@ impl CPU {
fn ret(&mut self) { fn ret(&mut self) {
let new_ip: u16 = self.pop(); let new_ip: u16 = self.pop();
self.dump_stack();
self.ip = new_ip; self.ip = new_ip;
} }
@ -544,13 +600,20 @@ impl CPU {
20 20
} }
0x09 => self.add_rr_rr(REG_N_H, REG_N_L, REG_N_B, REG_N_C), 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), 0x0B => self.dec_rr(REG_N_B, REG_N_C),
0x0C => self.reg_inc(REG_N_C), 0x0C => self.reg_inc(REG_N_C),
0x0D => self.reg_dec(REG_N_C), 0x0D => self.reg_dec(REG_N_C),
0x0E => self.ld_r_v(REG_N_C), 0x0E => self.ld_r_v(REG_N_C),
0x11 => self.ld_rr_vv(REG_N_D, REG_N_E), 0x11 => self.ld_rr_vv(REG_N_D, REG_N_E),
0x12 => self.ld_dref_rr_a(REG_D, REG_E), 0x12 => self.ld_dref_rr_a(REG_N_D, REG_N_E),
0x13 => self.inc_rr(REG_D, REG_E), 0x13 => self.inc_rr(REG_N_D, REG_N_E),
0x14 => self.reg_inc(REG_N_D), 0x14 => self.reg_inc(REG_N_D),
0x15 => self.reg_dec(REG_N_D), 0x15 => self.reg_dec(REG_N_D),
0x16 => self.ld_r_v(REG_N_D), 0x16 => self.ld_r_v(REG_N_D),
@ -559,16 +622,11 @@ impl CPU {
println!("RLA"); println!("RLA");
} }
let carry = self.flags & FLAG_C > 0; let carry = self.flags & FLAG_C > 0;
let val = self.regs[REG_A];
self.set_clear_flag(FLAG_C, val & 0x80 == 0x80);
if !carry { 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; self.regs[REG_A] = self.regs[REG_A] << 1;
} else { } else {
if self.regs[REG_A] & 0x80 == 0 {
self.clear_flag(FLAG_C);
}
self.regs[REG_A] = self.regs[REG_A] << 1 | 1; self.regs[REG_A] = self.regs[REG_A] << 1 | 1;
} }
self.clear_flag(FLAG_Z); self.clear_flag(FLAG_Z);
@ -594,28 +652,23 @@ impl CPU {
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_N_D, REG_N_E));
8 8
}, },
0x1B => self.dec_rr(REG_N_D, REG_N_E), 0x1B => self.dec_rr(REG_N_D, REG_N_E),
0x1C => self.reg_inc(REG_N_E), 0x1C => self.reg_inc(REG_N_E),
0x1D => self.reg_dec(REG_N_E), 0x1D => self.reg_dec(REG_N_E),
0x1E => self.ld_r_v(REG_N_E), 0x1E => self.ld_r_v(REG_N_E),
0x1F => { // UNTESTED 0x1F => {
if self.debug { if self.debug {
println!("RRA"); println!("RRA");
} }
let carry = self.flags & FLAG_C > 0; let carry = self.flags & FLAG_C > 0;
let val = self.regs[REG_A];
self.set_clear_flag(FLAG_C, val & 1 == 1);
if !carry { 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; self.regs[REG_A] = self.regs[REG_A] >> 1;
} else { } else {
if self.regs[REG_A] & 1 == 0 {
self.clear_flag(FLAG_C);
}
self.regs[REG_A] = self.regs[REG_A] >> 1 | 0x80; self.regs[REG_A] = self.regs[REG_A] >> 1 | 0x80;
} }
self.clear_flag(FLAG_Z); self.clear_flag(FLAG_Z);
@ -645,12 +698,12 @@ impl CPU {
if self.debug { if self.debug {
println!("LD (HL+), A"); 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.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 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), 0x24 => self.reg_inc(REG_N_H),
0x25 => self.reg_dec(REG_N_H), 0x25 => self.reg_dec(REG_N_H),
0x26 => self.ld_r_v(REG_N_H), 0x26 => self.ld_r_v(REG_N_H),
@ -677,9 +730,9 @@ impl CPU {
if self.debug { if self.debug {
println!("LD A, (HL+)"); 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.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 8
}, },
0x2B => self.dec_rr(REG_N_H, REG_N_L), 0x2B => self.dec_rr(REG_N_H, REG_N_L),
@ -691,6 +744,8 @@ impl CPU {
println!("CPL"); println!("CPL");
} }
self.regs[REG_A] = !self.regs[REG_A]; self.regs[REG_A] = !self.regs[REG_A];
self.set_flag(FLAG_N);
self.set_flag(FLAG_H);
4 4
}, },
0x30 => { 0x30 => {
@ -722,20 +777,30 @@ impl CPU {
if self.debug { if self.debug {
println!("LD (HL-), A"); 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]); self.interconnect.write_byte(addr, self.regs[REG_A]);
self.set_pair_value(REG_N_H, REG_N_L, addr.wrapping_sub(1));
addr -= 1;
self.set_pair_value(REG_H, REG_L, addr);
8 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), 0x35 => self.reg_dec(REG_N_HL),
0x36 => { 0x36 => {
let args = self.load_args(1); let args = self.load_args(1);
if self.debug { if self.debug {
println!("LD (HL), {:02x}", args[0]); 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]); self.interconnect.write_byte(addr, args[0]);
12 12
}, },
@ -744,6 +809,8 @@ impl CPU {
println!("SCF"); println!("SCF");
} }
self.set_flag(FLAG_C); self.set_flag(FLAG_C);
self.clear_flag(FLAG_N);
self.clear_flag(FLAG_H);
4 4
}, },
0x38 => { 0x38 => {
@ -768,8 +835,24 @@ impl CPU {
println!("ADD HL, SP"); println!("ADD HL, SP");
} }
let sp = self.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.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 8
} }
0x3C => self.reg_inc(REG_N_A), 0x3C => self.reg_inc(REG_N_A),
@ -780,6 +863,7 @@ impl CPU {
println!("CCF"); println!("CCF");
} }
self.flags ^= FLAG_C; self.flags ^= FLAG_C;
self.clear_flag(FLAG_N);
4 4
} }
@ -808,9 +892,14 @@ impl CPU {
if self.debug { if self.debug {
println!("ADD {}", REG_NAMES[reg_id]); 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.clear_flag(FLAG_N);
self.set_clear_flag(FLAG_Z, new == 0);
self.set_clear_flag(FLAG_C, new < old);
// TODO: H
4 4
} }
@ -818,12 +907,18 @@ impl CPU {
0x88 ... 0x8F => { 0x88 ... 0x8F => {
let reg_id = (instruction - 0x88) as usize; let reg_id = (instruction - 0x88) as usize;
println!("ADC {}", REG_NAMES[reg_id]); 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 4
} }
@ -833,14 +928,13 @@ impl CPU {
if self.debug { if self.debug {
println!("SUB {}", REG_NAMES[reg_id]); 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); self.set_flag(FLAG_N);
if self.regs[REG_A] == 0 { self.set_clear_flag(FLAG_Z, new == 0);
self.set_flag(FLAG_Z); self.set_clear_flag(FLAG_C, new > old);
} else { // TODO: H
self.clear_flag(FLAG_Z);
}
// TODO: H, C
4 4
} }
@ -850,16 +944,16 @@ impl CPU {
if self.debug { if self.debug {
println!("SBC {}", REG_NAMES[reg_id]); println!("SBC {}", 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];
if self.flags & FLAG_C == FLAG_C { let mut new = old.wrapping_sub(self.get_8bit_reg(reg_id));
self.regs[REG_A] = self.regs[REG_A].wrapping_sub(1); if self.flags & FLAG_C > 0 {
new = new.wrapping_sub(1);
} }
self.regs[REG_A] = new;
self.set_flag(FLAG_N); self.set_flag(FLAG_N);
if self.regs[REG_A] == 0 { self.set_clear_flag(FLAG_Z, new == 0);
self.set_flag(FLAG_Z); self.set_clear_flag(FLAG_C, new > old);
} else {
self.clear_flag(FLAG_Z);
}
4 4
} }
@ -876,6 +970,9 @@ impl CPU {
} else { } else {
self.clear_flag(FLAG_Z); self.clear_flag(FLAG_Z);
} }
self.clear_flag(FLAG_N);
self.set_flag(FLAG_H);
self.clear_flag(FLAG_C);
4 4
} }
@ -905,12 +1002,12 @@ impl CPU {
println!("OR {}", REG_NAMES[reg_id]); println!("OR {}", REG_NAMES[reg_id]);
} }
self.regs[REG_A] |= self.get_8bit_reg(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); self.clear_flag(FLAG_N);
if self.regs[REG_A] == 0 { self.clear_flag(FLAG_H);
self.set_flag(FLAG_Z);
} else {
self.clear_flag(FLAG_Z);
}
4 4
} }
@ -939,7 +1036,7 @@ impl CPU {
8 8
} }
}, },
0xC1 => self.pop_rr(REG_B, REG_C), 0xC1 => self.pop_rr(REG_N_B, REG_N_C),
0xC2 => { 0xC2 => {
let addr: u16 = to_u16(self.load_args(2)); let addr: u16 = to_u16(self.load_args(2));
if self.debug { if self.debug {
@ -972,7 +1069,7 @@ impl CPU {
12 12
} }
}, },
0xC5 => self.push_rr(REG_B, REG_C), 0xC5 => self.push_rr(REG_N_B, REG_N_C),
0xC6 => { 0xC6 => {
let val = self.load_args(1)[0]; let val = self.load_args(1)[0];
if self.debug { if self.debug {
@ -1056,8 +1153,8 @@ impl CPU {
8 8
} }
}, },
0xD1 => self.pop_rr(REG_D, REG_E), 0xD1 => self.pop_rr(REG_N_D, REG_N_E),
0xD5 => self.push_rr(REG_D, REG_E), 0xD5 => self.push_rr(REG_N_D, REG_N_E),
0xD6 => { 0xD6 => {
let val = self.load_args(1)[0]; let val = self.load_args(1)[0];
if self.debug { if self.debug {
@ -1083,7 +1180,8 @@ impl CPU {
} else { } else {
8 8
} }
} },
0xD9 => self.reti(),
0xDE => { 0xDE => {
let arg = self.load_args(1)[0]; let arg = self.load_args(1)[0];
if self.debug { if self.debug {
@ -1115,12 +1213,12 @@ impl CPU {
0xE2 => { 0xE2 => {
if self.debug { if self.debug {
println!("LD (C), A"); 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 8
}, },
0xE5 => self.push_rr(REG_H, REG_L), 0xE5 => self.push_rr(REG_N_H, REG_N_L),
0xE6 => { 0xE6 => {
let val = self.load_args(1)[0]; let val = self.load_args(1)[0];
if self.debug { if self.debug {
@ -1130,6 +1228,19 @@ impl CPU {
8 8
}, },
0xE7 => self.rst(0x20), 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 => { 0xE9 => {
if self.debug { if self.debug {
println!("JP (HL)"); println!("JP (HL)");
@ -1176,7 +1287,8 @@ impl CPU {
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); let addr = 0xFF00 + self.get_8bit_reg(REG_N_C) as u16;
self.regs[REG_A] = self.interconnect.read_byte(addr);
8 8
}, },
0xF3 => { 0xF3 => {
@ -1196,6 +1308,18 @@ impl CPU {
8 8
}, },
0xF7 => self.rst(0x30), 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 => { 0xFB => {
// Enable interrupts - TODO // Enable interrupts - TODO
if self.debug { if self.debug {

View File

@ -88,7 +88,7 @@ impl Display {
windowx: 0, windowx: 0,
windowy: 0, windowy: 0,
curline: 0, curline: 0,
lyc: 255, lyc: 0,
current_ticks: 0, current_ticks: 0,
current_mode: DisplayMode::default(), current_mode: DisplayMode::default(),
@ -175,10 +175,8 @@ impl Display {
// Do we want to have a time delta here? // Do we want to have a time delta here?
pub fn tick(&mut self, ticks: u16) { pub fn tick(&mut self, ticks: u16) {
self.current_ticks += ticks; self.current_ticks += ticks;
if self.curline == self.lyc { self.status &= 0xFC;
self.stat_fired = true;
self.stat_interrupt = true;
}
match self.current_mode { match self.current_mode {
DisplayMode::Scanline => { DisplayMode::Scanline => {
if self.current_ticks > TICKS_END_SCANLINE { if self.current_ticks > TICKS_END_SCANLINE {
@ -187,6 +185,7 @@ impl Display {
self.current_ticks = 0; self.current_ticks = 0;
self.current_mode = DisplayMode::Readmode; self.current_mode = DisplayMode::Readmode;
} }
self.status |= 3;
}, },
DisplayMode::Readmode => { DisplayMode::Readmode => {
if self.current_ticks > TICKS_END_READMODE { if self.current_ticks > TICKS_END_READMODE {
@ -194,6 +193,7 @@ impl Display {
self.current_mode = DisplayMode::HBlank; self.current_mode = DisplayMode::HBlank;
self.renderscan(); self.renderscan();
} }
self.status |= 2;
}, },
DisplayMode::HBlank => { DisplayMode::HBlank => {
if self.current_ticks > TICKS_END_HBLANK { if self.current_ticks > TICKS_END_HBLANK {
@ -207,6 +207,8 @@ impl Display {
self.current_mode = DisplayMode::Scanline; self.current_mode = DisplayMode::Scanline;
} }
} }
self.status &= 0xFC;
self.status |= 0;
}, },
DisplayMode::VBlank => { DisplayMode::VBlank => {
if self.current_ticks > TICKS_END_VBLANK { if self.current_ticks > TICKS_END_VBLANK {
@ -220,8 +222,18 @@ impl Display {
self.curline = 0; 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) { fn renderscan(&mut self) {

View File

@ -142,9 +142,19 @@ impl Interconnect {
0xFF10 ... 0xFF26 => { 0xFF10 ... 0xFF26 => {
self.sound.write_byte(addr, val); 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); 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 => { 0xFF50 => {
println!("Disabling boot rom."); println!("Disabling boot rom.");
self.disable_bootrom = val; self.disable_bootrom = val;