2016-08-17 12:31:22 +00:00
|
|
|
#include <ms/ms.hpp>
|
|
|
|
|
|
|
|
namespace MasterSystem {
|
|
|
|
|
|
|
|
VDP vdp;
|
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
|
|
|
#include "io.cpp"
|
2016-12-30 07:24:35 +00:00
|
|
|
#include "background.cpp"
|
|
|
|
#include "sprite.cpp"
|
2016-08-17 12:31:22 +00:00
|
|
|
|
|
|
|
auto VDP::Enter() -> void {
|
|
|
|
while(true) scheduler.synchronize(), vdp.main();
|
|
|
|
}
|
|
|
|
|
|
|
|
auto VDP::main() -> void {
|
2016-12-26 12:09:56 +00:00
|
|
|
if(io.vcounter <= vlines()) {
|
|
|
|
if(io.lcounter-- == 0) {
|
|
|
|
io.lcounter = io.lineCounter;
|
|
|
|
io.intLine = 1;
|
2016-08-19 14:11:26 +00:00
|
|
|
}
|
2016-12-30 07:24:35 +00:00
|
|
|
} else {
|
|
|
|
io.lcounter = io.lineCounter;
|
2016-08-19 14:11:26 +00:00
|
|
|
}
|
2016-12-26 12:09:56 +00:00
|
|
|
|
|
|
|
if(io.vcounter == vlines() + 1) {
|
|
|
|
io.intFrame = 1;
|
|
|
|
}
|
|
|
|
|
2016-12-30 07:24:35 +00:00
|
|
|
background.scanline();
|
|
|
|
sprite.scanline();
|
|
|
|
|
|
|
|
//684 clocks/scanline
|
|
|
|
for(uint x : range(256)) {
|
|
|
|
background.run();
|
|
|
|
sprite.run();
|
|
|
|
step(2);
|
|
|
|
|
Update to v101r27 release.
byuu says:
Changelog:
- SMS: emulated the generic Sega memory mapper (none of the more
limited forms of it yet)
- (missing ROM shift, ROM write enable emulation -- no commercial
games use either, though)
- SMS: bus I/O returns 0xff instead of 0x00 so games don't think every
key is being pressed at once
- (this is a hack until I implement proper controller pad reading)
- SMS: very limited protection against reading/writing past the end of
ROM/RAM (todo: should mirror)
- SMS: VDP background HSCROLL subtracts, rather than adds, to the
offset (unlike VSCROLL)
- SMS: VDP VSCROLL is 9-bit, modulates voffset+vscroll to 224 in
192-line mode (32x28 tilemap)
- SMS: VDP tiledata for backgrounds and sprites use `7-(x&7)` rather
than `(x&7)`
- SMS: fix output color to be 6-bit rather than 5-bit
- SMS: left clip uses register `#7`, not palette color `#7`
- (todo: do we want `color[reg7]` or `color[16 + reg7]`?)
- SMS: refined handling of 0xcb, 0xed prefixes in the Z80 core and its
disassembler
- SMS: emulated (0xfd, 0xdd) 0xcb opcodes 0x00-0x0f (still missing
0x10-0xff)
- SMS: fixed 0xcb 0b-----110 opcodes to use direct HL and never allow
(IX,IY)+d
- SMS: fixed major logic bug in (IX,IY)+d displacement
- (was using `read(x)` instead of `operand()` for the displacement
byte fetch before)
- icarus: fake there always being 32KiB of RAM in all SMS cartridges
for the time being
- (not sure how to detect this stuff yet; although I've read it's
not even really possible `>_>`)
TODO: remove processor/z80/dissassembler.cpp code block at line 396 (as it's unnecessary.)
Lots of commercial games are starting to show trashed graphical output now.
2017-01-06 08:11:38 +00:00
|
|
|
uint6 color = cram[io.backdropColor];
|
2016-12-30 07:24:35 +00:00
|
|
|
if(background.output.color && (background.output.priority || !sprite.output.color)) {
|
|
|
|
color = cram[background.output.palette << 4 | background.output.color];
|
|
|
|
} else if(sprite.output.color) {
|
|
|
|
color = cram[16 | sprite.output.color];
|
|
|
|
}
|
Update to v101r27 release.
byuu says:
Changelog:
- SMS: emulated the generic Sega memory mapper (none of the more
limited forms of it yet)
- (missing ROM shift, ROM write enable emulation -- no commercial
games use either, though)
- SMS: bus I/O returns 0xff instead of 0x00 so games don't think every
key is being pressed at once
- (this is a hack until I implement proper controller pad reading)
- SMS: very limited protection against reading/writing past the end of
ROM/RAM (todo: should mirror)
- SMS: VDP background HSCROLL subtracts, rather than adds, to the
offset (unlike VSCROLL)
- SMS: VDP VSCROLL is 9-bit, modulates voffset+vscroll to 224 in
192-line mode (32x28 tilemap)
- SMS: VDP tiledata for backgrounds and sprites use `7-(x&7)` rather
than `(x&7)`
- SMS: fix output color to be 6-bit rather than 5-bit
- SMS: left clip uses register `#7`, not palette color `#7`
- (todo: do we want `color[reg7]` or `color[16 + reg7]`?)
- SMS: refined handling of 0xcb, 0xed prefixes in the Z80 core and its
disassembler
- SMS: emulated (0xfd, 0xdd) 0xcb opcodes 0x00-0x0f (still missing
0x10-0xff)
- SMS: fixed 0xcb 0b-----110 opcodes to use direct HL and never allow
(IX,IY)+d
- SMS: fixed major logic bug in (IX,IY)+d displacement
- (was using `read(x)` instead of `operand()` for the displacement
byte fetch before)
- icarus: fake there always being 32KiB of RAM in all SMS cartridges
for the time being
- (not sure how to detect this stuff yet; although I've read it's
not even really possible `>_>`)
TODO: remove processor/z80/dissassembler.cpp code block at line 396 (as it's unnecessary.)
Lots of commercial games are starting to show trashed graphical output now.
2017-01-06 08:11:38 +00:00
|
|
|
if(x <= 7 && io.leftClip) color = cram[io.backdropColor];
|
Update to v101r29 release.
byuu says:
Changelog:
- SMS: background VDP clips partial tiles on the left (math may not be
right ... it's hard to reason about)
- SMS: fix background VDP scroll locks
- SMS: fix VDP sprite coordinates
- SMS: paint black after the end of the visible display
- todo: shouldn't be a brute force at the end of the main VDP
loop, should happen in each rendering unit
- higan: removed emulator/debugger.hpp
- higan: removed privileged: access specifier
- SFC: removed debugger hooks
- todo: remove sfc/debugger.hpp
- Z80: fixed disassembly of (fd,dd) cb (displacement) (opcode)
instructions
- Z80: fix to prevent interrupts from firing between ix/iy prefixes
and opcodes
- todo: this is a rather hacky fix that could, if exploited, crash
the stack frame
- Z80: fix BIT flags
- Z80: fix ADD hl,reg flags
- Z80: fix CPD, CPI flags
- Z80: fix IND, INI flags
- Z80: fix INDR, INIT loop flag check
- Z80: fix OUTD, OUTI flags
- Z80: fix OTDR, OTIR loop flag check
2017-01-09 21:27:13 +00:00
|
|
|
if(!io.displayEnable || io.vcounter >= vlines()) color = 0;
|
2016-12-30 07:24:35 +00:00
|
|
|
buffer[io.vcounter * 256 + x] = color;
|
2016-12-26 12:09:56 +00:00
|
|
|
}
|
2016-12-30 07:24:35 +00:00
|
|
|
step(172);
|
2016-12-26 12:09:56 +00:00
|
|
|
|
|
|
|
if(io.vcounter == 240) scheduler.exit(Scheduler::Event::Frame);
|
2016-08-17 12:31:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto VDP::step(uint clocks) -> void {
|
2016-12-26 12:09:56 +00:00
|
|
|
while(clocks--) {
|
|
|
|
if(++io.hcounter == 684) {
|
|
|
|
io.hcounter = 0;
|
|
|
|
if(++io.vcounter == 262) {
|
|
|
|
io.vcounter = 0;
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
2016-12-26 12:09:56 +00:00
|
|
|
cpu.setINT((io.lineInterrupts && io.intLine) || (io.frameInterrupts && io.intFrame));
|
|
|
|
Thread::step(1);
|
|
|
|
synchronize(cpu);
|
|
|
|
}
|
2016-08-19 14:11:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto VDP::refresh() -> void {
|
|
|
|
Emulator::video.refresh(buffer, 256 * sizeof(uint32), 256, 240);
|
|
|
|
}
|
|
|
|
|
2016-12-26 12:09:56 +00:00
|
|
|
auto VDP::vlines() -> uint {
|
|
|
|
if(io.lines240) return 240;
|
|
|
|
if(io.lines224) return 224;
|
|
|
|
return 192;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto VDP::vblank() -> bool {
|
|
|
|
return io.vcounter >= vlines();
|
|
|
|
}
|
|
|
|
|
2016-08-19 14:11:26 +00:00
|
|
|
auto VDP::power() -> void {
|
2016-12-30 07:24:35 +00:00
|
|
|
background.power();
|
|
|
|
sprite.power();
|
2016-08-19 14:11:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto VDP::reset() -> void {
|
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
|
|
|
create(VDP::Enter, system.colorburst() * 15.0 / 5.0);
|
|
|
|
|
|
|
|
memory::fill(&io, sizeof(IO));
|
2016-12-30 07:24:35 +00:00
|
|
|
|
|
|
|
background.reset();
|
|
|
|
sprite.reset();
|
2016-08-17 12:31:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|