Merge pull request #89 from Altheos/cirrus
Cirrus improvements from upstream
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -11,7 +11,7 @@
|
||||
* This is intended to be used by another SVGA driver,
|
||||
* and not as a card in it's own right.
|
||||
*
|
||||
* Version: @(#)vid_svga.c 1.0.23 2019/05/13
|
||||
* Version: @(#)vid_svga.c 1.0.24 2019/10/21
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -58,12 +58,13 @@
|
||||
#include "vid_svga_render.h"
|
||||
|
||||
|
||||
|
||||
extern int cyc_total;
|
||||
extern uint8_t edatlookup[4][4];
|
||||
|
||||
uint8_t svga_rotate[8][256];
|
||||
|
||||
static const uint32_t mask16[16] = {
|
||||
static const uint64_t mask16[16] = {
|
||||
0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
|
||||
0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
|
||||
0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
|
||||
@@ -84,7 +85,6 @@ svga_get_pri(void)
|
||||
return svga_pri;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
svga_set_override(svga_t *svga, int val)
|
||||
{
|
||||
@@ -93,7 +93,6 @@ svga_set_override(svga_t *svga, int val)
|
||||
svga->override = val;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
svga_out(uint16_t addr, uint8_t val, priv_t priv)
|
||||
{
|
||||
@@ -192,7 +191,7 @@ svga_out(uint16_t addr, uint8_t val, priv_t priv)
|
||||
svga->chain2_write = !(val & 4);
|
||||
svga->chain4 = val & 8;
|
||||
svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) &&
|
||||
!svga->gdcreg[1]) && svga->chain4;
|
||||
!svga->gdcreg[1]) && svga->chain4 && !(svga->adv_flags & FLAG_ADDR_BY8);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -519,6 +518,7 @@ svga_recalctimings(svga_t *svga)
|
||||
case 0x40: case 0x60: /*256+ colours*/
|
||||
switch (svga->bpp) {
|
||||
case 8:
|
||||
svga->map8 = svga->pallook;
|
||||
if (svga->lowres)
|
||||
svga->render = svga_render_8bpp_lowres;
|
||||
else
|
||||
@@ -606,6 +606,16 @@ svga_poll(priv_t priv)
|
||||
svga->hwcursor_oddeven = 1;
|
||||
}
|
||||
|
||||
if (svga->displine == svga->dac_hwcursor_latch.y && svga->dac_hwcursor_latch.ena) {
|
||||
svga->dac_hwcursor_on = 64 - svga->dac_hwcursor_latch.yoff;
|
||||
svga->dac_hwcursor_oddeven = 0;
|
||||
}
|
||||
|
||||
if (svga->displine == (svga->dac_hwcursor_latch.y + 1) && svga->dac_hwcursor_latch.ena &&
|
||||
svga->interlace) {
|
||||
svga->dac_hwcursor_on = 64 - (svga->dac_hwcursor_latch.yoff + 1);
|
||||
svga->dac_hwcursor_oddeven = 1;
|
||||
}
|
||||
if (svga->displine == svga->overlay_latch.y && svga->overlay_latch.ena) {
|
||||
svga->overlay_on = svga->overlay_latch.ysize - svga->overlay_latch.yoff;
|
||||
svga->overlay_oddeven = 0;
|
||||
@@ -629,7 +639,7 @@ svga_poll(priv_t priv)
|
||||
video_blit_wait_buffer();
|
||||
}
|
||||
|
||||
if (svga->hwcursor_on || svga->overlay_on) {
|
||||
if (svga->hwcursor_on || svga->dac_hwcursor_on || svga->overlay_on) {
|
||||
svga->changedvram[svga->ma >> 12] = svga->changedvram[(svga->ma >> 12) + 1] =
|
||||
svga->interlace ? 3 : 2;
|
||||
}
|
||||
@@ -645,8 +655,15 @@ svga_poll(priv_t priv)
|
||||
svga->overlay_on--;
|
||||
}
|
||||
|
||||
if (svga->dac_hwcursor_on) {
|
||||
if (!svga->override && svga->dac_hwcursor_draw)
|
||||
svga->dac_hwcursor_draw(svga, svga->displine);
|
||||
svga->dac_hwcursor_on--;
|
||||
if (svga->dac_hwcursor_on && svga->interlace)
|
||||
svga->dac_hwcursor_on--;
|
||||
}
|
||||
if (svga->hwcursor_on) {
|
||||
if (!svga->override)
|
||||
if (!svga->override && svga->hwcursor_draw)
|
||||
svga->hwcursor_draw(svga, svga->displine);
|
||||
svga->hwcursor_on--;
|
||||
if (svga->hwcursor_on && svga->interlace)
|
||||
@@ -673,7 +690,7 @@ svga_poll(priv_t priv)
|
||||
svga->hdisp_on = 0;
|
||||
|
||||
svga->linepos = 0;
|
||||
if (svga->sc == (svga->crtc[11] & 31))
|
||||
if ((svga->sc == (svga->crtc[11] & 31)) || (svga->sc == svga->rowcount))
|
||||
svga->con = 0;
|
||||
if (svga->dispon) {
|
||||
if (svga->linedbl && !svga->linecountff) {
|
||||
@@ -792,6 +809,8 @@ svga_poll(priv_t priv)
|
||||
svga->hwcursor_on = 0;
|
||||
svga->hwcursor_latch = svga->hwcursor;
|
||||
|
||||
svga->dac_hwcursor_on = 0;
|
||||
svga->dac_hwcursor_latch = svga->dac_hwcursor;
|
||||
svga->overlay_on = 0;
|
||||
svga->overlay_latch = svga->overlay;
|
||||
}
|
||||
@@ -836,7 +855,7 @@ svga_init(svga_t *svga, priv_t priv, int vramsize,
|
||||
svga->vram_max = vramsize;
|
||||
svga->vram_display_mask = svga->vram_mask = vramsize - 1;
|
||||
svga->decode_mask = 0x7fffff;
|
||||
svga->changedvram = (uint8_t *)mem_alloc(0x800000 >> 12);
|
||||
svga->changedvram = (uint8_t *)mem_alloc(vramsize >> 12);
|
||||
svga->recalctimings_ex = recalctimings_ex;
|
||||
svga->video_in = video_in;
|
||||
svga->video_out = video_out;
|
||||
@@ -846,6 +865,8 @@ svga_init(svga_t *svga, priv_t priv, int vramsize,
|
||||
svga->hwcursor.xsize = svga->hwcursor.ysize = 32;
|
||||
svga->hwcursor.yoff = 32;
|
||||
|
||||
svga->dac_hwcursor.xsize = svga->dac_hwcursor.ysize = 32;
|
||||
svga->dac_hwcursor.yoff = 32;
|
||||
mem_map_add(&svga->mapping, 0xa0000, 0x20000,
|
||||
svga_read, svga_readw, svga_readl,
|
||||
svga_write, svga_writew, svga_writel,
|
||||
@@ -857,6 +878,7 @@ svga_init(svga_t *svga, priv_t priv, int vramsize,
|
||||
|
||||
svga->ramdac_type = RAMDAC_6BIT;
|
||||
|
||||
svga->map8 = svga->pallook;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -875,42 +897,44 @@ void
|
||||
svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, priv_t priv)
|
||||
{
|
||||
svga_t *svga = (svga_t *)priv;
|
||||
uint32_t write_mask, bit_mask, set_mask, val32 = (uint32_t) val;
|
||||
int func_select, writemask2 = svga->writemask;
|
||||
int memory_map_mode;
|
||||
uint64_t write_mask, bit_mask, set_mask, mask0, la, val32 = (uint64_t) val;
|
||||
|
||||
if (svga->adv_flags & FLAG_ADDR_BY8)
|
||||
writemask2 = svga->seqregs[2];
|
||||
|
||||
cycles -= video_timing_write_b;
|
||||
|
||||
|
||||
if (! linear) {
|
||||
memory_map_mode = (svga->gdcreg[6] >> 2) & 3;
|
||||
//addr &= 0x1ffff;
|
||||
addr &= 0x1ffff;
|
||||
|
||||
switch (memory_map_mode) {
|
||||
case 0:
|
||||
addr &= svga->banked_mask;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
//if (addr >= 0x10000)
|
||||
//return;
|
||||
addr &= svga->banked_mask;
|
||||
if (addr >= 0x10000)
|
||||
return;
|
||||
if (svga->adv_flags & FLAG_EXTRA_BANKS)
|
||||
addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1];
|
||||
else
|
||||
addr += svga->write_bank;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
//addr -= 0x10000;
|
||||
//if (addr >= 0x8000)
|
||||
// return;
|
||||
addr &= svga->banked_mask;
|
||||
addr -= 0x10000;
|
||||
if (addr >= 0x8000)
|
||||
return;
|
||||
break;
|
||||
|
||||
default:
|
||||
case 3:
|
||||
//addr -= 0x18000;
|
||||
//if (addr >= 0x8000)
|
||||
// return;
|
||||
addr &= svga->banked_mask;
|
||||
addr += svga->write_bank;
|
||||
addr -= 0x18000;
|
||||
if (addr >= 0x8000)
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -918,7 +942,9 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, priv_t priv)
|
||||
if (!(svga->gdcreg[6] & 1))
|
||||
svga->fullchange = 2;
|
||||
|
||||
if ((svga->chain4 || svga->fb_only) && (svga->writemode < 4)) {
|
||||
if ((svga->adv_flags & FLAG_ADDR_BY8) && (svga->writemode < 4))
|
||||
addr <<= 3;
|
||||
else if ((svga->chain4 || svga->fb_only) && (svga->writemode < 4)) {
|
||||
writemask2 = 1 << (addr & 3);
|
||||
addr &= ~3;
|
||||
} else if (svga->chain2_write) {
|
||||
@@ -929,6 +955,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, priv_t priv)
|
||||
addr <<= 2;
|
||||
} else
|
||||
addr <<= 2;
|
||||
|
||||
addr &= svga->decode_mask;
|
||||
|
||||
if (addr >= svga->vram_max)
|
||||
@@ -952,31 +979,59 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, priv_t priv)
|
||||
|
||||
val32 |= (val32 << 8);
|
||||
val32 |= (val32 << 16);
|
||||
if (svga->adv_flags & FLAG_ADDR_BY8)
|
||||
val32 |= (val32 << 32);
|
||||
|
||||
if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) &&
|
||||
(!svga->gdcreg[1] || svga->set_reset_disabled)) {
|
||||
/* mask data according to sr[2] */
|
||||
write_mask = mask16[writemask2 & 0x0f];
|
||||
if (svga->adv_flags & FLAG_ADDR_BY8) {
|
||||
write_mask |= (mask16[(writemask2 & 0xf0) >> 4] << 32);
|
||||
addr >>= 3;
|
||||
((uint64_t *)(svga->vram))[addr] &= ~write_mask;
|
||||
((uint64_t *)(svga->vram))[addr] |= (val32 & write_mask);
|
||||
} else {
|
||||
addr >>= 2;
|
||||
|
||||
((uint32_t *)(svga->vram))[addr] &= ~write_mask;
|
||||
((uint32_t *)(svga->vram))[addr] |= (val32 & write_mask);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
set_mask = mask16[svga->gdcreg[1] & 0x0f];
|
||||
val32 = (val32 & ~set_mask) | (mask16[svga->gdcreg[0] & 0x0f] & set_mask);
|
||||
if (svga->adv_flags & FLAG_ADDR_BY8)
|
||||
set_mask |= (mask16[(svga->gdcreg[1] & 0xf0) >> 4] << 32);
|
||||
|
||||
mask0 = mask16[svga->gdcreg[0] & 0x0f];
|
||||
if (svga->adv_flags & FLAG_ADDR_BY8)
|
||||
mask0 |= (mask16[(svga->gdcreg[0] & 0xf0) >> 4] << 32);
|
||||
|
||||
val32 = (val32 & ~set_mask) | (mask0 & set_mask);
|
||||
break;
|
||||
case 1:
|
||||
val32 = svga->latch;
|
||||
|
||||
/* mask data according to sr[2] */
|
||||
write_mask = mask16[writemask2 & 0x0f];
|
||||
if (svga->adv_flags & FLAG_ADDR_BY8) {
|
||||
write_mask |= (mask16[(writemask2 & 0xf0) >> 4] << 32);
|
||||
addr >>= 3;
|
||||
|
||||
((uint64_t *)(svga->vram))[addr] &= ~write_mask;
|
||||
((uint64_t *)(svga->vram))[addr] |= (val32 & write_mask);
|
||||
} else {
|
||||
addr >>= 2;
|
||||
((uint32_t *)(svga->vram))[addr] &= ~write_mask;
|
||||
((uint32_t *)(svga->vram))[addr] |= (val32 & write_mask);
|
||||
}
|
||||
return;
|
||||
case 2:
|
||||
val32 = mask16[val32 & 0x0f];
|
||||
mask0 = mask16[val32 & 0x0f];
|
||||
if (svga->adv_flags & FLAG_ADDR_BY8)
|
||||
mask0 |= (mask16[(val32 & 0xf0) >> 4] << 32);
|
||||
val32 = mask0;
|
||||
bit_mask = svga->gdcreg[8];
|
||||
|
||||
if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled))
|
||||
@@ -989,6 +1044,8 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, priv_t priv)
|
||||
|
||||
bit_mask = svga->gdcreg[8] & val32;
|
||||
val32 = mask16[svga->gdcreg[0] & 0x0f];
|
||||
if (svga->adv_flags & FLAG_ADDR_BY8)
|
||||
val32 |= (mask16[(svga->gdcreg[0] & 0xf0) >> 4] << 32);
|
||||
break;
|
||||
default:
|
||||
if (svga->ven_write)
|
||||
@@ -1000,34 +1057,47 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, priv_t priv)
|
||||
bit_mask |= bit_mask << 8;
|
||||
bit_mask |= bit_mask << 16;
|
||||
|
||||
if (svga->adv_flags & FLAG_ADDR_BY8)
|
||||
bit_mask |= bit_mask << 32;
|
||||
|
||||
la = svga->latch;
|
||||
if (!(svga->adv_flags & FLAG_LATCH8))
|
||||
la &= 0xffffffff;
|
||||
|
||||
/* apply logical operation */
|
||||
switch(func_select) {
|
||||
case 0:
|
||||
default:
|
||||
/* set */
|
||||
val32 &= bit_mask;
|
||||
val32 |= (svga->latch & ~bit_mask);
|
||||
val32 |= (la & ~bit_mask);
|
||||
break;
|
||||
case 1:
|
||||
/* and */
|
||||
val32 |= ~bit_mask;
|
||||
val32 &= svga->latch;
|
||||
val32 &= la;
|
||||
break;
|
||||
case 2:
|
||||
/* or */
|
||||
val32 &= bit_mask;
|
||||
val32 |= svga->latch;
|
||||
val32 |= la;
|
||||
break;
|
||||
case 3:
|
||||
/* xor */
|
||||
val32 &= bit_mask;
|
||||
val32 ^= svga->latch;
|
||||
val32 ^= la;
|
||||
break;
|
||||
}
|
||||
|
||||
/* mask data according to sr[2] */
|
||||
write_mask = mask16[writemask2 & 0x0f];
|
||||
addr >>= 2;
|
||||
if (svga->adv_flags & FLAG_ADDR_BY8)
|
||||
write_mask |= (mask16[(writemask2 & 0xf0) >> 4] << 32);
|
||||
addr >>= ((svga->adv_flags & FLAG_ADDR_BY8) ? 3 : 2);
|
||||
|
||||
if (svga->adv_flags & FLAG_ADDR_BY8)
|
||||
((uint64_t *)(svga->vram))[addr] = (((uint64_t *)(svga->vram))[addr] & ~write_mask) | (val32 & write_mask);
|
||||
else
|
||||
((uint32_t *)(svga->vram))[addr] = (((uint32_t *)(svga->vram))[addr] & ~write_mask) | (val32 & write_mask);
|
||||
}
|
||||
|
||||
@@ -1036,11 +1106,17 @@ uint8_t
|
||||
svga_read_common(uint32_t addr, uint8_t linear, priv_t priv)
|
||||
{
|
||||
svga_t *svga = (svga_t *)priv;
|
||||
uint32_t latch_addr = 0, ret;
|
||||
uint32_t latch_addr = 0;
|
||||
int memory_map_mode, readplane = svga->readplane;
|
||||
uint32_t mask0, mask1;
|
||||
uint64_t ret;
|
||||
|
||||
if (svga->adv_flags & FLAG_ADDR_BY8)
|
||||
readplane = svga->gdcreg[4] & 7;
|
||||
|
||||
cycles -= video_timing_read_b;
|
||||
|
||||
|
||||
if (! linear) {
|
||||
memory_map_mode = (svga->gdcreg[6] >> 2) & 3;
|
||||
|
||||
@@ -1053,6 +1129,9 @@ svga_read_common(uint32_t addr, uint8_t linear, priv_t priv)
|
||||
case 1:
|
||||
if (addr >= 0x10000)
|
||||
return 0xff;
|
||||
else if (svga->adv_flags & FLAG_EXTRA_BANKS)
|
||||
addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1];
|
||||
else
|
||||
addr += svga->read_bank;
|
||||
break;
|
||||
|
||||
@@ -1070,10 +1149,15 @@ svga_read_common(uint32_t addr, uint8_t linear, priv_t priv)
|
||||
break;
|
||||
}
|
||||
|
||||
if (svga->adv_flags & FLAG_ADDR_BY8)
|
||||
latch_addr = (addr << 3) & svga->decode_mask;
|
||||
else
|
||||
latch_addr = (addr << 2) & svga->decode_mask;
|
||||
}
|
||||
|
||||
if (svga->chain4 || svga->fb_only) {
|
||||
if (svga->adv_flags & FLAG_ADDR_BY8)
|
||||
addr <<= 3;
|
||||
else if (svga->chain4 || svga->fb_only) {
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= svga->vram_max)
|
||||
return 0xff;
|
||||
@@ -1100,13 +1184,28 @@ svga_read_common(uint32_t addr, uint8_t linear, priv_t priv)
|
||||
|
||||
addr &= svga->vram_mask;
|
||||
|
||||
svga->latch = ((uint32_t *)(svga->vram))[addr >> 2];
|
||||
if (svga->adv_flags & FLAG_ADDR_BY8) {
|
||||
if (svga->adv_flags & FLAG_LATCH8)
|
||||
svga->latch = ((uint64_t *)(svga->vram))[addr >> 3];
|
||||
else
|
||||
svga->latch = (svga->latch & 0xffffffff00000000ULL) | (((uint64_t *)(svga->vram))[addr >> 3] & 0xffffffff);
|
||||
} else
|
||||
svga->latch = (svga->latch & 0xffffffff00000000ULL) | ((uint32_t *)(svga->vram))[addr >> 2];
|
||||
} else {
|
||||
if (latch_addr > svga->vram_max)
|
||||
svga->latch = 0xffffffff;
|
||||
if (svga->adv_flags & FLAG_LATCH8)
|
||||
svga->latch = 0xffffffffffffffffULL;
|
||||
else
|
||||
svga->latch = (svga->latch & 0xffffffff00000000ULL) | 0xffffffff;
|
||||
else {
|
||||
latch_addr &= svga->vram_mask;
|
||||
svga->latch = ((uint32_t *)(svga->vram))[latch_addr >> 2];
|
||||
if (svga->adv_flags & FLAG_ADDR_BY8) {
|
||||
if (svga->adv_flags & FLAG_LATCH8)
|
||||
svga->latch = ((uint64_t *)(svga->vram))[latch_addr >> 3];
|
||||
else
|
||||
svga->latch = (svga->latch & 0xffffffff00000000ULL) | (((uint64_t *)(svga->vram))[latch_addr >> 3] & 0xffffffff);
|
||||
} else
|
||||
svga->latch = (svga->latch & 0xffffffff00000000ULL) | ((uint32_t *)(svga->vram))[latch_addr >> 2];
|
||||
}
|
||||
|
||||
if (addr >= svga->vram_max)
|
||||
@@ -1118,15 +1217,21 @@ svga_read_common(uint32_t addr, uint8_t linear, priv_t priv)
|
||||
if (!(svga->gdcreg[5] & 8)) {
|
||||
/* read mode 0 */
|
||||
return (svga->latch >> (readplane * 8)) & 0xff;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* read mode 1 */
|
||||
if (svga->adv_flags & FLAG_LATCH8) {
|
||||
mask0 = mask16[svga->colourcompare & 0x0f] | (mask16[(svga->colourcompare & 0xf0) >> 4] << 32);
|
||||
mask1 = mask16[svga->colournocare & 0x0f] | (mask16[(svga->colournocare & 0xf0) >> 4] << 32);
|
||||
ret = (svga->latch ^ mask0) & mask1;
|
||||
ret |= ret >> 32;
|
||||
} else
|
||||
ret = (svga->latch ^ mask16[svga->colourcompare & 0x0f]) & mask16[svga->colournocare & 0x0f];
|
||||
ret |= ret >> 16;
|
||||
ret |= ret >> 8;
|
||||
ret = (~ret) & 0xff;
|
||||
return(ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
@@ -1164,6 +1269,13 @@ svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga)
|
||||
int x_add = (enable_overscan) ? 16 : 0;
|
||||
int i, j;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
svga->frames++;
|
||||
|
||||
if ((xsize > 2032) || (ysize > 2032)) {
|
||||
@@ -1243,6 +1355,7 @@ void
|
||||
svga_writew_common(uint32_t addr, uint16_t val, uint8_t linear, priv_t priv)
|
||||
{
|
||||
svga_t *svga = (svga_t *)priv;
|
||||
int memory_map_mode;
|
||||
|
||||
if (!svga->fast) {
|
||||
svga_write_common(addr, val & 0xff, linear, priv);
|
||||
@@ -1252,8 +1365,16 @@ svga_writew_common(uint32_t addr, uint16_t val, uint8_t linear, priv_t priv)
|
||||
|
||||
cycles -= video_timing_write_w;
|
||||
|
||||
if (!linear)
|
||||
|
||||
if (!linear) {
|
||||
memory_map_mode = (svga->gdcreg[6] >> 2) & 3;
|
||||
if ((memory_map_mode == 1) && (svga->adv_flags & FLAG_EXTRA_BANKS))
|
||||
addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1];
|
||||
else
|
||||
addr = (addr & svga->banked_mask) + svga->write_bank;
|
||||
}
|
||||
|
||||
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= svga->vram_max)
|
||||
return;
|
||||
@@ -1281,6 +1402,7 @@ void
|
||||
svga_writel_common(uint32_t addr, uint32_t val, uint8_t linear, priv_t priv)
|
||||
{
|
||||
svga_t *svga = (svga_t *)priv;
|
||||
int memory_map_mode;
|
||||
|
||||
if (!svga->fast) {
|
||||
svga_write_common(addr, val, linear, priv);
|
||||
@@ -1292,8 +1414,14 @@ svga_writel_common(uint32_t addr, uint32_t val, uint8_t linear, priv_t priv)
|
||||
|
||||
cycles -= video_timing_write_l;
|
||||
|
||||
if (!linear)
|
||||
|
||||
if (!linear) {
|
||||
memory_map_mode = (svga->gdcreg[6] >> 2) & 3;
|
||||
if ((memory_map_mode == 1) && (svga->adv_flags & FLAG_EXTRA_BANKS))
|
||||
addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1];
|
||||
else
|
||||
addr = (addr & svga->banked_mask) + svga->write_bank;
|
||||
}
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= svga->vram_max)
|
||||
return;
|
||||
@@ -1338,14 +1466,21 @@ uint16_t
|
||||
svga_readw_common(uint32_t addr, uint8_t linear, priv_t priv)
|
||||
{
|
||||
svga_t *svga = (svga_t *)priv;
|
||||
int memory_map_mode;
|
||||
|
||||
if (!svga->fast)
|
||||
return svga_read_common(addr, linear, priv) | (svga_read_common(addr + 1, linear, priv) << 8);
|
||||
|
||||
cycles -= video_timing_read_w;
|
||||
|
||||
if (!linear)
|
||||
|
||||
if (!linear) {
|
||||
memory_map_mode = (svga->gdcreg[6] >> 2) & 3;
|
||||
if ((memory_map_mode == 1) && (svga->adv_flags & FLAG_EXTRA_BANKS))
|
||||
addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1];
|
||||
else
|
||||
addr = (addr & svga->banked_mask) + svga->read_bank;
|
||||
}
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= svga->vram_max)
|
||||
return 0xffff;
|
||||
@@ -1372,6 +1507,7 @@ uint32_t
|
||||
svga_readl_common(uint32_t addr, uint8_t linear, priv_t priv)
|
||||
{
|
||||
svga_t *svga = (svga_t *)priv;
|
||||
int memory_map_mode;
|
||||
|
||||
if (!svga->fast) {
|
||||
return svga_read_common(addr, linear, priv) | (svga_read_common(addr + 1, linear, priv) << 8) |
|
||||
@@ -1380,8 +1516,13 @@ svga_readl_common(uint32_t addr, uint8_t linear, priv_t priv)
|
||||
|
||||
cycles -= video_timing_read_l;
|
||||
|
||||
if (!linear)
|
||||
if (!linear) {
|
||||
memory_map_mode = (svga->gdcreg[6] >> 2) & 3;
|
||||
if ((memory_map_mode == 1) && (svga->adv_flags & FLAG_EXTRA_BANKS))
|
||||
addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1];
|
||||
else
|
||||
addr = (addr & svga->banked_mask) + svga->read_bank;
|
||||
}
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= svga->vram_max)
|
||||
return 0xffffffff;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the generic SVGA driver.
|
||||
*
|
||||
* Version: @(#)vid_svga.h 1.0.8 2019/05/17
|
||||
* Version: @(#)vid_svga.h 1.0.9 2019/10/21
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -39,6 +39,9 @@
|
||||
#ifndef VIDEO_SVGA_H
|
||||
# define VIDEO_SVGA_H
|
||||
|
||||
#define FLAG_EXTRA_BANKS 1
|
||||
#define FLAG_ADDR_BY8 2
|
||||
#define FLAG_LATCH8 4
|
||||
|
||||
typedef struct {
|
||||
int ena,
|
||||
@@ -70,8 +73,8 @@ typedef struct svga_t
|
||||
displine, fullchange,
|
||||
video_res_x, video_res_y, video_bpp, frames, fps,
|
||||
vram_display_mask,
|
||||
hwcursor_on, overlay_on,
|
||||
hwcursor_oddeven, overlay_oddeven;
|
||||
hwcursor_on, dac_hwcursor_on, overlay_on,
|
||||
hwcursor_oddeven, dac_hwcursor_oddeven, overlay_oddeven;
|
||||
|
||||
/*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 :
|
||||
0MB-1MB - VRAM
|
||||
@@ -84,12 +87,15 @@ typedef struct svga_t
|
||||
uint32_t decode_mask, vram_max,
|
||||
vram_mask,
|
||||
charseta, charsetb,
|
||||
latch, ma_latch,
|
||||
adv_flags, ma_latch,
|
||||
ma, maback,
|
||||
write_bank, read_bank,
|
||||
extra_banks[2],
|
||||
banked_mask,
|
||||
ca, overscan_color,
|
||||
pallook[256];
|
||||
*map8, pallook[256];
|
||||
|
||||
uint64_t latch;
|
||||
|
||||
PALETTE vgapal;
|
||||
|
||||
@@ -99,6 +105,7 @@ typedef struct svga_t
|
||||
double clock;
|
||||
|
||||
hwcursor_t hwcursor, hwcursor_latch,
|
||||
dac_hwcursor, dac_hwcursor_latch,
|
||||
overlay, overlay_latch;
|
||||
|
||||
void (*render)(struct svga_t *svga);
|
||||
@@ -106,6 +113,7 @@ typedef struct svga_t
|
||||
void (*video_out)(uint16_t addr, uint8_t val, priv_t);
|
||||
uint8_t (*video_in) (uint16_t addr, priv_t);
|
||||
void (*hwcursor_draw)(struct svga_t *svga, int displine);
|
||||
void (*dac_hwcursor_draw)(struct svga_t *svga, int displine);
|
||||
void (*overlay_draw)(struct svga_t *svga, int displine);
|
||||
void (*vblank_start)(struct svga_t *svga);
|
||||
void (*ven_write)(struct svga_t *svga, uint8_t val, uint32_t addr);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* SVGA renderers.
|
||||
*
|
||||
* Version: @(#)vid_svga_render.c 1.0.17 2019/05/17
|
||||
* Version: @(#)vid_svga_render.c 1.0.18 2019/10/21
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -570,6 +570,147 @@ svga_render_8bpp_highres(svga_t *svga)
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_8bpp_gs_lowres(svga_t *svga)
|
||||
{
|
||||
int y_add = enable_overscan ? (overscan_y >> 1) : 0;
|
||||
int x_add = enable_overscan ? 8 : 0;
|
||||
int offset, x;
|
||||
uint32_t dat;
|
||||
pel_t *p;
|
||||
|
||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
|
||||
{
|
||||
offset = (8 - (svga->scrollcache & 6)) + 24;
|
||||
p = &screen->line[svga->displine + y_add][offset + x_add];
|
||||
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
for (x = 0; x <= svga->hdisp; x += 8)
|
||||
{
|
||||
dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
|
||||
|
||||
p[0].val = p[1].val = video_8togs[dat & 0xff];
|
||||
p[2].val = p[3].val = video_8togs[(dat >> 8) & 0xff];
|
||||
p[4].val = p[5].val = video_8togs[(dat >> 16) & 0xff];
|
||||
p[6].val = p[7].val = video_8togs[(dat >> 24) & 0xff];
|
||||
|
||||
svga->ma += 4;
|
||||
p += 8;
|
||||
}
|
||||
svga->ma &= svga->vram_display_mask;
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_8bpp_gs_highres(svga_t *svga)
|
||||
{
|
||||
int y_add = enable_overscan ? (overscan_y >> 1) : 0;
|
||||
int x_add = enable_overscan ? 8 : 0;
|
||||
int offset, x;
|
||||
uint32_t dat;
|
||||
pel_t *p;
|
||||
|
||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
|
||||
{
|
||||
offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
||||
p = &screen->line[svga->displine + y_add][offset + x_add];
|
||||
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
for (x = 0; x <= svga->hdisp; x += 8)
|
||||
{
|
||||
dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
|
||||
p[0].val = video_8togs[dat & 0xff];
|
||||
p[1].val = video_8togs[(dat >> 8) & 0xff];
|
||||
p[2].val = video_8togs[(dat >> 16) & 0xff];
|
||||
p[3].val = video_8togs[(dat >> 24) & 0xff];
|
||||
|
||||
dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
|
||||
p[4].val = video_8togs[dat & 0xff];
|
||||
p[5].val = video_8togs[(dat >> 8) & 0xff];
|
||||
p[6].val = video_8togs[(dat >> 16) & 0xff];
|
||||
p[7].val = video_8togs[(dat >> 24) & 0xff];
|
||||
|
||||
svga->ma += 8;
|
||||
p += 8;
|
||||
}
|
||||
svga->ma &= svga->vram_display_mask;
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_8bpp_rgb_lowres(svga_t *svga)
|
||||
{
|
||||
int y_add = enable_overscan ? (overscan_y >> 1) : 0;
|
||||
int x_add = enable_overscan ? 8 : 0;
|
||||
int offset, x;
|
||||
uint32_t dat;
|
||||
pel_t *p;
|
||||
|
||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
|
||||
{
|
||||
offset = (8 - (svga->scrollcache & 6)) + 24;
|
||||
p = &screen->line[svga->displine + y_add][offset + x_add];
|
||||
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
for (x = 0; x <= svga->hdisp; x += 8)
|
||||
{
|
||||
dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
|
||||
|
||||
p[0].val = p[1].val = video_8to32[dat & 0xff];
|
||||
p[2].val = p[3].val = video_8to32[(dat >> 8) & 0xff];
|
||||
p[4].val = p[5].val = video_8to32[(dat >> 16) & 0xff];
|
||||
p[6].val = p[7].val = video_8to32[(dat >> 24) & 0xff];
|
||||
|
||||
svga->ma += 4;
|
||||
p += 8;
|
||||
}
|
||||
svga->ma &= svga->vram_display_mask;
|
||||
}
|
||||
}
|
||||
|
||||
void svga_render_8bpp_rgb_highres(svga_t *svga)
|
||||
{
|
||||
int y_add = enable_overscan ? (overscan_y >> 1) : 0;
|
||||
int x_add = enable_overscan ? 8 : 0;
|
||||
int offset, x;
|
||||
uint32_t dat;
|
||||
pel_t *p;
|
||||
|
||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
|
||||
{
|
||||
offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
||||
p = &screen->line[svga->displine + y_add][offset + x_add];
|
||||
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
for (x = 0; x <= svga->hdisp; x += 8)
|
||||
{
|
||||
dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
|
||||
p[0].val = video_8to32[dat & 0xff];
|
||||
p[1].val = video_8to32[(dat >> 8) & 0xff];
|
||||
p[2].val = video_8to32[(dat >> 16) & 0xff];
|
||||
p[3].val = video_8to32[(dat >> 24) & 0xff];
|
||||
|
||||
dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
|
||||
p[4].val = video_8to32[dat & 0xff];
|
||||
p[5].val = video_8to32[(dat >> 8) & 0xff];
|
||||
p[6].val = video_8to32[(dat >> 16) & 0xff];
|
||||
p[7].val = video_8to32[(dat >> 24) & 0xff];
|
||||
|
||||
svga->ma += 8;
|
||||
p += 8;
|
||||
}
|
||||
svga->ma &= svga->vram_display_mask;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
svga_render_15bpp_lowres(svga_t *svga)
|
||||
@@ -646,6 +787,41 @@ svga_render_15bpp_highres(svga_t *svga)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
svga_render_mixed_lowres(svga_t *svga)
|
||||
{
|
||||
int y_add = enable_overscan ? (overscan_y >> 1) : 0;
|
||||
int x_add = enable_overscan ? 8 : 0;
|
||||
int offset, x;
|
||||
uint32_t dat;
|
||||
pel_t *p;
|
||||
|
||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) {
|
||||
offset = (8 - (svga->scrollcache & 6)) + 24;
|
||||
p = &screen->line[svga->displine + y_add][offset + x_add];
|
||||
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
for (x = 0; x <= svga->hdisp; x += 4)
|
||||
{
|
||||
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
|
||||
p[x].val = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0x7fff];
|
||||
|
||||
dat >>= 16;
|
||||
p[x + 1].val = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0x7fff];
|
||||
|
||||
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
|
||||
p[x + 2].val = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0x7fff];
|
||||
|
||||
dat >>= 16;
|
||||
p[x + 3].val = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0x7fff];
|
||||
}
|
||||
svga->ma += x << 1;
|
||||
svga->ma &= svga->vram_display_mask;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
svga_render_mixed_highres(svga_t *svga)
|
||||
|
||||
@@ -60,8 +60,14 @@ extern void svga_render_4bpp_lowres(svga_t *svga);
|
||||
extern void svga_render_4bpp_highres(svga_t *svga);
|
||||
extern void svga_render_8bpp_lowres(svga_t *svga);
|
||||
extern void svga_render_8bpp_highres(svga_t *svga);
|
||||
extern void svga_render_8bpp_gs_lowres(svga_t *svga);
|
||||
extern void svga_render_8bpp_gs_highres(svga_t *svga);
|
||||
extern void svga_render_8bpp_rgb_lowres(svga_t *svga);
|
||||
extern void svga_render_8bpp_rgb_highres(svga_t *svga);
|
||||
extern void svga_render_15bpp_lowres(svga_t *svga);
|
||||
extern void svga_render_15bpp_highres(svga_t *svga);
|
||||
extern void svga_render_mixed_lowres(svga_t *svga);
|
||||
extern void svga_render_mixed_highres(svga_t *svga);
|
||||
extern void svga_render_16bpp_lowres(svga_t *svga);
|
||||
extern void svga_render_16bpp_highres(svga_t *svga);
|
||||
extern void svga_render_24bpp_lowres(svga_t *svga);
|
||||
@@ -72,7 +78,6 @@ extern void svga_render_ABGR8888_lowres(svga_t *svga);
|
||||
extern void svga_render_ABGR8888_highres(svga_t *svga);
|
||||
extern void svga_render_RGBA8888_lowres(svga_t *svga);
|
||||
extern void svga_render_RGBA8888_highres(svga_t *svga);
|
||||
extern void svga_render_mixed_highres(svga_t *svga);
|
||||
|
||||
extern void (*svga_render)(svga_t *svga);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Main video-rendering module.
|
||||
*
|
||||
* Version: @(#)video.c 1.0.31 2019/05/05
|
||||
* Version: @(#)video.c 1.0.32 2019/10/15
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -73,6 +73,8 @@ dbcs_font_t *fontdatk = NULL, /* Korean KSC-5601 font */
|
||||
bitmap_t *screen = NULL;
|
||||
|
||||
uint32_t *video_6to8 = NULL,
|
||||
*video_8togs = NULL,
|
||||
*video_8to32 = NULL,
|
||||
*video_15to32 = NULL,
|
||||
*video_16to32 = NULL;
|
||||
uint32_t pal_lookup[256];
|
||||
@@ -631,6 +633,28 @@ calc_6to8(int c)
|
||||
return(i8 & 0xff);
|
||||
}
|
||||
|
||||
static int
|
||||
calc_8to32(int c)
|
||||
{
|
||||
int b, g, r;
|
||||
double db, dg, dr;
|
||||
|
||||
b = (c & 3);
|
||||
g = ((c >> 2) & 7);
|
||||
r = ((c >> 5) & 7);
|
||||
db = (((double) b) / 3.0) * 255.0;
|
||||
dg = (((double) g) / 7.0) * 255.0;
|
||||
dr = (((double) r) / 7.0) * 255.0;
|
||||
b = (int) db;
|
||||
g = ((int) dg) << 8;
|
||||
r = ((int) dr) << 16;
|
||||
|
||||
return(b | g | r);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int
|
||||
calc_15to32(int c)
|
||||
@@ -768,6 +792,15 @@ video_init(void)
|
||||
video_6to8 = (uint32_t *)mem_alloc(4 * 256);
|
||||
for (c = 0; c < 256; c++)
|
||||
video_6to8[c] = calc_6to8(c);
|
||||
|
||||
video_8togs = malloc(4 * 256);
|
||||
for (c = 0; c < 256; c++)
|
||||
video_8togs[c] = c | (c << 16) | (c << 24);
|
||||
|
||||
video_8to32 = malloc(4 * 256);
|
||||
for (c = 0; c < 256; c++)
|
||||
video_8to32[c] = calc_8to32(c);
|
||||
|
||||
video_15to32 = (uint32_t *)mem_alloc(4 * 65536);
|
||||
for (c = 0; c < 65536; c++)
|
||||
video_15to32[c] = calc_15to32(c);
|
||||
@@ -795,6 +828,8 @@ video_close(void)
|
||||
thread_destroy_event(video_blit.wake_ev);
|
||||
|
||||
free(video_6to8);
|
||||
free(video_8togs);
|
||||
free(video_8to32);
|
||||
free(video_15to32);
|
||||
free(video_16to32);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the video controller module.
|
||||
*
|
||||
* Version: @(#)video.h 1.0.37 2019/06/05
|
||||
* Version: @(#)video.h 1.0.38 2019/10/15
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -125,6 +125,8 @@ extern dbcs_font_t *fontdatk,
|
||||
|
||||
extern bitmap_t *screen;
|
||||
extern uint32_t *video_6to8,
|
||||
*video_8togs,
|
||||
*video_8to32,
|
||||
*video_15to32,
|
||||
*video_16to32;
|
||||
extern uint32_t pal_lookup[256];
|
||||
|
||||
Reference in New Issue
Block a user