Enabling lcd and vblank flag registers

This commit is contained in:
2021-10-28 22:13:23 -05:00
parent c401726da5
commit f90900a4c1
2 changed files with 65 additions and 70 deletions
+30 -2
View File
@@ -1,5 +1,12 @@
use crate::utils::{join_bytes};
use crate::utils::{
get_bit,
set_bit,
BitIndex,
join_bytes
};
use crate::rom::ROM;
use crate::ppu::{PPU, LCDStatus, LCDStatusModeFlag};
use crate::cpu::{InterruptFlag};
pub struct AddressRange {
begin: u16,
@@ -32,6 +39,7 @@ pub const NOT_USABLE: AddressRange = AddressRange{begin: 0xFEA0,
pub const IO_REGISTERS: AddressRange = AddressRange{begin: 0xFF00, end: 0xFF7F};
pub const HIGH_RAM: AddressRange = AddressRange{begin: 0xFF80, end: 0xFFFE};
pub const INTERRUPT_ENABLE_REGISTER: AddressRange = AddressRange{begin: 0xFFFF, end: 0xFFFF};
pub const INTERRUPT_FLAG_ADDRESS: u16 = 0xFF0F;
pub struct Bus {
game_rom: ROM,
@@ -65,6 +73,10 @@ impl Bus {
pub fn read(&self, address: u16) -> u8 {
if BANK_ZERO.in_range(address) || BANK_SWITCHABLE.in_range(address) {
return self.game_rom.read(address);
} else if VIDEO_RAM.in_range(address) {
if PPU::get_lcd_status(self, LCDStatus::ModeFlag(LCDStatusModeFlag::TransferringToLCD)) {
return 0xFF
}
} else if IO_REGISTERS.in_range(address) {
return self.data[address as usize];
}
@@ -91,8 +103,13 @@ impl Bus {
} else if ECHO_RAM.in_range(address) {
self.data[address as usize] = data;
self.data[(WORK_RAM_1.begin() + (address - ECHO_RAM.begin())) as usize] = data; // Copy to the working RAM
} else if VIDEO_RAM.in_range(address) {
//if !PPU::get_lcd_status(self, LCDStatus::ModeFlag(LCDStatusModeFlag::TransferringToLCD)) {
self.data[address as usize] = data;
// }
} else {
self.data[address as usize] = data;
}
self.data[address as usize] = data;
}
pub fn write_16bit(&mut self, address: u16, data: u16) {
@@ -100,4 +117,15 @@ impl Bus {
self.write(address, bytes[0]);
self.write(address.wrapping_add(1), bytes[1]);
}
pub fn set_flag(&mut self, flag: InterruptFlag, val: bool) {
let byte = self.read(INTERRUPT_FLAG_ADDRESS);
self.write(INTERRUPT_FLAG_ADDRESS, match flag {
InterruptFlag::VBlank => set_bit(byte, val, BitIndex::I0),
InterruptFlag::LCDSTAT => set_bit(byte, val, BitIndex::I1),
InterruptFlag::Timer => set_bit(byte, val, BitIndex::I2),
InterruptFlag::Serial => set_bit(byte, val, BitIndex::I3),
InterruptFlag::Joypad => set_bit(byte, val, BitIndex::I4),
});
}
}