2018-12-21 00:01:14 +00:00
|
|
|
auto VDP::Background::run(uint8 hoffset, uint9 voffset) -> void {
|
|
|
|
output = {};
|
|
|
|
switch(vdp.io.mode) {
|
|
|
|
case 0b0000: return graphics1(hoffset, voffset);
|
|
|
|
case 0b0001: return;
|
|
|
|
case 0b0010: return graphics2(hoffset, voffset);
|
|
|
|
case 0b0011: return;
|
|
|
|
case 0b0100: return;
|
|
|
|
case 0b0101: return;
|
|
|
|
case 0b0110: return;
|
|
|
|
case 0b0111: return;
|
|
|
|
case 0b1000: return graphics3(hoffset, voffset, 192);
|
|
|
|
case 0b1001: return;
|
|
|
|
case 0b1010: return graphics3(hoffset, voffset, 192);
|
|
|
|
case 0b1011: return graphics3(hoffset, voffset, 224);
|
|
|
|
case 0b1100: return graphics3(hoffset, voffset, 192);
|
|
|
|
case 0b1101: return;
|
|
|
|
case 0b1110: return graphics3(hoffset, voffset, 240);
|
|
|
|
case 0b1111: return graphics3(hoffset, voffset, 192);
|
|
|
|
}
|
2016-12-30 07:24:35 +00:00
|
|
|
}
|
|
|
|
|
2018-12-21 00:01:14 +00:00
|
|
|
auto VDP::Background::graphics1(uint8 hoffset, uint9 voffset) -> void {
|
|
|
|
uint14 nameTableAddress;
|
|
|
|
nameTableAddress.bits( 0, 4) = hoffset.bits(3,7);
|
|
|
|
nameTableAddress.bits( 5, 9) = voffset.bits(3,7);
|
|
|
|
nameTableAddress.bits(10,13) = vdp.io.nameTableAddress;
|
|
|
|
uint8 pattern = vdp.vram[nameTableAddress];
|
|
|
|
|
|
|
|
uint14 patternAddress;
|
|
|
|
patternAddress.bits( 0, 2) = voffset.bits(0,2);
|
|
|
|
patternAddress.bits( 3,10) = pattern;
|
|
|
|
patternAddress.bits(11,13) = vdp.io.patternTableAddress;
|
|
|
|
|
|
|
|
uint14 colorAddress; //d5 = 0
|
|
|
|
colorAddress.bits(0, 4) = pattern.bits(3,7);
|
|
|
|
colorAddress.bits(6,13) = vdp.io.colorTableAddress;
|
|
|
|
|
|
|
|
uint8 color = vdp.vram[colorAddress];
|
|
|
|
uint3 index = hoffset ^ 7;
|
2018-12-22 10:28:15 +00:00
|
|
|
if(!vdp.vram[patternAddress].bit(index)) {
|
2018-12-21 00:01:14 +00:00
|
|
|
output.color = color.bits(0,3);
|
2018-12-22 10:28:15 +00:00
|
|
|
} else {
|
|
|
|
output.color = color.bits(4,7);
|
2016-12-30 07:24:35 +00:00
|
|
|
}
|
2018-12-21 00:01:14 +00:00
|
|
|
}
|
2016-12-30 07:24:35 +00:00
|
|
|
|
2018-12-21 00:01:14 +00:00
|
|
|
auto VDP::Background::graphics2(uint8 hoffset, uint9 voffset) -> void {
|
|
|
|
uint14 nameTableAddress;
|
|
|
|
nameTableAddress.bits( 0, 4) = hoffset.bits(3,7);
|
|
|
|
nameTableAddress.bits( 5, 9) = voffset.bits(3,7);
|
|
|
|
nameTableAddress.bits(10,13) = vdp.io.nameTableAddress;
|
|
|
|
uint8 pattern = vdp.vram[nameTableAddress];
|
2016-12-30 07:24:35 +00:00
|
|
|
|
2018-12-21 00:01:14 +00:00
|
|
|
uint14 patternAddress;
|
|
|
|
patternAddress.bits(0, 2) = voffset.bits(0,2);
|
|
|
|
patternAddress.bits(3,10) = pattern;
|
|
|
|
if(voffset >= 64 && voffset <= 127) patternAddress.bit(11) = vdp.io.patternTableAddress.bit(0);
|
|
|
|
if(voffset >= 128 && voffset <= 191) patternAddress.bit(12) = vdp.io.patternTableAddress.bit(1);
|
Update to v106r70 release.
byuu says:
Changelog:
- Interface::displays() -> vector<Display> → Interface::display() -> Display
- <Platform::videoRefresh(display>, ...) → <Platform::videoFrame>(...)
- <Platform::audioSample>(...) → <Platform::audioFrame>(...)
- higan, icarus: use AboutDialog class instead of ad-hoc
implementations
- about dialog is now modal, but now has a clickable website URL
- icarus: reverted if constexpr for now
- MSX: implemented basic CPU, VDP support
I took out the multiple displays support thing because it was never
really implemented fully (Emulator::Video and the GUIs both ignored it)
or used anyway. If it ends up necessary in the future, I'll worry about
it then.
There's enough MSX emulation now to run Mr. Do! without sound or input.
I'm shipping higan with C-BIOS 0.29a, although it likely won't be good
enough in the future (eg it can't do BASIC, floppy disk, or cassette
loading.) I have keyboard and (not working) AY-3-8910 support in a
different branch, so that won't take too long to implement. Main problem
is naming all the darned keyboard keys. I think I need to change
settings.bml's input mapping lines so that the key names are values
instead of node names, so that any characters can appear inside of them.
It turns out my MSX set uses .rom for the file extensions ... gods. So,
icarus can't really import them like this. I may have to re-design
icarus' importer to stop caring about the file extension and instead ask
you what kind of games you are importing. There's no way icarus can
heuristically guess what systems the images belong to, because many
systems don't have any standardized magic bytes.
I'm struggling with where to put SG-1000, SC-3000, ColecoVision, Coleco
Adam stuff. I think they need to be split to two separate higan
subfolders (sg and cv, most likely ...) The MS/GG share a very
customized and extended VDP that the other systems don't have. The Sega
and Coleco older hardware share the same TMS9918 as the MSX, yet have
very different memory maps and peripherals that I don't want to mix
together. Especially if we start getting into the computer-variants
more.
2019-01-03 10:05:20 +00:00
|
|
|
uint14 colorAddress = patternAddress;
|
2018-12-21 00:01:14 +00:00
|
|
|
patternAddress.bit(13) = vdp.io.patternTableAddress.bit(2);
|
|
|
|
colorAddress.bit(13) = vdp.io.colorTableAddress.bit(7);
|
|
|
|
|
|
|
|
uint8 colorMask = vdp.io.colorTableAddress.bits(0,6) << 1 | 1;
|
2018-12-22 10:28:15 +00:00
|
|
|
uint8 color = vdp.vram[colorAddress];
|
2018-12-21 00:01:14 +00:00
|
|
|
uint3 index = hoffset ^ 7;
|
2018-12-22 10:28:15 +00:00
|
|
|
if(!vdp.vram[patternAddress].bit(index)) {
|
2018-12-21 00:01:14 +00:00
|
|
|
output.color = color.bits(0,3);
|
2018-12-22 10:28:15 +00:00
|
|
|
} else {
|
|
|
|
output.color = color.bits(4,7);
|
2018-12-21 00:01:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
auto VDP::Background::graphics3(uint8 hoffset, uint9 voffset, uint vlines) -> void {
|
|
|
|
if(hoffset < vdp.io.hscroll.bits(0,2)) return;
|
|
|
|
|
|
|
|
if(!vdp.io.horizontalScrollLock || voffset >= 16) hoffset -= vdp.io.hscroll;
|
|
|
|
if(!vdp.io.verticalScrollLock || hoffset <= 191) voffset += vdp.io.vscroll;
|
2016-12-30 07:24:35 +00:00
|
|
|
|
|
|
|
uint14 nameTableAddress;
|
2018-12-21 00:01:14 +00:00
|
|
|
if(vlines == 192) {
|
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(voffset >= 224) voffset -= 224;
|
2018-12-21 00:01:14 +00:00
|
|
|
nameTableAddress.bits( 1, 5) = hoffset.bits(3,7);
|
|
|
|
nameTableAddress.bits( 6,10) = voffset.bits(3,7);
|
|
|
|
nameTableAddress.bits(11,13) = vdp.io.nameTableAddress.bits(1,3);
|
2016-12-30 07:24:35 +00:00
|
|
|
} else {
|
2018-12-21 00:01:14 +00:00
|
|
|
voffset += 224;
|
|
|
|
nameTableAddress.bits( 1, 5) = hoffset.bits(3,7);
|
|
|
|
nameTableAddress.bits( 6,11) = voffset.bits(3,8);
|
|
|
|
nameTableAddress.bits(12,13) = vdp.io.nameTableAddress.bits(2,3);
|
2016-12-30 07:24:35 +00:00
|
|
|
}
|
|
|
|
|
2018-12-21 00:01:14 +00:00
|
|
|
uint16 pattern;
|
|
|
|
pattern.byte(0) = vdp.vram[nameTableAddress | 0];
|
|
|
|
pattern.byte(1) = vdp.vram[nameTableAddress | 1];
|
|
|
|
|
|
|
|
if(pattern.bit( 9)) hoffset ^= 7; //hflip
|
|
|
|
if(pattern.bit(10)) voffset ^= 7; //vflip
|
|
|
|
output.palette = pattern.bit(11);
|
|
|
|
output.priority = pattern.bit(12);
|
2016-12-30 07:24:35 +00:00
|
|
|
|
2018-12-21 00:01:14 +00:00
|
|
|
uint14 patternAddress;
|
|
|
|
patternAddress.bits(2, 4) = voffset.bits(0,2);
|
|
|
|
patternAddress.bits(5,13) = pattern.bits(0,8);
|
2016-12-30 07:24:35 +00:00
|
|
|
|
2018-12-21 00:01:14 +00:00
|
|
|
uint3 index = hoffset ^ 7;
|
|
|
|
output.color.bit(0) = vdp.vram[patternAddress | 0].bit(index);
|
|
|
|
output.color.bit(1) = vdp.vram[patternAddress | 1].bit(index);
|
|
|
|
output.color.bit(2) = vdp.vram[patternAddress | 2].bit(index);
|
|
|
|
output.color.bit(3) = vdp.vram[patternAddress | 3].bit(index);
|
2017-08-18 12:48:29 +00:00
|
|
|
|
|
|
|
if(output.color == 0) output.priority = 0;
|
2016-12-30 07:24:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto VDP::Background::power() -> void {
|
2018-05-28 01:16:27 +00:00
|
|
|
output = {};
|
2016-12-30 07:24:35 +00:00
|
|
|
}
|