bsnes/higan/pce/cpu/io.cpp

148 lines
2.9 KiB
C++

auto CPU::read(uint21 addr) -> uint8 {
//$000000-0fffff HuCard
if(!addr.bit(20)) {
return cartridge.read(addr);
}
uint8 bank = addr.bits(13,20);
addr = addr.bits(0,12);
//$1f8000-1fbfff RAM
if(bank >= 0xf8 && bank <= 0xfb) {
return ram[addr];
}
//$1fe000-$1fffff Hardware
if(bank == 0xff) {
//$0000-03ff VDC
//$0400-07ff VCE
if((addr & 0x1800) == 0x0000) {
return vdc.read(addr);
}
//$0800-0bff PSG
if((addr & 0x1c00) == 0x0800) {
return 0x00;
}
//$0c00-0fff Timer
if((addr & 0x1c00) == 0x0c00) {
return timer.value;
}
//$1000-13ff I/O
if((addr & 0x1c00) == 0x1000) {
return (
PCEngine::peripherals.controllerPort->readData() << 0
| 1 << 4
| 1 << 5
| 0 << 6 //device (0 = Turbografx-16; 1 = PC Engine)
| 1 << 7 //add-on (0 = CD-ROM; 1 = nothing)
);
}
//$1400-17ff IRQ
if((addr & 0x1c00) == 0x1400) {
if(addr.bits(0,1) == 2) {
return (
irq.disableExternal << 0
| irq.disableVDC << 1
| irq.disableTimer << 2
);
}
if(addr.bits(0,1) == 3) {
return (
irq.pendingExternal << 0
| irq.pendingVDC << 1
| irq.pendingTimer << 2
);
}
}
//$1800-1bff CD-ROM
if((addr & 0x1c00) == 0x1800) {
return 0xff;
}
//$1c00-1fff unmapped
if((addr & 0x1c00) == 0x1c00) {
return 0xff;
}
}
return 0x00;
}
auto CPU::write(uint21 addr, uint8 data) -> void {
//$000000-0fffff HuCard
if(!addr.bit(20)) {
return cartridge.write(addr, data);
}
uint8 bank = addr.bits(13,20);
addr = addr.bits(0,12);
//$1f8000-1fbfff RAM
if(bank >= 0xf8 && bank <= 0xfb) {
ram[addr] = data;
return;
}
//$1fe000-1fffff Hardware
if(bank == 0xff) {
//$0000-03ff VDC
//$0400-07ff VCE
if((addr & 0x1800) == 0x0000) {
return vdc.write(addr, data);
}
//$0800-0bff PSG
if((addr & 0x1c00) == 0x0800) {
return;
}
//$0c00-0fff Timer
if((addr & 0x1c00) == 0x0c00) {
if(!addr.bit(0)) {
timer.latch = data.bits(0,6);
} else {
timer.enable = data.bit(0);
if(timer.enable) timer.start();
}
return;
}
//$1000-13ff I/O
if((addr & 0x1c00) == 0x1000) {
PCEngine::peripherals.controllerPort->writeData(data.bits(0,1));
return;
}
//$1400-17ff IRQ
if((addr & 0x1c00) == 0x1400) {
if(addr.bits(0,1) == 2) {
irq.disableExternal = data.bit(0);
irq.disableVDC = data.bit(1);
irq.disableTimer = data.bit(2);
return;
}
if(addr.bits(0,1) == 3) {
irq.level(IRQ::Line::Timer, 0);
return;
}
}
//$1800-1bff CD-ROM
if((addr & 0x1c00) == 0x1800) {
return;
}
//$1c00-1fff unmapped
if((addr & 0x1c00) == 0x1c00) {
return;
}
}
}