bsnes/higan/pce/vdc/io.cpp

265 lines
6.1 KiB
C++

auto VDC::vramRead(uint16 addr) -> uint16 {
if(addr.bit(15)) return 0x00;
return vram[addr];
}
auto VDC::vramWrite(uint16 addr, uint16 data) -> void {
if(addr.bit(15)) return;
vram[addr] = data;
}
auto VDC::read(uint11 addr) -> uint8 {
bool a0 = addr.bit(0);
if(!addr.bit(10)) {
//VDC
if(addr.bit(1) == 0) {
//SR
if(a0) return 0x00;
uint8 data;
data.bit(0) = irq.pendingCollision;
data.bit(1) = irq.pendingOverflow;
data.bit(2) = irq.pendingLineCoincidence;
data.bit(3) = irq.pendingTransferSATB;
data.bit(4) = irq.pendingTransferVRAM;
data.bit(5) = irq.pendingVblank;
irq.lower();
return data;
}
if(addr.bit(1) == 1) {
if(io.address == 0x02) {
//VRR
uint8 data = io.vramDataRead.byte(a0);
if(a0) {
io.vramAddressRead += io.vramAddressIncrement;
io.vramDataRead = vramRead(io.vramAddressRead);
}
return data;
}
}
} else {
//VCE
if(addr.bits(0,2) == 0x04) {
//CTR
uint8 data = cram[io.colorAddress].bits(0,7);
return data;
}
if(addr.bits(0,2) == 0x05) {
//CTR
uint8 data = cram[io.colorAddress].bit(0);
io.colorAddress++;
return data;
}
}
return 0x00;
}
auto VDC::write(uint11 addr, uint8 data) -> void {
bool a0 = addr.bit(0);
if(!addr.bit(10)) {
//VDC
if(addr.bit(1) == 0) {
//AR
if(a0) return;
io.address = data.bits(0,4);
return;
}
if(addr.bit(1) == 1) {
if(io.address == 0x00) {
//MAWR
io.vramAddressWrite.byte(a0) = data;
return;
}
if(io.address == 0x01) {
//MARR
io.vramAddressRead.byte(a0) = data;
io.vramDataRead = vramRead(io.vramAddressRead);
return;
}
if(io.address == 0x02) {
//VWR
io.vramDataWrite.byte(a0) = data;
if(a0) {
vramWrite(io.vramAddressWrite, io.vramDataWrite);
io.vramAddressWrite += io.vramAddressIncrement;
}
return;
}
if(io.address == 0x05) {
//CR
if(!a0) {
irq.enableCollision = data.bit(0);
irq.enableOverflow = data.bit(1);
irq.enableLineCoincidence = data.bit(2);
irq.enableVblank = data.bit(3);
io.externalSync = data.bits(4,5);
sprite.enable = data.bit(6);
background.enable = data.bit(7);
} else {
io.displayOutput = data.bits(0,1);
io.dramRefresh = data.bit(2);
if(data.bits(3,4) == 0) io.vramAddressIncrement = 0x01;
if(data.bits(3,4) == 1) io.vramAddressIncrement = 0x20;
if(data.bits(3,4) == 2) io.vramAddressIncrement = 0x40;
if(data.bits(3,4) == 3) io.vramAddressIncrement = 0x80;
}
return;
}
if(io.address == 0x06) {
//RCR
io.lineCoincidence.byte(a0) = data;
return;
}
if(io.address == 0x07) {
//BXR
background.hscroll.byte(a0) = data;
return;
}
if(io.address == 0x08) {
//BYR
background.vscroll.byte(a0) = data;
background.voffset = background.vscroll;
return;
}
if(io.address == 0x09) {
//MWR
if(a0) return;
io.vramAccess = data.bits(0,1);
io.spriteAccess = data.bits(2,3);
if(data.bits(4,5) == 0) background.width = 32;
if(data.bits(4,5) == 1) background.width = 64;
if(data.bits(4,5) == 2) background.width = 128;
if(data.bits(4,5) == 3) background.width = 128;
if(data.bit(6) == 0) background.height = 32;
if(data.bit(6) == 1) background.height = 64;
io.cgMode = data.bit(7);
return;
}
if(io.address == 0x0a) {
//HSR
if(!a0) {
io.horizontalSyncWidth = data.bits(0,4);
} else {
io.horizontalDisplayStart = data.bits(0,6);
}
return;
}
if(io.address == 0x0b) {
//HDR
if(!a0) {
io.horizontalDisplayWidth = data.bits(0,6);
} else {
io.horizontalDisplayEnd = data.bits(0,6);
}
return;
}
if(io.address == 0x0c) {
//VPR
if(!a0) {
io.verticalSyncWidth = data.bits(0,4);
} else {
io.verticalDisplayStart = data.bits(0,7);
}
return;
}
if(io.address == 0x0d) {
//VDR
io.verticalDisplayWidth.byte(a0) = data;
return;
}
if(io.address == 0x0e) {
//VCR
if(a0) return;
io.verticalDisplayEnd = data.bits(0,7);
return;
}
if(io.address == 0x0f) {
//DCR
if(a0) return;
irq.enableTransferVRAM = data.bit(0);
irq.enableTransferSATB = data.bit(1);
dma.sourceIncrementMode = data.bit(2);
dma.targetIncrementMode = data.bit(3);
dma.satbRepeat = data.bit(4);
return;
}
if(io.address == 0x10) {
//SOUR
dma.source.byte(a0) = data;
return;
}
if(io.address == 0x11) {
//DESR
dma.target.byte(a0) = data;
return;
}
if(io.address == 0x12) {
//LENR
dma.length.byte(a0) = data;
if(a0) dma.vramStart();
return;
}
if(io.address == 0x13) {
//DVSSR
dma.satbSource.byte(a0) = data;
if(a0) dma.satbQueue();
return;
}
}
} else {
//VCE
if(addr.bits(0,2) == 0x00) {
//CR
io.divisionRatio = data.bits(0,1);
io.colorBlur = data.bit(2);
io.grayscale = data.bit(7);
return;
}
if(addr.bits(0,2) == 0x02) {
//CTA
io.colorAddress.bits(0,7) = data.bits(0,7);
return;
}
if(addr.bits(0,2) == 0x03) {
//CTA
io.colorAddress.bit(8) = data.bit(0);
return;
}
if(addr.bits(0,2) == 0x04) {
//CTW
cram[io.colorAddress].bits(0,7) = data.bits(0,7);
return;
}
if(addr.bits(0,2) == 0x05) {
//CTW
cram[io.colorAddress].bit(8) = data.bit(0);
io.colorAddress++;
return;
}
}
}