Update to v101r24 release.
byuu says:
Changelog:
- SMS: extended bus mapping of in/out ports: now decoding them fully
inside ms/bus
- SMS: moved Z80 disassembly code from processor/z80 to ms/cpu
(cosmetic)
- SMS: hooked up non-functional silent PSG sample generation, so I can
cap the framerate at 60fps
- SMS: hooked up the VDP main loop: 684 clocks/scanline, 262
scanlines/frame (no PAL support yet)
- SMS: emulated the VDP Vcounter and Hcounter polling ... hopefully
it's right, as it's very bizarre
- SMS: emulated VDP in/out ports (data read, data write, status read,
control write, register write)
- SMS: decoding and caching all VDP register flags (variable names
will probably change)
- nall: \#undef IN on Windows port (prevent compilation warning on
processor/z80)
Watching Sonic the Hedgehog, I can definitely see some VDP register
writes going through, which is a good sign.
Probably the big thing that's needed before I can get enough into the
VDP to start showing graphics is interrupt support. And interrupts are
never fun to figure out :/
What really sucks on this front is I'm flying blind on the Z80 CPU core.
Without a working VDP, I can't run any Z80 test ROMs to look for CPU
bugs. And the CPU is certainly too buggy still to run said test ROM
anyway. I can't find any SMS emulators with trace logging from reset.
Such logs vastly accelerate tracking down CPU logic bugs, so without
them, it's going to take a lot longer.
2016-12-17 11:31:34 +00:00
|
|
|
auto VDP::vcounter() -> uint8 {
|
|
|
|
if(io.lines240) {
|
|
|
|
//NTSC 256x240
|
|
|
|
return io.vcounter;
|
|
|
|
} else if(io.lines224) {
|
|
|
|
//NTSC 256x224
|
|
|
|
return io.vcounter <= 234 ? io.vcounter : io.vcounter - 6;
|
|
|
|
} else {
|
|
|
|
//NTSC 256x192
|
|
|
|
return io.vcounter <= 218 ? io.vcounter : io.vcounter - 6;
|
|
|
|
}
|
|
|
|
|
|
|
|
unreachable;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto VDP::hcounter() -> uint8 {
|
2016-12-26 12:09:56 +00:00
|
|
|
uint hcounter = io.hcounter >> 1;
|
Update to v101r24 release.
byuu says:
Changelog:
- SMS: extended bus mapping of in/out ports: now decoding them fully
inside ms/bus
- SMS: moved Z80 disassembly code from processor/z80 to ms/cpu
(cosmetic)
- SMS: hooked up non-functional silent PSG sample generation, so I can
cap the framerate at 60fps
- SMS: hooked up the VDP main loop: 684 clocks/scanline, 262
scanlines/frame (no PAL support yet)
- SMS: emulated the VDP Vcounter and Hcounter polling ... hopefully
it's right, as it's very bizarre
- SMS: emulated VDP in/out ports (data read, data write, status read,
control write, register write)
- SMS: decoding and caching all VDP register flags (variable names
will probably change)
- nall: \#undef IN on Windows port (prevent compilation warning on
processor/z80)
Watching Sonic the Hedgehog, I can definitely see some VDP register
writes going through, which is a good sign.
Probably the big thing that's needed before I can get enough into the
VDP to start showing graphics is interrupt support. And interrupts are
never fun to figure out :/
What really sucks on this front is I'm flying blind on the Z80 CPU core.
Without a working VDP, I can't run any Z80 test ROMs to look for CPU
bugs. And the CPU is certainly too buggy still to run said test ROM
anyway. I can't find any SMS emulators with trace logging from reset.
Such logs vastly accelerate tracking down CPU logic bugs, so without
them, it's going to take a lot longer.
2016-12-17 11:31:34 +00:00
|
|
|
return hcounter <= 233 ? hcounter : hcounter - 86;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto VDP::data() -> uint8 {
|
|
|
|
io.controlLatch = 0;
|
|
|
|
|
|
|
|
auto data = io.vramLatch;
|
|
|
|
io.vramLatch = vram[io.address++];
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto VDP::status() -> uint8 {
|
|
|
|
io.controlLatch = 0;
|
|
|
|
|
2016-12-26 12:09:56 +00:00
|
|
|
uint8 result = 0x00;
|
|
|
|
result |= io.intFrame << 7;
|
|
|
|
result |= io.spriteOverflow << 6;
|
|
|
|
result |= io.spriteCollision << 5;
|
|
|
|
result |= io.fifthSprite << 0;
|
|
|
|
|
|
|
|
io.intLine = 0;
|
|
|
|
io.intFrame = 0;
|
|
|
|
io.spriteOverflow = 0;
|
|
|
|
io.spriteCollision = 0;
|
|
|
|
io.fifthSprite = 0;
|
|
|
|
|
|
|
|
return result;
|
Update to v101r24 release.
byuu says:
Changelog:
- SMS: extended bus mapping of in/out ports: now decoding them fully
inside ms/bus
- SMS: moved Z80 disassembly code from processor/z80 to ms/cpu
(cosmetic)
- SMS: hooked up non-functional silent PSG sample generation, so I can
cap the framerate at 60fps
- SMS: hooked up the VDP main loop: 684 clocks/scanline, 262
scanlines/frame (no PAL support yet)
- SMS: emulated the VDP Vcounter and Hcounter polling ... hopefully
it's right, as it's very bizarre
- SMS: emulated VDP in/out ports (data read, data write, status read,
control write, register write)
- SMS: decoding and caching all VDP register flags (variable names
will probably change)
- nall: \#undef IN on Windows port (prevent compilation warning on
processor/z80)
Watching Sonic the Hedgehog, I can definitely see some VDP register
writes going through, which is a good sign.
Probably the big thing that's needed before I can get enough into the
VDP to start showing graphics is interrupt support. And interrupts are
never fun to figure out :/
What really sucks on this front is I'm flying blind on the Z80 CPU core.
Without a working VDP, I can't run any Z80 test ROMs to look for CPU
bugs. And the CPU is certainly too buggy still to run said test ROM
anyway. I can't find any SMS emulators with trace logging from reset.
Such logs vastly accelerate tracking down CPU logic bugs, so without
them, it's going to take a lot longer.
2016-12-17 11:31:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto VDP::data(uint8 data) -> void {
|
|
|
|
io.controlLatch = 0;
|
|
|
|
|
|
|
|
if(io.code <= 2) {
|
|
|
|
vram[io.address++] = data;
|
|
|
|
} else {
|
2016-12-30 07:24:35 +00:00
|
|
|
cram[io.address++ & 0x1f] = data;
|
Update to v101r24 release.
byuu says:
Changelog:
- SMS: extended bus mapping of in/out ports: now decoding them fully
inside ms/bus
- SMS: moved Z80 disassembly code from processor/z80 to ms/cpu
(cosmetic)
- SMS: hooked up non-functional silent PSG sample generation, so I can
cap the framerate at 60fps
- SMS: hooked up the VDP main loop: 684 clocks/scanline, 262
scanlines/frame (no PAL support yet)
- SMS: emulated the VDP Vcounter and Hcounter polling ... hopefully
it's right, as it's very bizarre
- SMS: emulated VDP in/out ports (data read, data write, status read,
control write, register write)
- SMS: decoding and caching all VDP register flags (variable names
will probably change)
- nall: \#undef IN on Windows port (prevent compilation warning on
processor/z80)
Watching Sonic the Hedgehog, I can definitely see some VDP register
writes going through, which is a good sign.
Probably the big thing that's needed before I can get enough into the
VDP to start showing graphics is interrupt support. And interrupts are
never fun to figure out :/
What really sucks on this front is I'm flying blind on the Z80 CPU core.
Without a working VDP, I can't run any Z80 test ROMs to look for CPU
bugs. And the CPU is certainly too buggy still to run said test ROM
anyway. I can't find any SMS emulators with trace logging from reset.
Such logs vastly accelerate tracking down CPU logic bugs, so without
them, it's going to take a lot longer.
2016-12-17 11:31:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
auto VDP::control(uint8 data) -> void {
|
|
|
|
if(io.controlLatch == 0) {
|
|
|
|
io.controlLatch = 1;
|
|
|
|
io.address.bits(0,7) = data.bits(0,7);
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
io.controlLatch = 0;
|
|
|
|
io.address.bits(8,13) = data.bits(0,5);
|
|
|
|
io.code.bits(0,1) = data.bits(6,7);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(io.code == 0) {
|
|
|
|
io.vramLatch = vram[io.address++];
|
|
|
|
}
|
|
|
|
|
|
|
|
if(io.code == 2) {
|
|
|
|
registerWrite(io.address.bits(11,8), io.address.bits(7,0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
auto VDP::registerWrite(uint4 addr, uint8 data) -> void {
|
|
|
|
switch(addr) {
|
|
|
|
|
|
|
|
//mode control 1
|
|
|
|
case 0x0: {
|
|
|
|
io.externalSync = data.bit(0);
|
|
|
|
io.extendedHeight = data.bit(1);
|
|
|
|
io.mode4 = data.bit(2);
|
|
|
|
io.spriteShift = data.bit(3);
|
|
|
|
io.lineInterrupts = data.bit(4);
|
|
|
|
io.leftClip = data.bit(5);
|
|
|
|
io.horizontalScrollLock = data.bit(6);
|
|
|
|
io.verticalScrollLock = data.bit(7);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//mode control 2
|
|
|
|
case 0x1: {
|
|
|
|
io.spriteDouble = data.bit(0);
|
|
|
|
io.spriteTile = data.bit(1);
|
|
|
|
io.lines240 = data.bit(3);
|
|
|
|
io.lines224 = data.bit(4);
|
|
|
|
io.frameInterrupts = data.bit(5);
|
|
|
|
io.displayEnable = data.bit(6);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//name table base address
|
|
|
|
case 0x2: {
|
|
|
|
io.nameTableMask = data.bit(0);
|
|
|
|
io.nameTableAddress = data.bits(1,3);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//color table base address
|
|
|
|
case 0x3: {
|
|
|
|
io.colorTableAddress = data.bits(0,7);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//pattern table base address
|
|
|
|
case 0x4: {
|
|
|
|
io.patternTableAddress = data.bits(0,7);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//sprite attribute table base address
|
|
|
|
case 0x5: {
|
|
|
|
io.spriteAttributeTableMask = data.bit(0);
|
|
|
|
io.spriteAttributeTableAddress = data.bits(1,6);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//sprite pattern table base address
|
|
|
|
case 0x6: {
|
|
|
|
io.spritePatternTableMask = data.bits(0,1);
|
|
|
|
io.spritePatternTableAddress = data.bit(2);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//backdrop color
|
|
|
|
case 0x7: {
|
|
|
|
io.backdropColor = data.bits(0,3);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//horizontal scroll offset
|
|
|
|
case 0x8: {
|
|
|
|
io.hscroll = data.bits(0,7);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//vertical scroll offset
|
|
|
|
case 0x9: {
|
|
|
|
io.vscroll = data.bits(0,7);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//line counter
|
|
|
|
case 0xa: {
|
|
|
|
io.lineCounter = data.bits(0,7);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
//0xb - 0xf unmapped
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|