Implemented odd/even memory mode for EGA and VGA.
This commit is contained in:
parent
cffa5a9926
commit
12232fd7b8
5 changed files with 91 additions and 53 deletions
115
src/vid_ega.c
115
src/vid_ega.c
|
|
@ -98,6 +98,7 @@ void ega_out(uint16_t addr, uint8_t val, void *p)
|
|||
break;
|
||||
case 6:
|
||||
// pclog("Write mapping %02X\n", val);
|
||||
ega->chain2 = val & 2;
|
||||
switch (val & 0xc)
|
||||
{
|
||||
case 0x0: /*128k at A0000*/
|
||||
|
|
@ -298,7 +299,7 @@ void ega_poll(void *p)
|
|||
{
|
||||
drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron);
|
||||
chr = ega->vram[(ega->ma << 1) & ega->vrammask];
|
||||
attr = ega->vram[((ega->ma << 1) + 4) & ega->vrammask];
|
||||
attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask];
|
||||
|
||||
if (attr & 8) charaddr = ega->charsetb + (chr * 128);
|
||||
else charaddr = ega->charseta + (chr * 128);
|
||||
|
|
@ -612,6 +613,7 @@ void ega_write(uint32_t addr, uint8_t val, void *p)
|
|||
{
|
||||
ega_t *ega = (ega_t *)p;
|
||||
uint8_t vala, valb, valc, vald;
|
||||
int writemask2 = ega->writemask;
|
||||
|
||||
egawrites++;
|
||||
cycles -= video_timing_b;
|
||||
|
|
@ -620,18 +622,27 @@ void ega_write(uint32_t addr, uint8_t val, void *p)
|
|||
if (addr >= 0xB0000) addr &= 0x7fff;
|
||||
else addr &= 0xffff;
|
||||
|
||||
if (ega->chain2)
|
||||
{
|
||||
writemask2 &= ~0xa;
|
||||
if (addr & 1)
|
||||
writemask2 <<= 1;
|
||||
addr &= ~1;
|
||||
}
|
||||
|
||||
addr <<= 2;
|
||||
|
||||
if (!(ega->gdcreg[6] & 1))
|
||||
fullchange = 2;
|
||||
addr <<= 2;
|
||||
|
||||
// pclog("%i %08X %i %i %02X %02X %02X %02X %02X\n",chain4,addr,writemode,writemask,gdcreg[8],vram[0],vram[1],vram[2],vram[3]);
|
||||
switch (ega->writemode)
|
||||
{
|
||||
case 1:
|
||||
if (ega->writemask & 1) ega->vram[addr] = ega->la;
|
||||
if (ega->writemask & 2) ega->vram[addr | 0x1] = ega->lb;
|
||||
if (ega->writemask & 4) ega->vram[addr | 0x2] = ega->lc;
|
||||
if (ega->writemask & 8) ega->vram[addr | 0x3] = ega->ld;
|
||||
if (writemask2 & 1) ega->vram[addr] = ega->la;
|
||||
if (writemask2 & 2) ega->vram[addr | 0x1] = ega->lb;
|
||||
if (writemask2 & 4) ega->vram[addr | 0x2] = ega->lc;
|
||||
if (writemask2 & 8) ega->vram[addr | 0x3] = ega->ld;
|
||||
break;
|
||||
case 0:
|
||||
if (ega->gdcreg[3] & 7)
|
||||
|
|
@ -639,10 +650,10 @@ void ega_write(uint32_t addr, uint8_t val, void *p)
|
|||
|
||||
if (ega->gdcreg[8] == 0xff && !(ega->gdcreg[3] & 0x18) && !ega->gdcreg[1])
|
||||
{
|
||||
if (ega->writemask & 1) ega->vram[addr] = val;
|
||||
if (ega->writemask & 2) ega->vram[addr | 0x1] = val;
|
||||
if (ega->writemask & 4) ega->vram[addr | 0x2] = val;
|
||||
if (ega->writemask & 8) ega->vram[addr | 0x3] = val;
|
||||
if (writemask2 & 1) ega->vram[addr] = val;
|
||||
if (writemask2 & 2) ega->vram[addr | 0x1] = val;
|
||||
if (writemask2 & 4) ega->vram[addr | 0x2] = val;
|
||||
if (writemask2 & 8) ega->vram[addr | 0x3] = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -658,28 +669,28 @@ void ega_write(uint32_t addr, uint8_t val, void *p)
|
|||
switch (ega->gdcreg[3] & 0x18)
|
||||
{
|
||||
case 0: /*Set*/
|
||||
if (ega->writemask & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]);
|
||||
if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]);
|
||||
if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]);
|
||||
if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]);
|
||||
if (writemask2 & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]);
|
||||
if (writemask2 & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]);
|
||||
if (writemask2 & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]);
|
||||
if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]);
|
||||
break;
|
||||
case 8: /*AND*/
|
||||
if (ega->writemask & 1) ega->vram[addr] = (vala | ~ega->gdcreg[8]) & ega->la;
|
||||
if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb | ~ega->gdcreg[8]) & ega->lb;
|
||||
if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc | ~ega->gdcreg[8]) & ega->lc;
|
||||
if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald | ~ega->gdcreg[8]) & ega->ld;
|
||||
if (writemask2 & 1) ega->vram[addr] = (vala | ~ega->gdcreg[8]) & ega->la;
|
||||
if (writemask2 & 2) ega->vram[addr | 0x1] = (valb | ~ega->gdcreg[8]) & ega->lb;
|
||||
if (writemask2 & 4) ega->vram[addr | 0x2] = (valc | ~ega->gdcreg[8]) & ega->lc;
|
||||
if (writemask2 & 8) ega->vram[addr | 0x3] = (vald | ~ega->gdcreg[8]) & ega->ld;
|
||||
break;
|
||||
case 0x10: /*OR*/
|
||||
if (ega->writemask & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) | ega->la;
|
||||
if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | ega->lb;
|
||||
if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | ega->lc;
|
||||
if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | ega->ld;
|
||||
if (writemask2 & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) | ega->la;
|
||||
if (writemask2 & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | ega->lb;
|
||||
if (writemask2 & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | ega->lc;
|
||||
if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | ega->ld;
|
||||
break;
|
||||
case 0x18: /*XOR*/
|
||||
if (ega->writemask & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) ^ ega->la;
|
||||
if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) ^ ega->lb;
|
||||
if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) ^ ega->lc;
|
||||
if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld;
|
||||
if (writemask2 & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) ^ ega->la;
|
||||
if (writemask2 & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) ^ ega->lb;
|
||||
if (writemask2 & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) ^ ega->lc;
|
||||
if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld;
|
||||
break;
|
||||
}
|
||||
// pclog("- %02X %02X %02X %02X %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr);
|
||||
|
|
@ -688,10 +699,10 @@ void ega_write(uint32_t addr, uint8_t val, void *p)
|
|||
case 2:
|
||||
if (!(ega->gdcreg[3] & 0x18) && !ega->gdcreg[1])
|
||||
{
|
||||
if (ega->writemask & 1) ega->vram[addr] = (((val & 1) ? 0xff : 0) & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]);
|
||||
if (ega->writemask & 2) ega->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]);
|
||||
if (ega->writemask & 4) ega->vram[addr | 0x2] = (((val & 4) ? 0xff : 0) & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]);
|
||||
if (ega->writemask & 8) ega->vram[addr | 0x3] = (((val & 8) ? 0xff : 0) & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]);
|
||||
if (writemask2 & 1) ega->vram[addr] = (((val & 1) ? 0xff : 0) & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]);
|
||||
if (writemask2 & 2) ega->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]);
|
||||
if (writemask2 & 4) ega->vram[addr | 0x2] = (((val & 4) ? 0xff : 0) & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]);
|
||||
if (writemask2 & 8) ega->vram[addr | 0x3] = (((val & 8) ? 0xff : 0) & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -702,28 +713,28 @@ void ega_write(uint32_t addr, uint8_t val, void *p)
|
|||
switch (ega->gdcreg[3] & 0x18)
|
||||
{
|
||||
case 0: /*Set*/
|
||||
if (ega->writemask & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]);
|
||||
if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]);
|
||||
if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]);
|
||||
if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]);
|
||||
if (writemask2 & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]);
|
||||
if (writemask2 & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]);
|
||||
if (writemask2 & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]);
|
||||
if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]);
|
||||
break;
|
||||
case 8: /*AND*/
|
||||
if (ega->writemask & 1) ega->vram[addr] = (vala | ~ega->gdcreg[8]) & ega->la;
|
||||
if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb | ~ega->gdcreg[8]) & ega->lb;
|
||||
if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc | ~ega->gdcreg[8]) & ega->lc;
|
||||
if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald | ~ega->gdcreg[8]) & ega->ld;
|
||||
if (writemask2 & 1) ega->vram[addr] = (vala | ~ega->gdcreg[8]) & ega->la;
|
||||
if (writemask2 & 2) ega->vram[addr | 0x1] = (valb | ~ega->gdcreg[8]) & ega->lb;
|
||||
if (writemask2 & 4) ega->vram[addr | 0x2] = (valc | ~ega->gdcreg[8]) & ega->lc;
|
||||
if (writemask2 & 8) ega->vram[addr | 0x3] = (vald | ~ega->gdcreg[8]) & ega->ld;
|
||||
break;
|
||||
case 0x10: /*OR*/
|
||||
if (ega->writemask & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) | ega->la;
|
||||
if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | ega->lb;
|
||||
if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | ega->lc;
|
||||
if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | ega->ld;
|
||||
if (writemask2 & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) | ega->la;
|
||||
if (writemask2 & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | ega->lb;
|
||||
if (writemask2 & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | ega->lc;
|
||||
if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | ega->ld;
|
||||
break;
|
||||
case 0x18: /*XOR*/
|
||||
if (ega->writemask & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) ^ ega->la;
|
||||
if (ega->writemask & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) ^ ega->lb;
|
||||
if (ega->writemask & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) ^ ega->lc;
|
||||
if (ega->writemask & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld;
|
||||
if (writemask2 & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) ^ ega->la;
|
||||
if (writemask2 & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) ^ ega->lb;
|
||||
if (writemask2 & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) ^ ega->lc;
|
||||
if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -735,13 +746,23 @@ uint8_t ega_read(uint32_t addr, void *p)
|
|||
{
|
||||
ega_t *ega = (ega_t *)p;
|
||||
uint8_t temp, temp2, temp3, temp4;
|
||||
int readplane = ega->readplane;
|
||||
|
||||
egareads++;
|
||||
cycles -= video_timing_b;
|
||||
cycles_lost += video_timing_b;
|
||||
// pclog("Readega %06X ",addr);
|
||||
if (addr >= 0xb0000) addr &= 0x7fff;
|
||||
else addr &= 0xffff;
|
||||
|
||||
if (ega->chain2)
|
||||
{
|
||||
readplane = (readplane & 2) | (addr & 1);
|
||||
addr &= ~1;
|
||||
}
|
||||
|
||||
addr <<= 2;
|
||||
|
||||
ega->la = ega->vram[addr];
|
||||
ega->lb = ega->vram[addr | 0x1];
|
||||
ega->lc = ega->vram[addr | 0x2];
|
||||
|
|
@ -762,7 +783,7 @@ uint8_t ega_read(uint32_t addr, void *p)
|
|||
temp4 ^= (ega->colourcompare & 8) ? 0xff : 0;
|
||||
return ~(temp | temp2 | temp3 | temp4);
|
||||
}
|
||||
return ega->vram[addr | ega->readplane];
|
||||
return ega->vram[addr | readplane];
|
||||
}
|
||||
|
||||
void ega_init(ega_t *ega)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ typedef struct ega_t
|
|||
int fast;
|
||||
uint8_t colourcompare, colournocare;
|
||||
int readmode, writemode, readplane;
|
||||
int chain4;
|
||||
int chain4, chain2;
|
||||
uint8_t writemask;
|
||||
uint32_t charseta, charsetb;
|
||||
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ void svga_out(uint16_t addr, uint8_t val, void *p)
|
|||
case 5: svga->writemode=val&3; svga->readmode=val&8; break;
|
||||
case 6:
|
||||
// pclog("svga_out recalcmapping %p\n", svga);
|
||||
svga->chain2 = val & 2;
|
||||
if ((svga->gdcreg[6] & 0xc) != (val & 0xc))
|
||||
{
|
||||
// pclog("Write mapping %02X\n", val);
|
||||
|
|
@ -740,6 +741,14 @@ void svga_write(uint32_t addr, uint8_t val, void *p)
|
|||
writemask2=1<<(addr&3);
|
||||
addr&=~3;
|
||||
}
|
||||
else if (svga->chain2)
|
||||
{
|
||||
writemask2 &= ~0xa;
|
||||
if (addr & 1)
|
||||
writemask2 <<= 1;
|
||||
addr &= ~1;
|
||||
addr <<= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
addr<<=2;
|
||||
|
|
@ -900,6 +909,7 @@ uint8_t svga_read(uint32_t addr, void *p)
|
|||
{
|
||||
svga_t *svga = (svga_t *)p;
|
||||
uint8_t temp, temp2, temp3, temp4;
|
||||
int readplane = svga->readplane;
|
||||
|
||||
cycles -= video_timing_b;
|
||||
cycles_lost += video_timing_b;
|
||||
|
|
@ -918,7 +928,14 @@ uint8_t svga_read(uint32_t addr, void *p)
|
|||
return 0xff;
|
||||
return svga->vram[addr];
|
||||
}
|
||||
else addr<<=2;
|
||||
else if (svga->chain2)
|
||||
{
|
||||
readplane = (readplane & 2) | (addr & 1);
|
||||
addr &= ~1;
|
||||
addr <<= 2;
|
||||
}
|
||||
else
|
||||
addr<<=2;
|
||||
|
||||
addr &= 0x7fffff;
|
||||
|
||||
|
|
@ -946,7 +963,7 @@ uint8_t svga_read(uint32_t addr, void *p)
|
|||
return ~(temp | temp2 | temp3 | temp4);
|
||||
}
|
||||
//pclog("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane);
|
||||
return svga->vram[addr | svga->readplane];
|
||||
return svga->vram[addr | readplane];
|
||||
}
|
||||
|
||||
void svga_write_linear(uint32_t addr, uint8_t val, void *p)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ typedef struct svga_t
|
|||
int fast;
|
||||
uint8_t colourcompare, colournocare;
|
||||
int readmode, writemode, readplane;
|
||||
int chain4;
|
||||
int chain4, chain2;
|
||||
uint8_t writemask;
|
||||
uint32_t charseta, charsetb;
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ void svga_render_text_40(svga_t *svga)
|
|||
{
|
||||
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
|
||||
chr = svga->vram[(svga->ma << 1) & svga->vrammask];
|
||||
attr = svga->vram[((svga->ma << 1) + 4) & svga->vrammask];
|
||||
attr = svga->vram[((svga->ma << 1) + 1) & svga->vrammask];
|
||||
if (attr & 8) charaddr = svga->charsetb + (chr * 128);
|
||||
else charaddr = svga->charseta + (chr * 128);
|
||||
|
||||
|
|
@ -115,7 +115,7 @@ void svga_render_text_80(svga_t *svga)
|
|||
{
|
||||
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
|
||||
chr = svga->vram[(svga->ma << 1) & svga->vrammask];
|
||||
attr = svga->vram[((svga->ma << 1) + 4) & svga->vrammask];
|
||||
attr = svga->vram[((svga->ma << 1) + 1) & svga->vrammask];
|
||||
if (attr & 8) charaddr = svga->charsetb + (chr * 128);
|
||||
else charaddr = svga->charseta + (chr * 128);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue