bsnes/higan/ms/vdp/background.cpp

118 lines
4.1 KiB
C++
Raw Normal View History

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);
}
}
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;
if(!vdp.vram[patternAddress].bit(index)) {
output.color = color.bits(0,3);
} else {
output.color = color.bits(4,7);
}
}
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];
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;
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;
uint8 color = vdp.vram[colorAddress];
uint3 index = hoffset ^ 7;
if(!vdp.vram[patternAddress].bit(index)) {
output.color = color.bits(0,3);
} else {
output.color = color.bits(4,7);
}
}
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;
uint14 nameTableAddress;
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;
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);
} else {
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);
}
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);
uint14 patternAddress;
patternAddress.bits(2, 4) = voffset.bits(0,2);
patternAddress.bits(5,13) = pattern.bits(0,8);
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);
if(output.color == 0) output.priority = 0;
}
auto VDP::Background::power() -> void {
output = {};
}