Add VRAM DMA; Add basic timer support
This commit is contained in:
parent
6d675616f1
commit
44c8b2e7d8
@ -1050,7 +1050,9 @@ impl CPU {
|
||||
// ADC
|
||||
0x88 ... 0x8F => {
|
||||
let reg_id = (instruction - 0x88) as usize;
|
||||
println!("ADC {}", REG_NAMES[reg_id]);
|
||||
if self.debug {
|
||||
println!("ADC {}", REG_NAMES[reg_id]);
|
||||
}
|
||||
|
||||
let old = self.regs[REG_A];
|
||||
let mut new = old.wrapping_add(self.get_8bit_reg(reg_id));
|
||||
|
||||
@ -27,7 +27,10 @@ pub struct Interconnect {
|
||||
serial: serial::Serial,
|
||||
timer: timer::Timer,
|
||||
|
||||
|
||||
vram_dma_source_high: u8,
|
||||
vram_dma_source_low: u8,
|
||||
vram_dma_destination_high: u8,
|
||||
vram_dma_destination_low: u8,
|
||||
}
|
||||
|
||||
impl Interconnect {
|
||||
@ -37,7 +40,7 @@ impl Interconnect {
|
||||
cartridge: cartridge::Cartridge::new(rom),
|
||||
ram: vec![0; WRAM_SIZE].into_boxed_slice(),
|
||||
hiram: vec![0; HIRAM_SIZE].into_boxed_slice(),
|
||||
wram_bank: 0,
|
||||
wram_bank: 1,
|
||||
sound: sound::Sound::new(),
|
||||
display: display::Display::new(),
|
||||
// Refactor those
|
||||
@ -48,12 +51,17 @@ impl Interconnect {
|
||||
timer: timer::Timer::new(),
|
||||
serial: serial::Serial::new(),
|
||||
|
||||
vram_dma_source_high: 0,
|
||||
vram_dma_source_low: 0,
|
||||
vram_dma_destination_high: 0,
|
||||
vram_dma_destination_low: 0,
|
||||
}
|
||||
}
|
||||
|
||||
// Somehow we need different timers for this.
|
||||
pub fn tick(&mut self, cycles: u8) {
|
||||
self.display.tick(cycles as u16 * 4);
|
||||
self.timer.tick(cycles as u16 * 4);
|
||||
|
||||
if self.display.vblank_interrupt() {
|
||||
self.interrupt_request_flags |= INTERRUPT_DISPLAY_VBLANK;
|
||||
@ -108,6 +116,14 @@ impl Interconnect {
|
||||
0xFF50 => {
|
||||
self.disable_bootrom
|
||||
},
|
||||
0xFF51 => self.vram_dma_source_high,
|
||||
0xFF52 => self.vram_dma_source_low,
|
||||
0xFF53 => self.vram_dma_destination_high,
|
||||
0xFF54 => self.vram_dma_destination_low,
|
||||
0xFF55 => {
|
||||
println!("Read from 0xFF55 (DMA length/mode/start) not fully supported");
|
||||
0xFF
|
||||
}
|
||||
0xFF56 => {
|
||||
self.infrared_com_port
|
||||
},
|
||||
@ -163,7 +179,7 @@ impl Interconnect {
|
||||
self.display.write_byte(addr, val);
|
||||
},
|
||||
0xFF46 => {
|
||||
println!("DMA transfer: ");
|
||||
println!("OAM 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);
|
||||
@ -175,10 +191,30 @@ impl Interconnect {
|
||||
println!("Disabling boot rom.");
|
||||
self.disable_bootrom = val;
|
||||
},
|
||||
0xFF51 => self.vram_dma_source_high = val,
|
||||
0xFF52 => self.vram_dma_source_low = val,
|
||||
0xFF53 => self.vram_dma_destination_high = val,
|
||||
0xFF54 => self.vram_dma_destination_low = val,
|
||||
0xFF55 => {
|
||||
let src: u16 = ((self.vram_dma_source_high as u16) << 8) | self.vram_dma_source_low as u16;
|
||||
let dst: u16 = ((self.vram_dma_destination_high as u16) << 8) | self.vram_dma_destination_low as u16;
|
||||
println!("VRAM DMA transfer from {:04X} to {:04X}; {:02X}", src, dst, val);
|
||||
let len: u16 = ((val & 0x7F) + 1) as u16 * 0x10 - 1;
|
||||
for i in 0..len {
|
||||
let v = self.read_byte(src.wrapping_add(i));
|
||||
self.write_byte(dst.wrapping_add(i), v);
|
||||
}
|
||||
}
|
||||
0xFF56 => {
|
||||
self.infrared_com_port = val;
|
||||
},
|
||||
0xFF70 => self.wram_bank = val,
|
||||
0xFF70 => {
|
||||
println!("Set wram bank to {:02X}", val);
|
||||
if val > 7 {
|
||||
panic!("R u sure this is correct?");
|
||||
}
|
||||
self.wram_bank = val;
|
||||
}
|
||||
0xFF80 ... 0xFFFE => {
|
||||
self.hiram[(addr - 0xFF80) as usize] = val;
|
||||
},
|
||||
|
||||
11
src/timer.rs
11
src/timer.rs
@ -3,7 +3,8 @@ pub struct Timer {
|
||||
tima: u8,
|
||||
tma: u8,
|
||||
tac: u8,
|
||||
timer_interrupt: bool
|
||||
timer_interrupt: bool,
|
||||
ctr: u16,
|
||||
}
|
||||
|
||||
impl Timer {
|
||||
@ -11,6 +12,14 @@ impl Timer {
|
||||
Timer::default()
|
||||
}
|
||||
|
||||
pub fn tick(&mut self, ticks: u16) {
|
||||
self.ctr += ticks;
|
||||
if self.ctr > 0x1000 {
|
||||
self.ctr = 0;
|
||||
self.timer_interrupt = true;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_byte(&mut self, addr: u16, val: u8) {
|
||||
match addr {
|
||||
0xFF05 => self.tima = val,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user