First post, by UselessSoftware
I revived an old 80186 PC emu project of mine that's kind of been on hold for 7 years or so. It was written poorly, and I'm trying to rewrite or at least refactor most of it. I started a new VGA implementation from scratch, and I'm having some issues with VGA writes. A lot of things only seem to write properly to one of the four planes. It's very obvious in the menus and floor/ceilings in Wolf3D. Linear mode games are working perfectly.
Does anyone have any experience with this? I've peeked at 86box and QEMU code to see if I could figure out what I'm doing wrong, and either I'm missing something or the problem is not actually in the write code. I'll figure it out with more time, but frankly my brain is starting to melt and I thought I'd ask on here if anyone has any thoughts.
Here's my write function.
void vga_writememory(uint32_t addr, uint8_t value) {
uint8_t temp, plane;
if ((vga_misc & 0x02) == 0) return; //RAM writes are disabled
addr = (addr - vga_membase) & vga_memmask; //TODO: Is this right?
if (vga_gfxd[0x05] & 0x10) { //host odd/even mode
vga_RAM[addr & 1][addr >> 1] = value;
return;
}
switch (vga_wmode) {
case 0:
for (plane = 0; plane < 4; plane++) {
if (vga_enableplane & (1 << plane)) { //are we allowed to write to this plane?
if (vga_gfxd[0x01] & (1 << plane)) { //test enable set/reset bit for plane
temp = (vga_gfxd[0x00] & (1 << plane)) ? 0xFF : 0x00; //set/reset expansion as source data
} else { //host data as source
value = vga_dorotate(value);
temp = vga_dologic(value, vga_latch[plane]);
}
temp = (temp & vga_gfxd[0x08]) | (vga_latch[plane] & ~vga_gfxd[0x08]);
vga_RAM[plane][addr] = temp;
}
}
break;
case 1:
for (plane = 0; plane < 4; plane++) {
if (vga_enableplane & (1 << plane)) {
vga_RAM[plane][addr] = vga_latch[plane];
}
}
break;
case 2:
for (plane = 0; plane < 4; plane++) {
if (vga_enableplane & (1 << plane)) {
temp = (value & (1 << plane)) ? 0xFF : 0x00;
temp = (vga_dologic(temp, vga_latch[plane]) & vga_gfxd[0x08]) | (vga_latch[plane] & (~vga_gfxd[0x08])); //bit mask logic
vga_RAM[plane][addr] = temp;
}
}
break;
case 3:
for (plane = 0; plane < 4; plane++) {
if (vga_enableplane & (1 << plane)) {
uint8_t temp2;
temp2 = (vga_gfxd[0x00] & (1 << plane)) ? 0xFF : 0x00;
temp = temp2 & vga_dorotate(value);
temp = (temp2 & temp) | (vga_latch[plane] & (~vga_gfxd[0x08])); //bit mask logic
vga_RAM[plane][addr] = temp;
}
}
break;
}
}
Wolf3D only ever seems to switch between write modes 0 and 1.
And this is the rest of the VGA code, which is not at all complete, and needs support for more rendering modes, proper VGA font etc:
https://github.com/mikechambers84/fake86-expe … les/video/vga.c