fix: implement 0xff41 and fix CALL instruciton
This commit is contained in:
parent
386a780a6f
commit
9203b61533
|
@ -108,6 +108,10 @@ impl Bus {
|
|||
0xFF25 => self.sound.control.select.into(),
|
||||
0xFF26 => self.sound.control.status.into(),
|
||||
0xFF40 => self.ppu.lcd_control.into(),
|
||||
0xFF41 => self.ppu.stat.into(),
|
||||
0xFF42 => self.ppu.pos.scroll_y,
|
||||
0xFF43 => self.ppu.pos.scroll_x,
|
||||
0xFF44 => self.ppu.pos.line_y,
|
||||
0xFF47 => self.ppu.monochrome.bg_palette.into(),
|
||||
_ => unimplemented!("Unable to read {:#06X} in I/O Registers", addr),
|
||||
}
|
||||
|
@ -172,6 +176,10 @@ impl Bus {
|
|||
0xFF25 => self.sound.control.select = byte.into(),
|
||||
0xFF26 => self.sound.control.status = byte.into(), // FIXME: Should we control which bytes are written to here?
|
||||
0xFF40 => self.ppu.lcd_control = byte.into(),
|
||||
0xFF41 => self.ppu.stat = byte.into(),
|
||||
0xFF42 => self.ppu.pos.scroll_y = byte,
|
||||
0xFF43 => self.ppu.pos.scroll_x = byte,
|
||||
0xFF44 => self.ppu.pos.line_y = byte,
|
||||
0xFF47 => self.ppu.monochrome.bg_palette = byte.into(),
|
||||
_ => unimplemented!("Unable to write to {:#06X} in I/O Registers", addr),
|
||||
};
|
||||
|
|
|
@ -70,10 +70,10 @@ impl Cpu {
|
|||
let hl = self.register_pair(RegisterPair::HL);
|
||||
let sp = self.register_pair(RegisterPair::SP);
|
||||
|
||||
println!(
|
||||
"A: {:#04X} | BC: {:#06X} | DE: {:#06X} | HL: {:#06X} | SP: {:#06X} | {}",
|
||||
a, bc, de, hl, sp, flag
|
||||
);
|
||||
// println!(
|
||||
// "A: {:#04X} | BC: {:#06X} | DE: {:#06X} | HL: {:#06X} | SP: {:#06X} | {}",
|
||||
// a, bc, de, hl, sp, flag
|
||||
// );
|
||||
|
||||
// Get info from serial port
|
||||
// if self.bus.read_byte(0xFF02) == 0x81 {
|
||||
|
|
|
@ -61,7 +61,7 @@ pub enum Registers {
|
|||
Word(RegisterPair),
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum MATHTarget {
|
||||
HL,
|
||||
SP,
|
||||
|
@ -1026,39 +1026,39 @@ impl Instruction {
|
|||
match cond {
|
||||
JumpCondition::NotZero => {
|
||||
if !flags.z {
|
||||
Self::push(cpu, nn);
|
||||
cpu.set_register_pair(RegisterPair::PC, pc + 1);
|
||||
Self::push(cpu, pc);
|
||||
cpu.set_register_pair(RegisterPair::PC, nn);
|
||||
return Cycles(24);
|
||||
}
|
||||
Cycles(12)
|
||||
}
|
||||
JumpCondition::Zero => {
|
||||
if flags.z {
|
||||
Self::push(cpu, nn);
|
||||
cpu.set_register_pair(RegisterPair::PC, pc + 1);
|
||||
Self::push(cpu, pc);
|
||||
cpu.set_register_pair(RegisterPair::PC, nn);
|
||||
return Cycles(24);
|
||||
}
|
||||
Cycles(12)
|
||||
}
|
||||
JumpCondition::NotCarry => {
|
||||
if !flags.c {
|
||||
Self::push(cpu, nn);
|
||||
cpu.set_register_pair(RegisterPair::PC, pc + 1);
|
||||
Self::push(cpu, pc);
|
||||
cpu.set_register_pair(RegisterPair::PC, nn);
|
||||
return Cycles(24);
|
||||
}
|
||||
Cycles(12)
|
||||
}
|
||||
JumpCondition::Carry => {
|
||||
if flags.c {
|
||||
Self::push(cpu, nn);
|
||||
cpu.set_register_pair(RegisterPair::PC, pc + 1);
|
||||
Self::push(cpu, pc);
|
||||
cpu.set_register_pair(RegisterPair::PC, nn);
|
||||
return Cycles(24);
|
||||
}
|
||||
Cycles(12)
|
||||
}
|
||||
JumpCondition::Always => {
|
||||
Self::push(cpu, nn);
|
||||
cpu.set_register_pair(RegisterPair::PC, pc + 1);
|
||||
Self::push(cpu, pc);
|
||||
cpu.set_register_pair(RegisterPair::PC, nn);
|
||||
Cycles(24)
|
||||
}
|
||||
}
|
||||
|
@ -2038,14 +2038,26 @@ impl std::fmt::Debug for LDTarget {
|
|||
match *self {
|
||||
LDTarget::IndirectC => f.write_str("IndirectC"),
|
||||
LDTarget::Register(reg) => write!(f, "{:?}", reg),
|
||||
LDTarget::IndirectRegister(pair) => write!(f, "{:?}", pair),
|
||||
LDTarget::ByteAtAddress(addr) => write!(f, "{:#06X}", addr),
|
||||
LDTarget::IndirectRegister(pair) => write!(f, "[{:?}]", pair),
|
||||
LDTarget::ByteAtAddress(addr) => write!(f, "[{:#06X}]", addr),
|
||||
LDTarget::ImmediateWord(word) => write!(f, "{:#06X}", word),
|
||||
LDTarget::ImmediateByte(byte) => write!(f, "{:#04X}", byte),
|
||||
LDTarget::RegisterPair(pair) => write!(f, "{:?}", pair),
|
||||
LDTarget::ByteAtAddressWithOffset(byte) => {
|
||||
write!(f, "{:#04X}", 0xFF00 + byte as u16)
|
||||
write!(f, "[0xFF00 + {:#04X}, {:#06X}]", byte, 0xFF00 + byte as u16)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for MATHTarget {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match *self {
|
||||
MATHTarget::HL => f.write_str("HL"),
|
||||
MATHTarget::SP => f.write_str("SP"),
|
||||
MATHTarget::Register(reg) => write!(f, "{:?}", reg),
|
||||
MATHTarget::RegisterPair(pair) => write!(f, "{:?}", pair),
|
||||
MATHTarget::ImmediateByte(byte) => write!(f, "{:#04X}", byte),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ fn main() {
|
|||
let instruction = game_boy.decode(opcode);
|
||||
|
||||
println!(
|
||||
"\nAddr: {:#06X} | Opcode: {:#04X} | Instr: {:X?}",
|
||||
"Addr: {:#06X} | Opcode: {:#04X} | Instr: {:X?}",
|
||||
pc, opcode, instruction
|
||||
);
|
||||
|
||||
|
|
45
src/ppu.rs
45
src/ppu.rs
|
@ -2,7 +2,9 @@
|
|||
pub struct PPU {
|
||||
pub lcd_control: LCDControl,
|
||||
pub monochrome: Monochrome,
|
||||
pub pos: ScreenPosition,
|
||||
pub vram: Box<[u8]>,
|
||||
pub stat: LCDStatus,
|
||||
}
|
||||
|
||||
impl Default for PPU {
|
||||
|
@ -10,11 +12,54 @@ impl Default for PPU {
|
|||
Self {
|
||||
lcd_control: Default::default(),
|
||||
monochrome: Default::default(),
|
||||
pos: Default::default(),
|
||||
stat: Default::default(),
|
||||
vram: vec![0; 8192].into_boxed_slice(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct LCDStatus {
|
||||
lyc_eq_ly: bool,
|
||||
mode2_stat: bool,
|
||||
mode1_stat: bool,
|
||||
mode0_stat: bool,
|
||||
coincidence: bool,
|
||||
ppu_mode: u8,
|
||||
}
|
||||
|
||||
impl From<u8> for LCDStatus {
|
||||
fn from(byte: u8) -> Self {
|
||||
Self {
|
||||
lyc_eq_ly: (byte >> 6) & 0x01 == 0x01,
|
||||
mode2_stat: (byte >> 5) & 0x01 == 0x01,
|
||||
mode1_stat: (byte >> 4) & 0x01 == 0x01,
|
||||
mode0_stat: (byte >> 3) & 0x01 == 0x01,
|
||||
coincidence: (byte >> 2) & 0x01 == 0x01,
|
||||
ppu_mode: byte & 0x03,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<LCDStatus> for u8 {
|
||||
fn from(status: LCDStatus) -> Self {
|
||||
0x80 | (status.lyc_eq_ly as u8) << 6
|
||||
| (status.mode2_stat as u8) << 5
|
||||
| (status.mode1_stat as u8) << 4
|
||||
| (status.mode0_stat as u8) << 3
|
||||
| (status.coincidence as u8) << 2
|
||||
| (status.ppu_mode & 0x03)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct ScreenPosition {
|
||||
pub scroll_y: u8,
|
||||
pub scroll_x: u8,
|
||||
pub line_y: u8,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct Monochrome {
|
||||
pub bg_palette: BackgroundPalette,
|
||||
|
|
Loading…
Reference in New Issue