2017-01-16 21:02:56 +00:00
|
|
|
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);
|
2017-01-16 21:02:56 +00:00
|
|
|
} 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
|
Update to v101r35 release.
byuu says:
Changelog:
- PCE: added 384KB HuCard ROM mirroring mode
- PCE: corrected D-pad polling order
- PCE: corrected palette color ordering (GRB, not RGB -- yes,
seriously)
- PCE: corrected SATB DMA -- should write to SATB, not to VRAM
- PCE: broke out Background, Sprite VDC settings to separate
subclasses
- PCE: emulated VDC backgrounds
- PCE: emulated VDC sprites
- PCE: emulated VDC sprite overflow, collision interrupts
- HuC6280: fixed disassembler output for STi instructions
- HuC6280: added missing LastCycle check to interrupt()
- HuC6280: fixed BIT, CMP, CPX, CPY, TRB, TSB, TST flag testing and
result
- HuC6280: added extra cycle delays to the block move instructions
- HuC6280: fixed ordering for flag set/clear instructions (happens
after LastCycle check)
- HuC6280: removed extra cycle from immediate instructions
- HuC6280: fixed indirectLoad, indirectYStore absolute addressing
- HuC6280: fixed BBR, BBS zeropage value testing
- HuC6280: fixed stack push/pull direction
Neutopia looks okay until the main title screen, then there's some
gibberish on the bottom. The game also locks up with some gibberish once
you actually start a new game. So, still not playable just yet =(
2017-01-19 08:38:57 +00:00
|
|
|
background.hscroll.byte(a0) = data;
|
2017-01-16 21:02:56 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(io.address == 0x08) {
|
|
|
|
//BYR
|
Update to v101r35 release.
byuu says:
Changelog:
- PCE: added 384KB HuCard ROM mirroring mode
- PCE: corrected D-pad polling order
- PCE: corrected palette color ordering (GRB, not RGB -- yes,
seriously)
- PCE: corrected SATB DMA -- should write to SATB, not to VRAM
- PCE: broke out Background, Sprite VDC settings to separate
subclasses
- PCE: emulated VDC backgrounds
- PCE: emulated VDC sprites
- PCE: emulated VDC sprite overflow, collision interrupts
- HuC6280: fixed disassembler output for STi instructions
- HuC6280: added missing LastCycle check to interrupt()
- HuC6280: fixed BIT, CMP, CPX, CPY, TRB, TSB, TST flag testing and
result
- HuC6280: added extra cycle delays to the block move instructions
- HuC6280: fixed ordering for flag set/clear instructions (happens
after LastCycle check)
- HuC6280: removed extra cycle from immediate instructions
- HuC6280: fixed indirectLoad, indirectYStore absolute addressing
- HuC6280: fixed BBR, BBS zeropage value testing
- HuC6280: fixed stack push/pull direction
Neutopia looks okay until the main title screen, then there's some
gibberish on the bottom. The game also locks up with some gibberish once
you actually start a new game. So, still not playable just yet =(
2017-01-19 08:38:57 +00:00
|
|
|
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;
|
2017-01-16 21:02:56 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(io.address == 0x09) {
|
|
|
|
//MWR
|
|
|
|
if(a0) return;
|
|
|
|
io.vramAccess = data.bits(0,1);
|
|
|
|
io.spriteAccess = data.bits(2,3);
|
Update to v101r35 release.
byuu says:
Changelog:
- PCE: added 384KB HuCard ROM mirroring mode
- PCE: corrected D-pad polling order
- PCE: corrected palette color ordering (GRB, not RGB -- yes,
seriously)
- PCE: corrected SATB DMA -- should write to SATB, not to VRAM
- PCE: broke out Background, Sprite VDC settings to separate
subclasses
- PCE: emulated VDC backgrounds
- PCE: emulated VDC sprites
- PCE: emulated VDC sprite overflow, collision interrupts
- HuC6280: fixed disassembler output for STi instructions
- HuC6280: added missing LastCycle check to interrupt()
- HuC6280: fixed BIT, CMP, CPX, CPY, TRB, TSB, TST flag testing and
result
- HuC6280: added extra cycle delays to the block move instructions
- HuC6280: fixed ordering for flag set/clear instructions (happens
after LastCycle check)
- HuC6280: removed extra cycle from immediate instructions
- HuC6280: fixed indirectLoad, indirectYStore absolute addressing
- HuC6280: fixed BBR, BBS zeropage value testing
- HuC6280: fixed stack push/pull direction
Neutopia looks okay until the main title screen, then there's some
gibberish on the bottom. The game also locks up with some gibberish once
you actually start a new game. So, still not playable just yet =(
2017-01-19 08:38:57 +00:00
|
|
|
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;
|
2017-01-16 21:02:56 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|