bsnes/higan/pce/vdc/io.cpp

265 lines
6.1 KiB
C++
Raw Normal View History

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);
Update to v102 release. byuu says (in the public announcement): This release adds very preliminary emulation of the Sega Master System (Mark III), Sega Game Gear, Sega Mega Drive (Genesis), and NEC PC Engine (Turbografx-16). These cores do not yet offer sound emulation, save states or cheat codes. I'm always very hesitant to release a new emulation core in its alpha stages, as in the past this has resulted in lasting bad impressions of cores that have since improved greatly. For instance, the Game Boy Advance emulation offered today is easily the second most accurate around, yet it is still widely judged by its much older alpha implementation. However, it's always been tradition with higan to not hold onto code in secret. Rather than delay future releases for another year or two, I'll put my faith in you all to understand that the emulation of these systems will improve over time. I hope that by releasing things as they are now, I might be able to receive some much needed assistance in improving these cores, as the documentation for these new systems is very much less than ideal. byuu says (in the WIP forum): Changelog: - PCE: latch background scroll registers (fixes Neutopia scrolling) - PCE: clip background attribute table scrolling (fixes Blazing Lazers scrolling) - PCE: support background/sprite enable/disable bits - PCE: fix large sprite indexing (fixes Blazing Lazers title screen sprites) - HuC6280: wrap zeropage accesses to never go beyond $20xx - HuC6280: fix alternating addresses for block move instructions (fixes Neutopia II) - HuC6280: block move instructions save and restore A,X,Y registers - HuC6280: emulate BCD mode (may not be 100% correct, based on SNES BCD) (fixes Blazing Lazers scoring)
2017-01-19 21:01:15 +00:00
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;
Update to v102 release. byuu says (in the public announcement): This release adds very preliminary emulation of the Sega Master System (Mark III), Sega Game Gear, Sega Mega Drive (Genesis), and NEC PC Engine (Turbografx-16). These cores do not yet offer sound emulation, save states or cheat codes. I'm always very hesitant to release a new emulation core in its alpha stages, as in the past this has resulted in lasting bad impressions of cores that have since improved greatly. For instance, the Game Boy Advance emulation offered today is easily the second most accurate around, yet it is still widely judged by its much older alpha implementation. However, it's always been tradition with higan to not hold onto code in secret. Rather than delay future releases for another year or two, I'll put my faith in you all to understand that the emulation of these systems will improve over time. I hope that by releasing things as they are now, I might be able to receive some much needed assistance in improving these cores, as the documentation for these new systems is very much less than ideal. byuu says (in the WIP forum): Changelog: - PCE: latch background scroll registers (fixes Neutopia scrolling) - PCE: clip background attribute table scrolling (fixes Blazing Lazers scrolling) - PCE: support background/sprite enable/disable bits - PCE: fix large sprite indexing (fixes Blazing Lazers title screen sprites) - HuC6280: wrap zeropage accesses to never go beyond $20xx - HuC6280: fix alternating addresses for block move instructions (fixes Neutopia II) - HuC6280: block move instructions save and restore A,X,Y registers - HuC6280: emulate BCD mode (may not be 100% correct, based on SNES BCD) (fixes Blazing Lazers scoring)
2017-01-19 21:01:15 +00:00
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;
}
}
}