Rework (S)VGA memory addressing. Support correct chain-4 mapping, as well
as MA13/14 remapping for non-CGA modes. Fixes corruption on Windows 3.x when using Paradise drivers, also fixes corruption in Titan.
This commit is contained in:
parent
f9cdcfa6b6
commit
092be3e9d4
12 changed files with 740 additions and 239 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
/*Cirrus Logic CL-GD5429 emulation*/
|
/*Cirrus Logic CL-GD5429 emulation*/
|
||||||
|
//SR7.0 = "true packed-pixel memory addressing"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
|
@ -178,6 +179,8 @@ void gd5429_out(uint16_t addr, uint8_t val, void *p)
|
||||||
|
|
||||||
case 0x07:
|
case 0x07:
|
||||||
svga->set_reset_disabled = svga->seqregs[7] & 1;
|
svga->set_reset_disabled = svga->seqregs[7] & 1;
|
||||||
|
svga->packed_chain4 = svga->seqregs[7] & 1;
|
||||||
|
svga_recalctimings(svga);
|
||||||
case 0x17:
|
case 0x17:
|
||||||
if (gd5429->type >= CL_TYPE_GD5429)
|
if (gd5429->type >= CL_TYPE_GD5429)
|
||||||
gd5429_recalc_mapping(gd5429);
|
gd5429_recalc_mapping(gd5429);
|
||||||
|
|
@ -844,11 +847,16 @@ void gd5429_write_linear(uint32_t addr, uint8_t val, void *p)
|
||||||
svga->fullchange = 2;
|
svga->fullchange = 2;
|
||||||
if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING)
|
if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING)
|
||||||
addr <<= 3;
|
addr <<= 3;
|
||||||
else if ((svga->chain4 || svga->fb_only) && (svga->writemode < 4))
|
else if (((svga->chain4 && svga->packed_chain4) || svga->fb_only) && (svga->writemode < 4))
|
||||||
{
|
{
|
||||||
writemask2 = 1 << (addr & 3);
|
writemask2 = 1 << (addr & 3);
|
||||||
addr &= ~3;
|
addr &= ~3;
|
||||||
}
|
}
|
||||||
|
else if (svga->chain4)
|
||||||
|
{
|
||||||
|
writemask2 = 1 << (addr & 3);
|
||||||
|
addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
|
||||||
|
}
|
||||||
else if (svga->chain2_write)
|
else if (svga->chain2_write)
|
||||||
{
|
{
|
||||||
writemask2 &= ~0xa;
|
writemask2 &= ~0xa;
|
||||||
|
|
@ -1193,13 +1201,18 @@ uint8_t gd5429_read_linear(uint32_t addr, void *p)
|
||||||
|
|
||||||
if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING)
|
if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING)
|
||||||
addr <<= 3;
|
addr <<= 3;
|
||||||
else if (svga->chain4 || svga->fb_only)
|
else if ((svga->chain4 && svga->packed_chain4) || svga->fb_only)
|
||||||
{
|
{
|
||||||
addr &= svga->decode_mask;
|
addr &= svga->decode_mask;
|
||||||
if (addr >= svga->vram_max)
|
if (addr >= svga->vram_max)
|
||||||
return 0xff;
|
return 0xff;
|
||||||
return svga->vram[addr & svga->vram_mask];
|
return svga->vram[addr & svga->vram_mask];
|
||||||
}
|
}
|
||||||
|
else if (svga->chain4)
|
||||||
|
{
|
||||||
|
readplane = addr & 3;
|
||||||
|
addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
|
||||||
|
}
|
||||||
else if (svga->chain2_read)
|
else if (svga->chain2_read)
|
||||||
{
|
{
|
||||||
readplane = (readplane & 2) | (addr & 1);
|
readplane = (readplane & 2) | (addr & 1);
|
||||||
|
|
|
||||||
|
|
@ -496,6 +496,8 @@ void *et4000_init()
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
et4000->svga.packed_chain4 = 1;
|
||||||
|
|
||||||
return et4000;
|
return et4000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -527,6 +529,8 @@ void *et4000k_init()
|
||||||
et4000->svga.ksc5601_swap_mode = 0;
|
et4000->svga.ksc5601_swap_mode = 0;
|
||||||
et4000->svga.ksc5601_english_font_type = 0;
|
et4000->svga.ksc5601_english_font_type = 0;
|
||||||
|
|
||||||
|
et4000->svga.packed_chain4 = 1;
|
||||||
|
|
||||||
return et4000;
|
return et4000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -571,6 +575,8 @@ void *et4000_kasan_init()
|
||||||
et4000->svga.ksc5601_swap_mode = 0;
|
et4000->svga.ksc5601_swap_mode = 0;
|
||||||
et4000->svga.ksc5601_english_font_type = 0x1FF;
|
et4000->svga.ksc5601_english_font_type = 0x1FF;
|
||||||
|
|
||||||
|
et4000->svga.packed_chain4 = 1;
|
||||||
|
|
||||||
return et4000;
|
return et4000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1207,6 +1207,8 @@ void *et4000w32p_init()
|
||||||
et4000->fifo_not_full_event = thread_create_event();
|
et4000->fifo_not_full_event = thread_create_event();
|
||||||
et4000->fifo_thread = thread_create(fifo_thread, et4000);
|
et4000->fifo_thread = thread_create(fifo_thread, et4000);
|
||||||
|
|
||||||
|
et4000->svga.packed_chain4 = 1;
|
||||||
|
|
||||||
return et4000;
|
return et4000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,9 @@ void ht216_out(uint16_t addr, uint8_t val, void *p)
|
||||||
ht216->read_bank_reg[0] = (ht216->read_bank_reg[0] & ~0x10) | ((val & 1) ? 0x10 : 0);
|
ht216->read_bank_reg[0] = (ht216->read_bank_reg[0] & ~0x10) | ((val & 1) ? 0x10 : 0);
|
||||||
ht216->write_bank_reg[0] = (ht216->write_bank_reg[0] & ~0x10) | ((val & 1) ? 0x10 : 0);
|
ht216->write_bank_reg[0] = (ht216->write_bank_reg[0] & ~0x10) | ((val & 1) ? 0x10 : 0);
|
||||||
break;
|
break;
|
||||||
|
case 0xfc:
|
||||||
|
svga->packed_chain4 = val & 0x20;
|
||||||
|
break;
|
||||||
case 0xff:
|
case 0xff:
|
||||||
svga->hwcursor.addr = ((ht216->ht_regs[0x94] << 6) | (3 << 14) | ((val & 0x60) << 11)) << 2;
|
svga->hwcursor.addr = ((ht216->ht_regs[0x94] << 6) | (3 << 14) | ((val & 0x60) << 11)) << 2;
|
||||||
//pclog("cursor_addr = %05x\n", svga->hwcursor.addr);
|
//pclog("cursor_addr = %05x\n", svga->hwcursor.addr);
|
||||||
|
|
@ -421,6 +424,14 @@ static inline uint8_t extalu(int op, uint8_t input_a, uint8_t input_b)
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*Remap address for chain-4/doubleword style layout*/
|
||||||
|
static inline uint32_t dword_remap(svga_t *svga, uint32_t in_addr)
|
||||||
|
{
|
||||||
|
if (svga->packed_chain4)
|
||||||
|
return in_addr;
|
||||||
|
return ((in_addr & 0xfffc) << 2) | ((in_addr & 0x30000) >> 14) | (in_addr & ~0x3ffff);
|
||||||
|
}
|
||||||
|
|
||||||
static void ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t cpu_dat_unexpanded)
|
static void ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t cpu_dat_unexpanded)
|
||||||
{
|
{
|
||||||
svga_t *svga = &ht216->svga;
|
svga_t *svga = &ht216->svga;
|
||||||
|
|
@ -430,10 +441,10 @@ static void ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8
|
||||||
|
|
||||||
if (!(svga->gdcreg[6] & 1))
|
if (!(svga->gdcreg[6] & 1))
|
||||||
svga->fullchange = 2;
|
svga->fullchange = 2;
|
||||||
if (svga->chain4 || svga->fb_only)
|
if (svga->chain4)
|
||||||
{
|
{
|
||||||
writemask2 = 1 << (addr & 3);
|
writemask2 = 1 << (addr & 3);
|
||||||
addr&=~3;
|
addr = dword_remap(svga, addr) & ~3;
|
||||||
}
|
}
|
||||||
else if (svga->chain2_write)
|
else if (svga->chain2_write)
|
||||||
{
|
{
|
||||||
|
|
@ -666,9 +677,10 @@ static void ht216_dm_extalu_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat
|
||||||
uint8_t input_a = 0, input_b = 0;
|
uint8_t input_a = 0, input_b = 0;
|
||||||
uint8_t fg, bg;
|
uint8_t fg, bg;
|
||||||
uint8_t output;
|
uint8_t output;
|
||||||
|
uint32_t remapped_addr = dword_remap(svga, addr);
|
||||||
|
|
||||||
if (ht216->ht_regs[0xcd] & HT_REG_CD_RMWMDE) /*RMW*/
|
if (ht216->ht_regs[0xcd] & HT_REG_CD_RMWMDE) /*RMW*/
|
||||||
input_b = svga->vram[addr];
|
input_b = svga->vram[remapped_addr];
|
||||||
else
|
else
|
||||||
input_b = ht216->bg_latch[addr & 7];
|
input_b = ht216->bg_latch[addr & 7];
|
||||||
|
|
||||||
|
|
@ -695,9 +707,9 @@ static void ht216_dm_extalu_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat
|
||||||
bg = extalu(ht216->ht_regs[0xce] & 0xf, input_a, input_b);
|
bg = extalu(ht216->ht_regs[0xce] & 0xf, input_a, input_b);
|
||||||
// svga->vram[addr]
|
// svga->vram[addr]
|
||||||
output = (fg & rop_select) | (bg & ~rop_select);
|
output = (fg & rop_select) | (bg & ~rop_select);
|
||||||
svga->vram[addr] = (svga->vram[addr] & ~bit_mask) | (output & bit_mask);
|
svga->vram[addr] = (svga->vram[remapped_addr] & ~bit_mask) | (output & bit_mask);
|
||||||
// pclog(" A=%02x B=%02x R=%02x FG=%02x BG=%02x ops=%02x val=%02x addr=%05x\n", input_a, input_b, rop_select, fg, bg, ht216->ht_regs[0xce], svga->vram[addr], addr);
|
// pclog(" A=%02x B=%02x R=%02x FG=%02x BG=%02x ops=%02x val=%02x addr=%05x\n", input_a, input_b, rop_select, fg, bg, ht216->ht_regs[0xce], svga->vram[addr], addr);
|
||||||
svga->changedvram[addr >> 12] = changeframecount;
|
svga->changedvram[remapped_addr >> 12] = changeframecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val)
|
static void ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val)
|
||||||
|
|
@ -909,7 +921,7 @@ static uint8_t ht216_read_common(ht216_t *ht216, uint32_t addr)
|
||||||
|
|
||||||
egareads++;
|
egareads++;
|
||||||
|
|
||||||
if (svga->chain4 || svga->fb_only)
|
if (svga->chain4)
|
||||||
{
|
{
|
||||||
// if (ht216->ht_regs[0xcd])
|
// if (ht216->ht_regs[0xcd])
|
||||||
// pclog(" addr=%08x decode_mask=%08x vram_max=%08x\n", addr, svga->decode_mask, svga->vram_max);
|
// pclog(" addr=%08x decode_mask=%08x vram_max=%08x\n", addr, svga->decode_mask, svga->vram_max);
|
||||||
|
|
@ -920,20 +932,20 @@ static uint8_t ht216_read_common(ht216_t *ht216, uint32_t addr)
|
||||||
latch_addr = (addr & svga->vram_mask) & ~7;
|
latch_addr = (addr & svga->vram_mask) & ~7;
|
||||||
if (ht216->ht_regs[0xcd] & HT_REG_CD_ASTODE)
|
if (ht216->ht_regs[0xcd] & HT_REG_CD_ASTODE)
|
||||||
latch_addr += (svga->gdcreg[3] & 7);
|
latch_addr += (svga->gdcreg[3] & 7);
|
||||||
ht216->bg_latch[0] = svga->vram[latch_addr];
|
ht216->bg_latch[0] = svga->vram[dword_remap(svga, latch_addr)];
|
||||||
ht216->bg_latch[1] = svga->vram[latch_addr + 1];
|
ht216->bg_latch[1] = svga->vram[dword_remap(svga, latch_addr + 1)];
|
||||||
ht216->bg_latch[2] = svga->vram[latch_addr + 2];
|
ht216->bg_latch[2] = svga->vram[dword_remap(svga, latch_addr + 2)];
|
||||||
ht216->bg_latch[3] = svga->vram[latch_addr + 3];
|
ht216->bg_latch[3] = svga->vram[dword_remap(svga, latch_addr + 3)];
|
||||||
ht216->bg_latch[4] = svga->vram[latch_addr + 4];
|
ht216->bg_latch[4] = svga->vram[dword_remap(svga, latch_addr + 4)];
|
||||||
ht216->bg_latch[5] = svga->vram[latch_addr + 5];
|
ht216->bg_latch[5] = svga->vram[dword_remap(svga, latch_addr + 5)];
|
||||||
ht216->bg_latch[6] = svga->vram[latch_addr + 6];
|
ht216->bg_latch[6] = svga->vram[dword_remap(svga, latch_addr + 6)];
|
||||||
ht216->bg_latch[7] = svga->vram[latch_addr + 7];
|
ht216->bg_latch[7] = svga->vram[dword_remap(svga, latch_addr + 7)];
|
||||||
|
|
||||||
/*pclog(" Read %08x %02x %02x %02x %02x %02x %02x %02x %02x\n", addr,
|
/*pclog(" Read %08x %02x %02x %02x %02x %02x %02x %02x %02x\n", addr,
|
||||||
ht216->bg_latch[0],ht216->bg_latch[1],ht216->bg_latch[2],ht216->bg_latch[3],
|
ht216->bg_latch[0],ht216->bg_latch[1],ht216->bg_latch[2],ht216->bg_latch[3],
|
||||||
ht216->bg_latch[4],ht216->bg_latch[5],ht216->bg_latch[6],ht216->bg_latch[7]);*/
|
ht216->bg_latch[4],ht216->bg_latch[5],ht216->bg_latch[6],ht216->bg_latch[7]);*/
|
||||||
|
|
||||||
return svga->vram[addr & svga->vram_mask];
|
return svga->vram[dword_remap(svga, addr) & svga->vram_mask];
|
||||||
}
|
}
|
||||||
else if (svga->chain2_read)
|
else if (svga->chain2_read)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
51
src/vid_s3.c
51
src/vid_s3.c
|
|
@ -1010,6 +1010,7 @@ void s3_out(uint16_t addr, uint8_t val, void *p)
|
||||||
{
|
{
|
||||||
case 0x31:
|
case 0x31:
|
||||||
s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4);
|
s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4);
|
||||||
|
svga->force_dword_mode = val & 0x08;
|
||||||
break;
|
break;
|
||||||
case 0x32:
|
case 0x32:
|
||||||
svga->vram_display_mask = (val & 0x40) ? 0x3ffff : s3->vram_mask;
|
svga->vram_display_mask = (val & 0x40) ? 0x3ffff : s3->vram_mask;
|
||||||
|
|
@ -1662,15 +1663,35 @@ static void polygon_setup(s3_t *s3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define READ_SRC(addr, dat) if (s3->bpp == 0) dat = svga->vram[ (addr) & s3->vram_mask]; \
|
/*Remap address for chain-4/doubleword style layout*/
|
||||||
else if (s3->bpp == 1) dat = vram_w[(addr) & (s3->vram_mask >> 1)]; \
|
static inline uint32_t dword_remap(uint32_t in_addr)
|
||||||
else dat = vram_l[(addr) & (s3->vram_mask >> 2)]; \
|
{
|
||||||
|
return ((in_addr << 2) & 0x3fff0) |
|
||||||
|
((in_addr >> 14) & 0xc) |
|
||||||
|
(in_addr & ~0x3fffc);
|
||||||
|
}
|
||||||
|
static inline uint32_t dword_remap_w(uint32_t in_addr)
|
||||||
|
{
|
||||||
|
return ((in_addr << 2) & 0x1fff8) |
|
||||||
|
((in_addr >> 14) & 0x6) |
|
||||||
|
(in_addr & ~0x1fffe);
|
||||||
|
}
|
||||||
|
static inline uint32_t dword_remap_l(uint32_t in_addr)
|
||||||
|
{
|
||||||
|
return ((in_addr << 2) & 0xfffc) |
|
||||||
|
((in_addr >> 14) & 0x3) |
|
||||||
|
(in_addr & ~0xffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define READ_SRC(addr, dat) if (s3->bpp == 0) dat = svga->vram[ dword_remap(addr) & s3->vram_mask]; \
|
||||||
|
else if (s3->bpp == 1) dat = vram_w[dword_remap_w(addr) & (s3->vram_mask >> 1)]; \
|
||||||
|
else dat = vram_l[dword_remap_l(addr) & (s3->vram_mask >> 2)]; \
|
||||||
if (vram_mask) \
|
if (vram_mask) \
|
||||||
dat = ((dat & rd_mask) == rd_mask);
|
dat = ((dat & rd_mask) == rd_mask);
|
||||||
|
|
||||||
#define READ_DST(addr, dat) if (s3->bpp == 0) dat = svga->vram[ (addr) & s3->vram_mask]; \
|
#define READ_DST(addr, dat) if (s3->bpp == 0) dat = svga->vram[ dword_remap(addr) & s3->vram_mask]; \
|
||||||
else if (s3->bpp == 1) dat = vram_w[(addr) & (s3->vram_mask >> 1)]; \
|
else if (s3->bpp == 1) dat = vram_w[dword_remap_w(addr) & (s3->vram_mask >> 1)]; \
|
||||||
else dat = vram_l[(addr) & (s3->vram_mask >> 2)];
|
else dat = vram_l[dword_remap_l(addr) & (s3->vram_mask >> 2)];
|
||||||
|
|
||||||
#define MIX { \
|
#define MIX { \
|
||||||
uint32_t old_dest_dat = dest_dat; \
|
uint32_t old_dest_dat = dest_dat; \
|
||||||
|
|
@ -1699,18 +1720,18 @@ static void polygon_setup(s3_t *s3)
|
||||||
|
|
||||||
#define WRITE(addr) if (s3->bpp == 0) \
|
#define WRITE(addr) if (s3->bpp == 0) \
|
||||||
{ \
|
{ \
|
||||||
svga->vram[(addr) & s3->vram_mask] = dest_dat; \
|
svga->vram[dword_remap(addr) & s3->vram_mask] = dest_dat; \
|
||||||
svga->changedvram[((addr) & s3->vram_mask) >> 12] = changeframecount; \
|
svga->changedvram[(dword_remap(addr) & s3->vram_mask) >> 12] = changeframecount; \
|
||||||
} \
|
} \
|
||||||
else if (s3->bpp == 1) \
|
else if (s3->bpp == 1) \
|
||||||
{ \
|
{ \
|
||||||
vram_w[(addr) & (s3->vram_mask >> 1)] = dest_dat; \
|
vram_w[dword_remap_w(addr) & (s3->vram_mask >> 1)] = dest_dat; \
|
||||||
svga->changedvram[((addr) & (s3->vram_mask >> 1)) >> 11] = changeframecount; \
|
svga->changedvram[(dword_remap_w(addr) & (s3->vram_mask >> 1)) >> 11] = changeframecount; \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
vram_l[(addr) & (s3->vram_mask >> 2)] = dest_dat; \
|
vram_l[dword_remap_l(addr) & (s3->vram_mask >> 2)] = dest_dat; \
|
||||||
svga->changedvram[((addr) & (s3->vram_mask >> 2)) >> 10] = changeframecount; \
|
svga->changedvram[(dword_remap_l(addr) & (s3->vram_mask >> 2)) >> 10] = changeframecount; \
|
||||||
}
|
}
|
||||||
|
|
||||||
void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3)
|
void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3)
|
||||||
|
|
@ -2520,8 +2541,10 @@ void s3_hwcursor_draw(svga_t *svga, int displine)
|
||||||
// pclog("HWcursor %i %i\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y);
|
// pclog("HWcursor %i %i\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y);
|
||||||
for (x = 0; x < 64; x += 16)
|
for (x = 0; x < 64; x += 16)
|
||||||
{
|
{
|
||||||
dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 8) | svga->vram[svga->hwcursor_latch.addr + 1];
|
uint32_t remapped_addr = dword_remap(svga->hwcursor_latch.addr);
|
||||||
dat[1] = (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3];
|
|
||||||
|
dat[0] = (svga->vram[remapped_addr] << 8) | svga->vram[remapped_addr + 1];
|
||||||
|
dat[1] = (svga->vram[remapped_addr + 2] << 8) | svga->vram[remapped_addr + 3];
|
||||||
for (xx = 0; xx < 16; xx++)
|
for (xx = 0; xx < 16; xx++)
|
||||||
{
|
{
|
||||||
if (offset >= svga->hwcursor_latch.x)
|
if (offset >= svga->hwcursor_latch.x)
|
||||||
|
|
|
||||||
|
|
@ -3945,6 +3945,9 @@ static void *s3_virge_init()
|
||||||
|
|
||||||
ddc_init();
|
ddc_init();
|
||||||
|
|
||||||
|
//TODO ViRGE does not use packed chain4
|
||||||
|
virge->svga.packed_chain4 = 1;
|
||||||
|
|
||||||
return virge;
|
return virge;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4044,6 +4047,9 @@ static void *s3_virge_375_init()
|
||||||
|
|
||||||
ddc_init();
|
ddc_init();
|
||||||
|
|
||||||
|
//TODO ViRGE does not use packed chain4
|
||||||
|
virge->svga.packed_chain4 = 1;
|
||||||
|
|
||||||
return virge;
|
return virge;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,8 @@ void svga_out(uint16_t addr, uint8_t val, void *p)
|
||||||
case 4:
|
case 4:
|
||||||
svga->chain2_write = !(val & 4);
|
svga->chain2_write = !(val & 4);
|
||||||
svga->chain4 = val & 8;
|
svga->chain4 = val & 8;
|
||||||
svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4;
|
svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) &&
|
||||||
|
((svga->chain4 && svga->packed_chain4) || svga->fb_only);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -201,7 +202,8 @@ void svga_out(uint16_t addr, uint8_t val, void *p)
|
||||||
case 7: svga->colournocare=val; break;
|
case 7: svga->colournocare=val; break;
|
||||||
}
|
}
|
||||||
svga->gdcreg[svga->gdcaddr & 15] = val;
|
svga->gdcreg[svga->gdcaddr & 15] = val;
|
||||||
svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4;
|
svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) &&
|
||||||
|
((svga->chain4 && svga->packed_chain4) || svga->fb_only);
|
||||||
if (((svga->gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((svga->gdcaddr & 15) == 6 && (val ^ o) & 1))
|
if (((svga->gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((svga->gdcaddr & 15) == 6 && (val ^ o) & 1))
|
||||||
svga_recalctimings(svga);
|
svga_recalctimings(svga);
|
||||||
break;
|
break;
|
||||||
|
|
@ -444,6 +446,8 @@ void svga_recalctimings(svga_t *svga)
|
||||||
svga->dispontime = TIMER_USEC;
|
svga->dispontime = TIMER_USEC;
|
||||||
if (svga->dispofftime < TIMER_USEC)
|
if (svga->dispofftime < TIMER_USEC)
|
||||||
svga->dispofftime = TIMER_USEC;
|
svga->dispofftime = TIMER_USEC;
|
||||||
|
|
||||||
|
svga_recalc_remap_func(svga);
|
||||||
/* printf("SVGA horiz total %i display end %i vidclock %f\n",svga->crtc[0],svga->crtc[1],svga->clock);
|
/* printf("SVGA horiz total %i display end %i vidclock %f\n",svga->crtc[0],svga->crtc[1],svga->clock);
|
||||||
printf("SVGA vert total %i display end %i max row %i vsync %i\n",svga->vtotal,svga->dispend,(svga->crtc[9]&31)+1,svga->vsyncstart);
|
printf("SVGA vert total %i display end %i max row %i vsync %i\n",svga->vtotal,svga->dispend,(svga->crtc[9]&31)+1,svga->vsyncstart);
|
||||||
printf("total %f on %i cycles off %i cycles frame %i sec %i %02X\n",disptime*crtcconst,svga->dispontime,svga->dispofftime,(svga->dispontime+svga->dispofftime)*svga->vtotal,(svga->dispontime+svga->dispofftime)*svga->vtotal*70,svga->seqregs[1]);
|
printf("total %f on %i cycles off %i cycles frame %i sec %i %02X\n",disptime*crtcconst,svga->dispontime,svga->dispofftime,(svga->dispontime+svga->dispofftime)*svga->vtotal,(svga->dispontime+svga->dispofftime)*svga->vtotal*70,svga->seqregs[1]);
|
||||||
|
|
@ -816,11 +820,17 @@ void svga_write(uint32_t addr, uint8_t val, void *p)
|
||||||
addr += svga->write_bank;
|
addr += svga->write_bank;
|
||||||
|
|
||||||
if (!(svga->gdcreg[6] & 1)) svga->fullchange=2;
|
if (!(svga->gdcreg[6] & 1)) svga->fullchange=2;
|
||||||
if (svga->chain4 || svga->fb_only)
|
if ((svga->chain4 && svga->packed_chain4) || svga->fb_only)
|
||||||
{
|
{
|
||||||
writemask2=1<<(addr&3);
|
writemask2=1<<(addr&3);
|
||||||
addr&=~3;
|
addr&=~3;
|
||||||
}
|
}
|
||||||
|
else if (svga->chain4)
|
||||||
|
{
|
||||||
|
writemask2 = 1 << (addr & 3);
|
||||||
|
addr &= ~3;
|
||||||
|
addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
|
||||||
|
}
|
||||||
else if (svga->chain2_write)
|
else if (svga->chain2_write)
|
||||||
{
|
{
|
||||||
writemask2 &= ~0xa;
|
writemask2 &= ~0xa;
|
||||||
|
|
@ -1007,7 +1017,7 @@ uint8_t svga_read(uint32_t addr, void *p)
|
||||||
|
|
||||||
// pclog("%05X %i %04X:%04X %02X %02X %i\n",addr,svga->chain4,CS,pc, vram[addr & 0x7fffff], vram[(addr << 2) & 0x7fffff], svga->readmode);
|
// pclog("%05X %i %04X:%04X %02X %02X %i\n",addr,svga->chain4,CS,pc, vram[addr & 0x7fffff], vram[(addr << 2) & 0x7fffff], svga->readmode);
|
||||||
// pclog("%i\n", svga->readmode);
|
// pclog("%i\n", svga->readmode);
|
||||||
if (svga->chain4 || svga->fb_only)
|
if ((svga->chain4 && svga->packed_chain4) || svga->fb_only)
|
||||||
{
|
{
|
||||||
addr &= svga->decode_mask;
|
addr &= svga->decode_mask;
|
||||||
if (addr >= svga->vram_max)
|
if (addr >= svga->vram_max)
|
||||||
|
|
@ -1019,6 +1029,11 @@ uint8_t svga_read(uint32_t addr, void *p)
|
||||||
svga->ld = svga->vram[latch_addr | 0x3];
|
svga->ld = svga->vram[latch_addr | 0x3];
|
||||||
return svga->vram[addr & svga->vram_mask];
|
return svga->vram[addr & svga->vram_mask];
|
||||||
}
|
}
|
||||||
|
else if (svga->chain4)
|
||||||
|
{
|
||||||
|
readplane = addr & 3;
|
||||||
|
addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
|
||||||
|
}
|
||||||
else if (svga->chain2_read)
|
else if (svga->chain2_read)
|
||||||
{
|
{
|
||||||
readplane = (readplane & 2) | (addr & 1);
|
readplane = (readplane & 2) | (addr & 1);
|
||||||
|
|
@ -1082,11 +1097,16 @@ void svga_write_linear(uint32_t addr, uint8_t val, void *p)
|
||||||
if (svga_output) pclog("Write LFB %08X %02X ", addr, val);
|
if (svga_output) pclog("Write LFB %08X %02X ", addr, val);
|
||||||
if (!(svga->gdcreg[6] & 1))
|
if (!(svga->gdcreg[6] & 1))
|
||||||
svga->fullchange = 2;
|
svga->fullchange = 2;
|
||||||
if (svga->chain4 || svga->fb_only)
|
if ((svga->chain4 && svga->packed_chain4) || svga->fb_only)
|
||||||
{
|
{
|
||||||
writemask2=1<<(addr&3);
|
writemask2=1<<(addr&3);
|
||||||
addr&=~3;
|
addr&=~3;
|
||||||
}
|
}
|
||||||
|
else if (svga->chain4)
|
||||||
|
{
|
||||||
|
writemask2 = 1 << (addr & 3);
|
||||||
|
addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
|
||||||
|
}
|
||||||
else if (svga->chain2_write)
|
else if (svga->chain2_write)
|
||||||
{
|
{
|
||||||
writemask2 &= ~0xa;
|
writemask2 &= ~0xa;
|
||||||
|
|
@ -1262,13 +1282,18 @@ uint8_t svga_read_linear(uint32_t addr, void *p)
|
||||||
|
|
||||||
egareads++;
|
egareads++;
|
||||||
|
|
||||||
if (svga->chain4 || svga->fb_only)
|
if ((svga->chain4 && svga->packed_chain4) || svga->fb_only)
|
||||||
{
|
{
|
||||||
addr &= svga->decode_mask;
|
addr &= svga->decode_mask;
|
||||||
if (addr >= svga->vram_max)
|
if (addr >= svga->vram_max)
|
||||||
return 0xff;
|
return 0xff;
|
||||||
return svga->vram[addr & svga->vram_mask];
|
return svga->vram[addr & svga->vram_mask];
|
||||||
}
|
}
|
||||||
|
else if (svga->chain4)
|
||||||
|
{
|
||||||
|
readplane = addr & 3;
|
||||||
|
addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
|
||||||
|
}
|
||||||
else if (svga->chain2_read)
|
else if (svga->chain2_read)
|
||||||
{
|
{
|
||||||
readplane = (readplane & 2) | (addr & 1);
|
readplane = (readplane & 2) | (addr & 1);
|
||||||
|
|
@ -1276,7 +1301,9 @@ uint8_t svga_read_linear(uint32_t addr, void *p)
|
||||||
addr <<= 2;
|
addr <<= 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
addr<<=2;
|
addr<<=2;
|
||||||
|
}
|
||||||
|
|
||||||
addr &= svga->decode_mask;
|
addr &= svga->decode_mask;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,16 @@ typedef struct svga_t
|
||||||
|
|
||||||
/*Used to implement CRTC[0x17] bit 2 hsync divisor*/
|
/*Used to implement CRTC[0x17] bit 2 hsync divisor*/
|
||||||
int hsync_divisor;
|
int hsync_divisor;
|
||||||
|
|
||||||
|
/*Tseng-style chain4 mode - CRTC dword mode is the same as byte mode, chain4
|
||||||
|
addresses are shifted to match*/
|
||||||
|
int packed_chain4;
|
||||||
|
|
||||||
|
/*Force CRTC to dword mode, regardless of CR14/CR17. Required for S3 enhanced mode*/
|
||||||
|
int force_dword_mode;
|
||||||
|
|
||||||
|
int remap_required;
|
||||||
|
uint32_t (*remap_func)(struct svga_t *svga, uint32_t in_addr);
|
||||||
} svga_t;
|
} svga_t;
|
||||||
|
|
||||||
extern int svga_init(svga_t *svga, void *p, int memsize,
|
extern int svga_init(svga_t *svga, void *p, int memsize,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "vid_svga.h"
|
#include "vid_svga.h"
|
||||||
#include "vid_svga_render.h"
|
#include "vid_svga_render.h"
|
||||||
|
#include "vid_svga_render_remap.h"
|
||||||
|
|
||||||
void svga_render_null(svga_t *svga)
|
void svga_render_null(svga_t *svga)
|
||||||
{
|
{
|
||||||
|
|
@ -58,9 +59,12 @@ void svga_render_text_40(svga_t *svga)
|
||||||
|
|
||||||
for (x = 0; x < svga->hdisp; x += xinc)
|
for (x = 0; x < svga->hdisp; x += xinc)
|
||||||
{
|
{
|
||||||
|
uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask;
|
||||||
|
|
||||||
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
|
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
|
||||||
chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask];
|
chr = svga->vram[addr];
|
||||||
attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask];
|
attr = svga->vram[addr+1];
|
||||||
|
|
||||||
if (attr & 8) charaddr = svga->charsetb + (chr * 128);
|
if (attr & 8) charaddr = svga->charsetb + (chr * 128);
|
||||||
else charaddr = svga->charseta + (chr * 128);
|
else charaddr = svga->charseta + (chr * 128);
|
||||||
|
|
||||||
|
|
@ -122,9 +126,12 @@ void svga_render_text_80(svga_t *svga)
|
||||||
|
|
||||||
for (x = 0; x < svga->hdisp; x += xinc)
|
for (x = 0; x < svga->hdisp; x += xinc)
|
||||||
{
|
{
|
||||||
|
uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask;
|
||||||
|
|
||||||
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
|
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
|
||||||
chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask];
|
chr = svga->vram[addr];
|
||||||
attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask];
|
attr = svga->vram[addr+1];
|
||||||
|
|
||||||
if (attr & 8) charaddr = svga->charsetb + (chr * 128);
|
if (attr & 8) charaddr = svga->charsetb + (chr * 128);
|
||||||
else charaddr = svga->charseta + (chr * 128);
|
else charaddr = svga->charseta + (chr * 128);
|
||||||
|
|
||||||
|
|
@ -186,10 +193,12 @@ void svga_render_text_80_ksc5601(svga_t *svga)
|
||||||
|
|
||||||
for (x = 0; x < svga->hdisp; x += xinc)
|
for (x = 0; x < svga->hdisp; x += xinc)
|
||||||
{
|
{
|
||||||
|
uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask;
|
||||||
|
|
||||||
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
|
drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron);
|
||||||
chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask];
|
chr = svga->vram[addr];
|
||||||
nextchr = svga->vram[((svga->ma + 4) << 1) & svga->vram_display_mask];
|
nextchr = svga->vram[addr + 8];
|
||||||
attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask];
|
attr = svga->vram[addr + 1];
|
||||||
|
|
||||||
if (drawcursor)
|
if (drawcursor)
|
||||||
{
|
{
|
||||||
|
|
@ -304,11 +313,9 @@ void svga_render_text_80_ksc5601(svga_t *svga)
|
||||||
|
|
||||||
void svga_render_2bpp_lowres(svga_t *svga)
|
void svga_render_2bpp_lowres(svga_t *svga)
|
||||||
{
|
{
|
||||||
int changed_offset;
|
uint32_t changed_addr = svga->remap_func(svga, svga->ma);
|
||||||
|
|
||||||
changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12;
|
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
|
||||||
|
|
||||||
if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange)
|
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
int offset = ((8 - svga->scrollcache) << 1) + 16;
|
int offset = ((8 - svga->scrollcache) << 1) + 16;
|
||||||
|
|
@ -320,10 +327,11 @@ void svga_render_2bpp_lowres(svga_t *svga)
|
||||||
|
|
||||||
for (x = 0; x <= svga->hdisp; x += 16)
|
for (x = 0; x <= svga->hdisp; x += 16)
|
||||||
{
|
{
|
||||||
|
uint32_t addr = svga->remap_func(svga, svga->ma);
|
||||||
uint8_t dat[2];
|
uint8_t dat[2];
|
||||||
|
|
||||||
dat[0] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000];
|
dat[0] = svga->vram[addr];
|
||||||
dat[1] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000 + 1];
|
dat[1] = svga->vram[addr + 1];
|
||||||
svga->ma += 4;
|
svga->ma += 4;
|
||||||
svga->ma &= svga->vram_display_mask;
|
svga->ma &= svga->vram_display_mask;
|
||||||
|
|
||||||
|
|
@ -343,11 +351,9 @@ void svga_render_2bpp_lowres(svga_t *svga)
|
||||||
|
|
||||||
void svga_render_2bpp_highres(svga_t *svga)
|
void svga_render_2bpp_highres(svga_t *svga)
|
||||||
{
|
{
|
||||||
int changed_offset;
|
uint32_t changed_addr = svga->remap_func(svga, svga->ma);
|
||||||
|
|
||||||
changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12;
|
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
|
||||||
|
|
||||||
if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange)
|
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
int offset = (8 - svga->scrollcache) + 24;
|
int offset = (8 - svga->scrollcache) + 24;
|
||||||
|
|
@ -359,30 +365,31 @@ void svga_render_2bpp_highres(svga_t *svga)
|
||||||
|
|
||||||
for (x = 0; x <= svga->hdisp; x += 8)
|
for (x = 0; x <= svga->hdisp; x += 8)
|
||||||
{
|
{
|
||||||
|
uint32_t addr = svga->remap_func(svga, svga->ma);
|
||||||
uint8_t dat[2];
|
uint8_t dat[2];
|
||||||
|
|
||||||
dat[0] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000];
|
dat[0] = svga->vram[addr];
|
||||||
dat[1] = svga->vram[(svga->ma << 1) + ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000 + 1];
|
dat[1] = svga->vram[addr + 1];
|
||||||
svga->ma += 4;
|
svga->ma += 4;
|
||||||
svga->ma &= svga->vram_display_mask;
|
svga->ma &= svga->vram_display_mask;
|
||||||
|
|
||||||
p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
|
*p++ = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]];
|
||||||
p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
|
*p++ = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]];
|
||||||
p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]];
|
*p++ = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]];
|
||||||
p[3] = svga->pallook[svga->egapal[dat[0] & 3]];
|
*p++ = svga->pallook[svga->egapal[dat[0] & 3]];
|
||||||
p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]];
|
*p++ = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]];
|
||||||
p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]];
|
*p++ = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]];
|
||||||
p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]];
|
*p++ = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]];
|
||||||
p[7] = svga->pallook[svga->egapal[dat[1] & 3]];
|
*p++ = svga->pallook[svga->egapal[dat[1] & 3]];
|
||||||
|
|
||||||
p += 8;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void svga_render_4bpp_lowres(svga_t *svga)
|
void svga_render_4bpp_lowres(svga_t *svga)
|
||||||
{
|
{
|
||||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
|
uint32_t changed_addr = svga->remap_func(svga, svga->ma);
|
||||||
|
|
||||||
|
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
int offset = ((8 - svga->scrollcache) << 1) + 16;
|
int offset = ((8 - svga->scrollcache) << 1) + 16;
|
||||||
|
|
@ -396,8 +403,9 @@ void svga_render_4bpp_lowres(svga_t *svga)
|
||||||
{
|
{
|
||||||
uint8_t edat[4];
|
uint8_t edat[4];
|
||||||
uint8_t dat;
|
uint8_t dat;
|
||||||
|
uint32_t addr = svga->remap_func(svga, svga->ma);
|
||||||
|
|
||||||
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma]);
|
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]);
|
||||||
svga->ma += 4;
|
svga->ma += 4;
|
||||||
svga->ma &= svga->vram_display_mask;
|
svga->ma &= svga->vram_display_mask;
|
||||||
|
|
||||||
|
|
@ -421,11 +429,9 @@ void svga_render_4bpp_lowres(svga_t *svga)
|
||||||
|
|
||||||
void svga_render_4bpp_highres(svga_t *svga)
|
void svga_render_4bpp_highres(svga_t *svga)
|
||||||
{
|
{
|
||||||
int changed_offset;
|
uint32_t changed_addr = svga->remap_func(svga, svga->ma);
|
||||||
|
|
||||||
changed_offset = (svga->ma + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12;
|
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
|
||||||
|
|
||||||
if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange)
|
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
int offset = (8 - svga->scrollcache) + 24;
|
int offset = (8 - svga->scrollcache) + 24;
|
||||||
|
|
@ -439,32 +445,33 @@ void svga_render_4bpp_highres(svga_t *svga)
|
||||||
{
|
{
|
||||||
uint8_t edat[4];
|
uint8_t edat[4];
|
||||||
uint8_t dat;
|
uint8_t dat;
|
||||||
|
uint32_t addr = svga->remap_func(svga, svga->ma);
|
||||||
|
|
||||||
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma | ((svga->sc & ~svga->crtc[0x17] & 3)) * 0x8000]);
|
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]);
|
||||||
svga->ma += 4;
|
svga->ma += 4;
|
||||||
svga->ma &= svga->vram_display_mask;
|
svga->ma &= svga->vram_display_mask;
|
||||||
|
|
||||||
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
|
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
|
||||||
p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
|
*p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
|
||||||
p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
|
*p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]];
|
||||||
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
|
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
|
||||||
p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
|
*p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
|
||||||
p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
|
*p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]];
|
||||||
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
|
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
|
||||||
p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
|
*p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
|
||||||
p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
|
*p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]];
|
||||||
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
|
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
|
||||||
p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
|
*p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
|
||||||
p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
|
*p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]];
|
||||||
|
|
||||||
p += 8;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void svga_render_8bpp_lowres(svga_t *svga)
|
void svga_render_8bpp_lowres(svga_t *svga)
|
||||||
{
|
{
|
||||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
|
uint32_t changed_addr = svga->remap_func(svga, svga->ma);
|
||||||
|
|
||||||
|
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
int offset = (8 - (svga->scrollcache & 6)) + 24;
|
int offset = (8 - (svga->scrollcache & 6)) + 24;
|
||||||
|
|
@ -474,6 +481,8 @@ void svga_render_8bpp_lowres(svga_t *svga)
|
||||||
svga->firstline_draw = svga->displine;
|
svga->firstline_draw = svga->displine;
|
||||||
svga->lastline_draw = svga->displine;
|
svga->lastline_draw = svga->displine;
|
||||||
|
|
||||||
|
if (!svga->remap_required)
|
||||||
|
{
|
||||||
for (x = 0; x <= svga->hdisp; x += 8)
|
for (x = 0; x <= svga->hdisp; x += 8)
|
||||||
{
|
{
|
||||||
uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
|
uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
|
||||||
|
|
@ -486,13 +495,32 @@ void svga_render_8bpp_lowres(svga_t *svga)
|
||||||
svga->ma += 4;
|
svga->ma += 4;
|
||||||
p += 8;
|
p += 8;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (x = 0; x <= svga->hdisp; x += 8)
|
||||||
|
{
|
||||||
|
uint32_t addr = svga->remap_func(svga, svga->ma);
|
||||||
|
uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
|
||||||
|
|
||||||
|
p[0] = p[1] = svga->pallook[dat & 0xff];
|
||||||
|
p[2] = p[3] = svga->pallook[(dat >> 8) & 0xff];
|
||||||
|
p[4] = p[5] = svga->pallook[(dat >> 16) & 0xff];
|
||||||
|
p[6] = p[7] = svga->pallook[(dat >> 24) & 0xff];
|
||||||
|
|
||||||
|
svga->ma += 4;
|
||||||
|
p += 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
svga->ma &= svga->vram_display_mask;
|
svga->ma &= svga->vram_display_mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void svga_render_8bpp_highres(svga_t *svga)
|
void svga_render_8bpp_highres(svga_t *svga)
|
||||||
{
|
{
|
||||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
|
uint32_t changed_addr = svga->remap_func(svga, svga->ma);
|
||||||
|
|
||||||
|
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
||||||
|
|
@ -502,31 +530,50 @@ void svga_render_8bpp_highres(svga_t *svga)
|
||||||
svga->firstline_draw = svga->displine;
|
svga->firstline_draw = svga->displine;
|
||||||
svga->lastline_draw = svga->displine;
|
svga->lastline_draw = svga->displine;
|
||||||
|
|
||||||
|
if (!svga->remap_required)
|
||||||
|
{
|
||||||
for (x = 0; x <= svga->hdisp; x += 8)
|
for (x = 0; x <= svga->hdisp; x += 8)
|
||||||
{
|
{
|
||||||
uint32_t dat;
|
uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
|
||||||
dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
|
*p++ = svga->pallook[dat & 0xff];
|
||||||
p[0] = svga->pallook[dat & 0xff];
|
*p++ = svga->pallook[(dat >> 8) & 0xff];
|
||||||
p[1] = svga->pallook[(dat >> 8) & 0xff];
|
*p++ = svga->pallook[(dat >> 16) & 0xff];
|
||||||
p[2] = svga->pallook[(dat >> 16) & 0xff];
|
*p++ = svga->pallook[(dat >> 24) & 0xff];
|
||||||
p[3] = svga->pallook[(dat >> 24) & 0xff];
|
|
||||||
|
|
||||||
dat = *(uint32_t *)(&svga->vram[(svga->ma+4) & svga->vram_display_mask]);
|
dat = *(uint32_t *)(&svga->vram[(svga->ma+4) & svga->vram_display_mask]);
|
||||||
p[4] = svga->pallook[dat & 0xff];
|
*p++ = svga->pallook[dat & 0xff];
|
||||||
p[5] = svga->pallook[(dat >> 8) & 0xff];
|
*p++ = svga->pallook[(dat >> 8) & 0xff];
|
||||||
p[6] = svga->pallook[(dat >> 16) & 0xff];
|
*p++ = svga->pallook[(dat >> 16) & 0xff];
|
||||||
p[7] = svga->pallook[(dat >> 24) & 0xff];
|
*p++ = svga->pallook[(dat >> 24) & 0xff];
|
||||||
|
|
||||||
svga->ma += 8;
|
svga->ma += 8;
|
||||||
p += 8;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (x = 0; x <= svga->hdisp; x += 4)
|
||||||
|
{
|
||||||
|
uint32_t addr = svga->remap_func(svga, svga->ma);
|
||||||
|
uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
|
||||||
|
|
||||||
|
svga->ma += 4;
|
||||||
|
|
||||||
|
*p++ = svga->pallook[dat & 0xff];
|
||||||
|
*p++ = svga->pallook[(dat >> 8) & 0xff];
|
||||||
|
*p++ = svga->pallook[(dat >> 16) & 0xff];
|
||||||
|
*p++ = svga->pallook[(dat >> 24) & 0xff];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
svga->ma &= svga->vram_display_mask;
|
svga->ma &= svga->vram_display_mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void svga_render_15bpp_lowres(svga_t *svga)
|
void svga_render_15bpp_lowres(svga_t *svga)
|
||||||
{
|
{
|
||||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
|
uint32_t changed_addr = svga->remap_func(svga, svga->ma);
|
||||||
|
|
||||||
|
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
int offset = (8 - (svga->scrollcache & 6)) + 24;
|
int offset = (8 - (svga->scrollcache & 6)) + 24;
|
||||||
|
|
@ -536,26 +583,44 @@ void svga_render_15bpp_lowres(svga_t *svga)
|
||||||
svga->firstline_draw = svga->displine;
|
svga->firstline_draw = svga->displine;
|
||||||
svga->lastline_draw = svga->displine;
|
svga->lastline_draw = svga->displine;
|
||||||
|
|
||||||
|
if (!svga->remap_required)
|
||||||
|
{
|
||||||
for (x = 0; x <= svga->hdisp; x += 4)
|
for (x = 0; x <= svga->hdisp; x += 4)
|
||||||
{
|
{
|
||||||
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
|
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
|
||||||
|
|
||||||
p[x] = video_15to32[dat & 0xffff];
|
*p++ = video_15to32[dat & 0xffff];
|
||||||
p[x + 1] = video_15to32[dat >> 16];
|
*p++ = video_15to32[dat >> 16];
|
||||||
|
|
||||||
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
|
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
|
||||||
|
|
||||||
p[x] = video_15to32[dat & 0xffff];
|
*p++ = video_15to32[dat & 0xffff];
|
||||||
p[x + 1] = video_15to32[dat >> 16];
|
*p++ = video_15to32[dat >> 16];
|
||||||
}
|
}
|
||||||
svga->ma += x << 1;
|
svga->ma += x << 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (x = 0; x <= svga->hdisp; x += 2)
|
||||||
|
{
|
||||||
|
uint32_t addr = svga->remap_func(svga, svga->ma);
|
||||||
|
uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
|
||||||
|
|
||||||
|
*p++ = video_15to32[dat & 0xffff];
|
||||||
|
*p++ = video_15to32[dat >> 16];
|
||||||
|
|
||||||
|
svga->ma += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
svga->ma &= svga->vram_display_mask;
|
svga->ma &= svga->vram_display_mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void svga_render_15bpp_highres(svga_t *svga)
|
void svga_render_15bpp_highres(svga_t *svga)
|
||||||
{
|
{
|
||||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
|
uint32_t changed_addr = svga->remap_func(svga, svga->ma);
|
||||||
|
|
||||||
|
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
||||||
|
|
@ -565,32 +630,51 @@ void svga_render_15bpp_highres(svga_t *svga)
|
||||||
svga->firstline_draw = svga->displine;
|
svga->firstline_draw = svga->displine;
|
||||||
svga->lastline_draw = svga->displine;
|
svga->lastline_draw = svga->displine;
|
||||||
|
|
||||||
|
if (!svga->remap_required)
|
||||||
|
{
|
||||||
for (x = 0; x <= svga->hdisp; x += 8)
|
for (x = 0; x <= svga->hdisp; x += 8)
|
||||||
{
|
{
|
||||||
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
|
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
|
||||||
p[x] = video_15to32[dat & 0xffff];
|
*p++ = video_15to32[dat & 0xffff];
|
||||||
p[x + 1] = video_15to32[dat >> 16];
|
*p++ = video_15to32[dat >> 16];
|
||||||
|
|
||||||
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
|
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
|
||||||
p[x + 2] = video_15to32[dat & 0xffff];
|
*p++ = video_15to32[dat & 0xffff];
|
||||||
p[x + 3] = video_15to32[dat >> 16];
|
*p++ = video_15to32[dat >> 16];
|
||||||
|
|
||||||
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]);
|
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]);
|
||||||
p[x + 4] = video_15to32[dat & 0xffff];
|
*p++ = video_15to32[dat & 0xffff];
|
||||||
p[x + 5] = video_15to32[dat >> 16];
|
*p++ = video_15to32[dat >> 16];
|
||||||
|
|
||||||
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]);
|
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]);
|
||||||
p[x + 6] = video_15to32[dat & 0xffff];
|
*p++ = video_15to32[dat & 0xffff];
|
||||||
p[x + 7] = video_15to32[dat >> 16];
|
*p++ = video_15to32[dat >> 16];
|
||||||
}
|
}
|
||||||
|
|
||||||
svga->ma += x << 1;
|
svga->ma += x << 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (x = 0; x <= svga->hdisp; x += 2)
|
||||||
|
{
|
||||||
|
uint32_t addr = svga->remap_func(svga, svga->ma);
|
||||||
|
uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
|
||||||
|
|
||||||
|
*p++ = video_15to32[dat & 0xffff];
|
||||||
|
*p++ = video_15to32[dat >> 16];
|
||||||
|
|
||||||
|
svga->ma += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
svga->ma &= svga->vram_display_mask;
|
svga->ma &= svga->vram_display_mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void svga_render_16bpp_lowres(svga_t *svga)
|
void svga_render_16bpp_lowres(svga_t *svga)
|
||||||
{
|
{
|
||||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
|
uint32_t changed_addr = svga->remap_func(svga, svga->ma);
|
||||||
|
|
||||||
|
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
int offset = (8 - (svga->scrollcache & 6)) + 24;
|
int offset = (8 - (svga->scrollcache & 6)) + 24;
|
||||||
|
|
@ -600,17 +684,34 @@ void svga_render_16bpp_lowres(svga_t *svga)
|
||||||
svga->firstline_draw = svga->displine;
|
svga->firstline_draw = svga->displine;
|
||||||
svga->lastline_draw = svga->displine;
|
svga->lastline_draw = svga->displine;
|
||||||
|
|
||||||
|
if (!svga->remap_required)
|
||||||
|
{
|
||||||
for (x = 0; x <= svga->hdisp; x += 4)
|
for (x = 0; x <= svga->hdisp; x += 4)
|
||||||
{
|
{
|
||||||
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
|
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
|
||||||
|
|
||||||
p[x] = video_16to32[dat & 0xffff];
|
*p++ = video_16to32[dat & 0xffff];
|
||||||
p[x + 1] = video_16to32[dat >> 16];
|
*p++ = video_16to32[dat >> 16];
|
||||||
|
|
||||||
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
|
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
|
||||||
|
|
||||||
p[x] = video_16to32[dat & 0xffff];
|
*p++ = video_16to32[dat & 0xffff];
|
||||||
p[x + 1] = video_16to32[dat >> 16];
|
*p++ = video_16to32[dat >> 16];
|
||||||
|
}
|
||||||
|
svga->ma += x << 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (x = 0; x <= svga->hdisp; x += 2)
|
||||||
|
{
|
||||||
|
uint32_t addr = svga->remap_func(svga, svga->ma);
|
||||||
|
uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
|
||||||
|
|
||||||
|
*p++ = video_16to32[dat & 0xffff];
|
||||||
|
*p++ = video_16to32[dat >> 16];
|
||||||
|
|
||||||
|
svga->ma += 4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
svga->ma += x << 1;
|
svga->ma += x << 1;
|
||||||
svga->ma &= svga->vram_display_mask;
|
svga->ma &= svga->vram_display_mask;
|
||||||
|
|
@ -619,7 +720,9 @@ void svga_render_16bpp_lowres(svga_t *svga)
|
||||||
|
|
||||||
void svga_render_16bpp_highres(svga_t *svga)
|
void svga_render_16bpp_highres(svga_t *svga)
|
||||||
{
|
{
|
||||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
|
uint32_t changed_addr = svga->remap_func(svga, svga->ma);
|
||||||
|
|
||||||
|
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
||||||
|
|
@ -629,55 +732,106 @@ void svga_render_16bpp_highres(svga_t *svga)
|
||||||
svga->firstline_draw = svga->displine;
|
svga->firstline_draw = svga->displine;
|
||||||
svga->lastline_draw = svga->displine;
|
svga->lastline_draw = svga->displine;
|
||||||
|
|
||||||
|
if (!svga->remap_required)
|
||||||
|
{
|
||||||
for (x = 0; x <= svga->hdisp; x += 8)
|
for (x = 0; x <= svga->hdisp; x += 8)
|
||||||
{
|
{
|
||||||
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
|
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]);
|
||||||
p[x] = video_16to32[dat & 0xffff];
|
*p++ = video_16to32[dat & 0xffff];
|
||||||
p[x + 1] = video_16to32[dat >> 16];
|
*p++ = video_16to32[dat >> 16];
|
||||||
|
|
||||||
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
|
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]);
|
||||||
p[x + 2] = video_16to32[dat & 0xffff];
|
*p++ = video_16to32[dat & 0xffff];
|
||||||
p[x + 3] = video_16to32[dat >> 16];
|
*p++ = video_16to32[dat >> 16];
|
||||||
|
|
||||||
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]);
|
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]);
|
||||||
p[x + 4] = video_16to32[dat & 0xffff];
|
*p++ = video_16to32[dat & 0xffff];
|
||||||
p[x + 5] = video_16to32[dat >> 16];
|
*p++ = video_16to32[dat >> 16];
|
||||||
|
|
||||||
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]);
|
dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]);
|
||||||
p[x + 6] = video_16to32[dat & 0xffff];
|
*p++ = video_16to32[dat & 0xffff];
|
||||||
p[x + 7] = video_16to32[dat >> 16];
|
*p++ = video_16to32[dat >> 16];
|
||||||
}
|
}
|
||||||
|
|
||||||
svga->ma += x << 1;
|
svga->ma += x << 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (x = 0; x <= svga->hdisp; x += 2)
|
||||||
|
{
|
||||||
|
uint32_t addr = svga->remap_func(svga, svga->ma);
|
||||||
|
uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
|
||||||
|
|
||||||
|
*p++ = video_16to32[dat & 0xffff];
|
||||||
|
*p++ = video_16to32[dat >> 16];
|
||||||
|
|
||||||
|
svga->ma += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
svga->ma &= svga->vram_display_mask;
|
svga->ma &= svga->vram_display_mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void svga_render_24bpp_lowres(svga_t *svga)
|
void svga_render_24bpp_lowres(svga_t *svga)
|
||||||
{
|
{
|
||||||
int x, offset;
|
uint32_t changed_addr = svga->remap_func(svga, svga->ma);
|
||||||
uint32_t fg;
|
|
||||||
|
|
||||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
|
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
|
||||||
{
|
{
|
||||||
|
int x;
|
||||||
|
int offset = (8 - (svga->scrollcache & 6)) + 24;
|
||||||
|
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
|
||||||
|
|
||||||
if (svga->firstline_draw == 2000)
|
if (svga->firstline_draw == 2000)
|
||||||
svga->firstline_draw = svga->displine;
|
svga->firstline_draw = svga->displine;
|
||||||
svga->lastline_draw = svga->displine;
|
svga->lastline_draw = svga->displine;
|
||||||
|
|
||||||
offset = (8 - (svga->scrollcache & 6)) + 24;
|
if (!svga->remap_required)
|
||||||
|
{
|
||||||
for (x = 0; x <= svga->hdisp; x++)
|
for (x = 0; x <= svga->hdisp; x++)
|
||||||
{
|
{
|
||||||
fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
|
uint32_t dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
|
||||||
svga->ma += 3;
|
uint32_t dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
|
||||||
svga->ma &= svga->vram_display_mask;
|
uint32_t dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]);
|
||||||
((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg;
|
|
||||||
|
p[0] = p[1] = dat0 & 0xffffff;
|
||||||
|
p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8);
|
||||||
|
p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16);
|
||||||
|
p[6] = p[7] = dat2 >> 8;
|
||||||
|
|
||||||
|
svga->ma += 12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (x = 0; x <= svga->hdisp; x += 4)
|
||||||
|
{
|
||||||
|
uint32_t dat0, dat1, dat2;
|
||||||
|
uint32_t addr;
|
||||||
|
|
||||||
|
addr = svga->remap_func(svga, svga->ma);
|
||||||
|
dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
|
||||||
|
addr = svga->remap_func(svga, svga->ma + 4);
|
||||||
|
dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
|
||||||
|
addr = svga->remap_func(svga, svga->ma + 8);
|
||||||
|
dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
|
||||||
|
|
||||||
|
p[0] = p[1] = dat0 & 0xffffff;
|
||||||
|
p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8);
|
||||||
|
p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16);
|
||||||
|
p[6] = p[7] = dat2 >> 8;
|
||||||
|
|
||||||
|
svga->ma += 12;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void svga_render_24bpp_highres(svga_t *svga)
|
void svga_render_24bpp_highres(svga_t *svga)
|
||||||
{
|
{
|
||||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
|
uint32_t changed_addr = svga->remap_func(svga, svga->ma);
|
||||||
|
|
||||||
|
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
||||||
|
|
@ -687,46 +841,84 @@ void svga_render_24bpp_highres(svga_t *svga)
|
||||||
svga->firstline_draw = svga->displine;
|
svga->firstline_draw = svga->displine;
|
||||||
svga->lastline_draw = svga->displine;
|
svga->lastline_draw = svga->displine;
|
||||||
|
|
||||||
|
if (!svga->remap_required)
|
||||||
|
{
|
||||||
for (x = 0; x <= svga->hdisp; x += 4)
|
for (x = 0; x <= svga->hdisp; x += 4)
|
||||||
{
|
{
|
||||||
uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
|
uint32_t dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]);
|
||||||
p[x] = dat & 0xffffff;
|
uint32_t dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
|
||||||
|
uint32_t dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]);
|
||||||
|
|
||||||
dat = *(uint32_t *)(&svga->vram[(svga->ma + 3) & svga->vram_display_mask]);
|
*p++ = dat0 & 0xffffff;
|
||||||
p[x + 1] = dat & 0xffffff;
|
*p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8);
|
||||||
|
*p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16);
|
||||||
dat = *(uint32_t *)(&svga->vram[(svga->ma + 6) & svga->vram_display_mask]);
|
*p++ = dat2 >> 8;
|
||||||
p[x + 2] = dat & 0xffffff;
|
|
||||||
|
|
||||||
dat = *(uint32_t *)(&svga->vram[(svga->ma + 9) & svga->vram_display_mask]);
|
|
||||||
p[x + 3] = dat & 0xffffff;
|
|
||||||
|
|
||||||
svga->ma += 12;
|
svga->ma += 12;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (x = 0; x <= svga->hdisp; x += 4)
|
||||||
|
{
|
||||||
|
uint32_t dat0, dat1, dat2;
|
||||||
|
uint32_t addr;
|
||||||
|
|
||||||
|
addr = svga->remap_func(svga, svga->ma);
|
||||||
|
dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
|
||||||
|
addr = svga->remap_func(svga, svga->ma + 4);
|
||||||
|
dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
|
||||||
|
addr = svga->remap_func(svga, svga->ma + 8);
|
||||||
|
dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
|
||||||
|
|
||||||
|
*p++ = dat0 & 0xffffff;
|
||||||
|
*p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8);
|
||||||
|
*p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16);
|
||||||
|
*p++ = dat2 >> 8;
|
||||||
|
|
||||||
|
svga->ma += 12;
|
||||||
|
}
|
||||||
|
}
|
||||||
svga->ma &= svga->vram_display_mask;
|
svga->ma &= svga->vram_display_mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void svga_render_32bpp_lowres(svga_t *svga)
|
void svga_render_32bpp_lowres(svga_t *svga)
|
||||||
{
|
{
|
||||||
int x, offset;
|
uint32_t changed_addr = svga->remap_func(svga, svga->ma);
|
||||||
uint32_t fg;
|
|
||||||
|
|
||||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange)
|
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
|
||||||
{
|
{
|
||||||
|
int x;
|
||||||
|
int offset = (8 - (svga->scrollcache & 6)) + 24;
|
||||||
|
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
|
||||||
|
|
||||||
if (svga->firstline_draw == 2000)
|
if (svga->firstline_draw == 2000)
|
||||||
svga->firstline_draw = svga->displine;
|
svga->firstline_draw = svga->displine;
|
||||||
svga->lastline_draw = svga->displine;
|
svga->lastline_draw = svga->displine;
|
||||||
|
|
||||||
offset = (8 - (svga->scrollcache & 6)) + 24;
|
if (!svga->remap_required)
|
||||||
|
{
|
||||||
for (x = 0; x <= svga->hdisp; x++)
|
for (x = 0; x <= svga->hdisp; x++)
|
||||||
{
|
{
|
||||||
fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
|
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
|
||||||
svga->ma += 4;
|
*p++ = dat & 0xffffff;
|
||||||
svga->ma &= svga->vram_display_mask;
|
*p++ = dat & 0xffffff;
|
||||||
((uint32_t *)buffer32->line[svga->displine])[(x << 1) + offset] = ((uint32_t *)buffer32->line[svga->displine])[(x << 1) + 1 + offset] = fg;
|
|
||||||
}
|
}
|
||||||
|
svga->ma += x*4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (x = 0; x <= svga->hdisp; x++)
|
||||||
|
{
|
||||||
|
uint32_t addr = svga->remap_func(svga, svga->ma);
|
||||||
|
uint32_t dat = *(uint32_t *)(&svga->vram[addr]);
|
||||||
|
*p++ = dat & 0xffffff;
|
||||||
|
*p++ = dat & 0xffffff;
|
||||||
|
svga->ma += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
svga->ma &= svga->vram_display_mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -734,7 +926,9 @@ void svga_render_32bpp_lowres(svga_t *svga)
|
||||||
91%*/
|
91%*/
|
||||||
void svga_render_32bpp_highres(svga_t *svga)
|
void svga_render_32bpp_highres(svga_t *svga)
|
||||||
{
|
{
|
||||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange)
|
uint32_t changed_addr = svga->remap_func(svga, svga->ma);
|
||||||
|
|
||||||
|
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
||||||
|
|
@ -744,19 +938,35 @@ void svga_render_32bpp_highres(svga_t *svga)
|
||||||
svga->firstline_draw = svga->displine;
|
svga->firstline_draw = svga->displine;
|
||||||
svga->lastline_draw = svga->displine;
|
svga->lastline_draw = svga->displine;
|
||||||
|
|
||||||
|
if (!svga->remap_required)
|
||||||
|
{
|
||||||
for (x = 0; x <= svga->hdisp; x++)
|
for (x = 0; x <= svga->hdisp; x++)
|
||||||
{
|
{
|
||||||
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
|
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
|
||||||
p[x] = dat & 0xffffff;
|
*p++ = dat & 0xffffff;
|
||||||
}
|
}
|
||||||
|
svga->ma += x*4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (x = 0; x <= svga->hdisp; x++)
|
||||||
|
{
|
||||||
|
uint32_t addr = svga->remap_func(svga, svga->ma);
|
||||||
|
uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
|
||||||
|
*p++ = dat & 0xffffff;
|
||||||
svga->ma += 4;
|
svga->ma += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
svga->ma &= svga->vram_display_mask;
|
svga->ma &= svga->vram_display_mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void svga_render_ABGR8888_highres(svga_t *svga)
|
void svga_render_ABGR8888_highres(svga_t *svga)
|
||||||
{
|
{
|
||||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange)
|
uint32_t changed_addr = svga->remap_func(svga, svga->ma);
|
||||||
|
|
||||||
|
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
||||||
|
|
@ -766,19 +976,35 @@ void svga_render_ABGR8888_highres(svga_t *svga)
|
||||||
svga->firstline_draw = svga->displine;
|
svga->firstline_draw = svga->displine;
|
||||||
svga->lastline_draw = svga->displine;
|
svga->lastline_draw = svga->displine;
|
||||||
|
|
||||||
|
if (!svga->remap_required)
|
||||||
|
{
|
||||||
for (x = 0; x <= svga->hdisp; x++)
|
for (x = 0; x <= svga->hdisp; x++)
|
||||||
{
|
{
|
||||||
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
|
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
|
||||||
p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
|
*p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
|
||||||
}
|
}
|
||||||
|
svga->ma += x*4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (x = 0; x <= svga->hdisp; x++)
|
||||||
|
{
|
||||||
|
uint32_t addr = svga->remap_func(svga, svga->ma);
|
||||||
|
uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
|
||||||
|
*p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
|
||||||
svga->ma += 4;
|
svga->ma += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
svga->ma &= svga->vram_display_mask;
|
svga->ma &= svga->vram_display_mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void svga_render_RGBA8888_highres(svga_t *svga)
|
void svga_render_RGBA8888_highres(svga_t *svga)
|
||||||
{
|
{
|
||||||
if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange)
|
uint32_t changed_addr = svga->remap_func(svga, svga->ma);
|
||||||
|
|
||||||
|
if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24;
|
||||||
|
|
@ -788,12 +1014,26 @@ void svga_render_RGBA8888_highres(svga_t *svga)
|
||||||
svga->firstline_draw = svga->displine;
|
svga->firstline_draw = svga->displine;
|
||||||
svga->lastline_draw = svga->displine;
|
svga->lastline_draw = svga->displine;
|
||||||
|
|
||||||
|
if (!svga->remap_required)
|
||||||
|
{
|
||||||
for (x = 0; x <= svga->hdisp; x++)
|
for (x = 0; x <= svga->hdisp; x++)
|
||||||
{
|
{
|
||||||
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
|
uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
|
||||||
p[x] = dat >> 8;
|
*p++ = dat >> 8;
|
||||||
}
|
}
|
||||||
|
svga->ma += x*4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (x = 0; x <= svga->hdisp; x++)
|
||||||
|
{
|
||||||
|
uint32_t addr = svga->remap_func(svga, svga->ma);
|
||||||
|
uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
|
||||||
|
*p++ = dat >> 8;
|
||||||
svga->ma += 4;
|
svga->ma += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
svga->ma &= svga->vram_display_mask;
|
svga->ma &= svga->vram_display_mask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ extern int scrollcache;
|
||||||
|
|
||||||
extern uint8_t edatlookup[4][4];
|
extern uint8_t edatlookup[4][4];
|
||||||
|
|
||||||
|
void svga_recalc_remap_func(svga_t *svga);
|
||||||
|
|
||||||
void svga_render_null(svga_t *svga);
|
void svga_render_null(svga_t *svga);
|
||||||
void svga_render_blank(svga_t *svga);
|
void svga_render_blank(svga_t *svga);
|
||||||
void svga_render_text_40(svga_t *svga);
|
void svga_render_text_40(svga_t *svga);
|
||||||
|
|
|
||||||
129
src/vid_svga_render_remap.h
Normal file
129
src/vid_svga_render_remap.h
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
/*Variables :
|
||||||
|
byte/word/doubleword mode
|
||||||
|
word has MA13/MA15->MA0
|
||||||
|
ET4000 treats doubleword as byte
|
||||||
|
row 0 -> MA13
|
||||||
|
row 1 -> MA14
|
||||||
|
*/
|
||||||
|
|
||||||
|
//S3 - enhanced mode mappings CR31.3 can force doubleword mode
|
||||||
|
//Cirrus Logic handles SVGA writes seperately
|
||||||
|
//S3, CL, TGUI blitters need checking
|
||||||
|
|
||||||
|
//CL, S3, Mach64, ET4000, Banshee, TGUI all okay
|
||||||
|
//Still to check - ViRGE, HT216
|
||||||
|
#define VAR_BYTE_MODE (0 << 0)
|
||||||
|
#define VAR_WORD_MODE_MA13 (1 << 0)
|
||||||
|
#define VAR_WORD_MODE_MA15 (2 << 0)
|
||||||
|
#define VAR_DWORD_MODE (3 << 0)
|
||||||
|
#define VAR_MODE_MASK (3 << 0)
|
||||||
|
#define VAR_ROW0_MA13 (1 << 2)
|
||||||
|
#define VAR_ROW1_MA14 (1 << 3)
|
||||||
|
|
||||||
|
#define ADDRESS_REMAP_FUNC(nr) \
|
||||||
|
static uint32_t address_remap_func_ ## nr(svga_t *svga, uint32_t in_addr) \
|
||||||
|
{ \
|
||||||
|
uint32_t out_addr; \
|
||||||
|
\
|
||||||
|
switch (nr & VAR_MODE_MASK) \
|
||||||
|
{ \
|
||||||
|
case VAR_BYTE_MODE: \
|
||||||
|
out_addr = in_addr; \
|
||||||
|
break; \
|
||||||
|
\
|
||||||
|
case VAR_WORD_MODE_MA13: \
|
||||||
|
out_addr = ((in_addr << 1) & 0x1fff8) | \
|
||||||
|
((in_addr >> 13) & 0x4) | \
|
||||||
|
(in_addr & ~0x1ffff); \
|
||||||
|
break; \
|
||||||
|
\
|
||||||
|
case VAR_WORD_MODE_MA15: \
|
||||||
|
out_addr = ((in_addr << 1) & 0x1fff8) | \
|
||||||
|
((in_addr >> 15) & 0x4) | \
|
||||||
|
(in_addr & ~0x1ffff); \
|
||||||
|
break; \
|
||||||
|
\
|
||||||
|
case VAR_DWORD_MODE: \
|
||||||
|
out_addr = ((in_addr << 2) & 0x3fff0) | \
|
||||||
|
((in_addr >> 14) & 0xc) | \
|
||||||
|
(in_addr & ~0x3ffff); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
if (nr & VAR_ROW0_MA13) \
|
||||||
|
out_addr = (out_addr & ~(1 << (13+2))) | \
|
||||||
|
((svga->sc & 1) ? (1 << (13+2)) : 0); \
|
||||||
|
if (nr & VAR_ROW1_MA14) \
|
||||||
|
out_addr = (out_addr & ~(1 << (14+2))) | \
|
||||||
|
((svga->sc & 2) ? (1 << (14+2)) : 0); \
|
||||||
|
\
|
||||||
|
return out_addr; \
|
||||||
|
}
|
||||||
|
|
||||||
|
ADDRESS_REMAP_FUNC(0)
|
||||||
|
ADDRESS_REMAP_FUNC(1)
|
||||||
|
ADDRESS_REMAP_FUNC(2)
|
||||||
|
ADDRESS_REMAP_FUNC(3)
|
||||||
|
ADDRESS_REMAP_FUNC(4)
|
||||||
|
ADDRESS_REMAP_FUNC(5)
|
||||||
|
ADDRESS_REMAP_FUNC(6)
|
||||||
|
ADDRESS_REMAP_FUNC(7)
|
||||||
|
ADDRESS_REMAP_FUNC(8)
|
||||||
|
ADDRESS_REMAP_FUNC(9)
|
||||||
|
ADDRESS_REMAP_FUNC(10)
|
||||||
|
ADDRESS_REMAP_FUNC(11)
|
||||||
|
ADDRESS_REMAP_FUNC(12)
|
||||||
|
ADDRESS_REMAP_FUNC(13)
|
||||||
|
ADDRESS_REMAP_FUNC(14)
|
||||||
|
ADDRESS_REMAP_FUNC(15)
|
||||||
|
|
||||||
|
static uint32_t (*address_remap_funcs[16])(svga_t *svga, uint32_t in_addr) =
|
||||||
|
{
|
||||||
|
address_remap_func_0,
|
||||||
|
address_remap_func_1,
|
||||||
|
address_remap_func_2,
|
||||||
|
address_remap_func_3,
|
||||||
|
address_remap_func_4,
|
||||||
|
address_remap_func_5,
|
||||||
|
address_remap_func_6,
|
||||||
|
address_remap_func_7,
|
||||||
|
address_remap_func_8,
|
||||||
|
address_remap_func_9,
|
||||||
|
address_remap_func_10,
|
||||||
|
address_remap_func_11,
|
||||||
|
address_remap_func_12,
|
||||||
|
address_remap_func_13,
|
||||||
|
address_remap_func_14,
|
||||||
|
address_remap_func_15
|
||||||
|
};
|
||||||
|
|
||||||
|
void svga_recalc_remap_func(svga_t *svga)
|
||||||
|
{
|
||||||
|
int func_nr;
|
||||||
|
|
||||||
|
if (svga->fb_only)
|
||||||
|
func_nr = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (svga->force_dword_mode)
|
||||||
|
func_nr = VAR_DWORD_MODE;
|
||||||
|
else if (svga->crtc[0x14] & (1 << 6))
|
||||||
|
func_nr = svga->packed_chain4 ? VAR_BYTE_MODE : VAR_DWORD_MODE;
|
||||||
|
else if (svga->crtc[0x17] & (1 << 6))
|
||||||
|
func_nr = VAR_BYTE_MODE;
|
||||||
|
else if (svga->crtc[0x17] & (1 << 5))
|
||||||
|
func_nr = VAR_WORD_MODE_MA15;
|
||||||
|
else
|
||||||
|
func_nr = VAR_WORD_MODE_MA13;
|
||||||
|
|
||||||
|
if (!(svga->crtc[0x17] & (1 << 0)))
|
||||||
|
func_nr |= VAR_ROW0_MA13;
|
||||||
|
if (!(svga->crtc[0x17] & (1 << 1)))
|
||||||
|
func_nr |= VAR_ROW1_MA14;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pclog("svga_recalc_remap_func: fb_only=%i chain4=%i packed_chain4=%i crtc[14]=%02x crtc[17]=%02x func_nr=%i\n",
|
||||||
|
// svga->fb_only, svga->chain4, svga->packed_chain4, svga->crtc[0x14], svga->crtc[0x17], func_nr);
|
||||||
|
svga->remap_required = (func_nr != 0);
|
||||||
|
svga->remap_func = address_remap_funcs[func_nr];
|
||||||
|
}
|
||||||
|
|
@ -631,17 +631,34 @@ void tgui_recalcmapping(tgui_t *tgui)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*Remap address for chain-4/doubleword style layout*/
|
||||||
|
static inline uint32_t dword_remap(uint32_t in_addr)
|
||||||
|
{
|
||||||
|
return ((in_addr << 2) & 0x3fff0) |
|
||||||
|
((in_addr >> 14) & 0xc) |
|
||||||
|
(in_addr & ~0x3fffc);
|
||||||
|
}
|
||||||
|
static inline uint32_t dword_remap_w(uint32_t in_addr)
|
||||||
|
{
|
||||||
|
return ((in_addr << 2) & 0x1fff8) |
|
||||||
|
((in_addr >> 14) & 0x6) |
|
||||||
|
(in_addr & ~0x1fffe);
|
||||||
|
}
|
||||||
|
|
||||||
void tgui_hwcursor_draw(svga_t *svga, int displine)
|
void tgui_hwcursor_draw(svga_t *svga, int displine)
|
||||||
{
|
{
|
||||||
uint32_t dat[2];
|
uint32_t dat[2];
|
||||||
int xx;
|
int xx;
|
||||||
int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
|
int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
|
||||||
|
uint32_t remapped_addr;
|
||||||
|
|
||||||
if (svga->interlace && svga->hwcursor_oddeven)
|
if (svga->interlace && svga->hwcursor_oddeven)
|
||||||
svga->hwcursor_latch.addr += 8;
|
svga->hwcursor_latch.addr += 8;
|
||||||
|
|
||||||
dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 24) | (svga->vram[svga->hwcursor_latch.addr + 1] << 16) | (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3];
|
remapped_addr = dword_remap(svga->hwcursor_latch.addr);
|
||||||
dat[1] = (svga->vram[svga->hwcursor_latch.addr + 4] << 24) | (svga->vram[svga->hwcursor_latch.addr + 5] << 16) | (svga->vram[svga->hwcursor_latch.addr + 6] << 8) | svga->vram[svga->hwcursor_latch.addr + 7];
|
dat[0] = (svga->vram[remapped_addr] << 24) | (svga->vram[remapped_addr + 1] << 16) | (svga->vram[remapped_addr + 2] << 8) | svga->vram[remapped_addr + 3];
|
||||||
|
remapped_addr = dword_remap(svga->hwcursor_latch.addr+4);
|
||||||
|
dat[1] = (svga->vram[remapped_addr] << 24) | (svga->vram[remapped_addr + 1] << 16) | (svga->vram[remapped_addr + 2] << 8) | svga->vram[remapped_addr + 3];
|
||||||
for (xx = 0; xx < 32; xx++)
|
for (xx = 0; xx < 32; xx++)
|
||||||
{
|
{
|
||||||
if (offset >= svga->hwcursor_latch.x)
|
if (offset >= svga->hwcursor_latch.x)
|
||||||
|
|
@ -840,8 +857,13 @@ static uint8_t tgui_ext_linear_read(uint32_t addr, void *p)
|
||||||
return 0xff;
|
return 0xff;
|
||||||
|
|
||||||
addr &= ~0xf;
|
addr &= ~0xf;
|
||||||
|
addr = dword_remap(addr);
|
||||||
|
|
||||||
for (c = 0; c < 16; c++)
|
for (c = 0; c < 16; c++)
|
||||||
tgui->copy_latch[c] = svga->vram[addr+c];
|
{
|
||||||
|
tgui->copy_latch[c] = svga->vram[addr];
|
||||||
|
addr += ((c & 3) == 3) ? 13 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
return svga->vram[addr & svga->vram_mask];
|
return svga->vram[addr & svga->vram_mask];
|
||||||
}
|
}
|
||||||
|
|
@ -871,7 +893,9 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p)
|
||||||
if (addr >= svga->vram_max)
|
if (addr >= svga->vram_max)
|
||||||
return;
|
return;
|
||||||
addr &= svga->vram_mask;
|
addr &= svga->vram_mask;
|
||||||
addr &= ~0x7;
|
addr &= (tgui->ext_gdc_regs[0] & 8) ? ~0xf : ~0x7;
|
||||||
|
|
||||||
|
addr = dword_remap(addr);
|
||||||
svga->changedvram[addr >> 12] = changeframecount;
|
svga->changedvram[addr >> 12] = changeframecount;
|
||||||
|
|
||||||
switch (tgui->ext_gdc_regs[0] & 0xf)
|
switch (tgui->ext_gdc_regs[0] & 0xf)
|
||||||
|
|
@ -882,7 +906,7 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p)
|
||||||
{
|
{
|
||||||
if (mask & (1 << c))
|
if (mask & (1 << c))
|
||||||
*(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0];
|
*(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0];
|
||||||
addr++;
|
addr += (c == 4) ? 13 : 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -892,7 +916,7 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p)
|
||||||
{
|
{
|
||||||
if (mask & (1 << c))
|
if (mask & (1 << c))
|
||||||
*(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1];
|
*(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1];
|
||||||
addr++;
|
addr += (c == 4) ? 13 : 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -902,7 +926,7 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p)
|
||||||
{
|
{
|
||||||
if ((val & mask) & (1 << c))
|
if ((val & mask) & (1 << c))
|
||||||
*(uint8_t *)&svga->vram[addr] = fg[0];
|
*(uint8_t *)&svga->vram[addr] = fg[0];
|
||||||
addr++;
|
addr += (c == 4) ? 13 : 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -912,15 +936,17 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p)
|
||||||
{
|
{
|
||||||
if ((val & mask) & (1 << c))
|
if ((val & mask) & (1 << c))
|
||||||
*(uint8_t *)&svga->vram[addr] = fg[(c & 1) ^ 1];
|
*(uint8_t *)&svga->vram[addr] = fg[(c & 1) ^ 1];
|
||||||
addr++;
|
addr += (c == 4) ? 13 : 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x8: case 0x9: case 0xa: case 0xb:
|
case 0x8: case 0x9: case 0xa: case 0xb:
|
||||||
case 0xc: case 0xd: case 0xe: case 0xf:
|
case 0xc: case 0xd: case 0xe: case 0xf:
|
||||||
addr &= ~0xf;
|
|
||||||
for (c = 0; c < 16; c++)
|
for (c = 0; c < 16; c++)
|
||||||
*(uint8_t *)&svga->vram[addr+c] = tgui->copy_latch[c];
|
{
|
||||||
|
*(uint8_t *)&svga->vram[addr] = tgui->copy_latch[c];
|
||||||
|
addr += ((c & 3) == 3) ? 13 : 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -942,6 +968,8 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p)
|
||||||
return;
|
return;
|
||||||
addr &= svga->vram_mask;
|
addr &= svga->vram_mask;
|
||||||
addr &= ~0xf;
|
addr &= ~0xf;
|
||||||
|
|
||||||
|
addr = dword_remap(addr);
|
||||||
svga->changedvram[addr >> 12] = changeframecount;
|
svga->changedvram[addr >> 12] = changeframecount;
|
||||||
|
|
||||||
val = (val >> 8) | (val << 8);
|
val = (val >> 8) | (val << 8);
|
||||||
|
|
@ -954,7 +982,7 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p)
|
||||||
{
|
{
|
||||||
if (mask & (1 << c))
|
if (mask & (1 << c))
|
||||||
*(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0];
|
*(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0];
|
||||||
addr++;
|
addr += (c & 3) ? 1 : 13;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -964,7 +992,7 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p)
|
||||||
{
|
{
|
||||||
if (mask & (1 << c))
|
if (mask & (1 << c))
|
||||||
*(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1];
|
*(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1];
|
||||||
addr++;
|
addr += (c & 3) ? 1 : 13;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -974,7 +1002,7 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p)
|
||||||
{
|
{
|
||||||
if ((val & mask) & (1 << c))
|
if ((val & mask) & (1 << c))
|
||||||
*(uint8_t *)&svga->vram[addr] = fg[0];
|
*(uint8_t *)&svga->vram[addr] = fg[0];
|
||||||
addr++;
|
addr += (c & 3) ? 1 : 13;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -984,14 +1012,17 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p)
|
||||||
{
|
{
|
||||||
if ((val & mask) & (1 << c))
|
if ((val & mask) & (1 << c))
|
||||||
*(uint8_t *)&svga->vram[addr] = fg[(c & 1) ^ 1];
|
*(uint8_t *)&svga->vram[addr] = fg[(c & 1) ^ 1];
|
||||||
addr++;
|
addr += (c & 3) ? 1 : 13;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x8: case 0x9: case 0xa: case 0xb:
|
case 0x8: case 0x9: case 0xa: case 0xb:
|
||||||
case 0xc: case 0xd: case 0xe: case 0xf:
|
case 0xc: case 0xd: case 0xe: case 0xf:
|
||||||
for (c = 0; c < 16; c++)
|
for (c = 0; c < 16; c++)
|
||||||
*(uint8_t *)&svga->vram[addr+c] = tgui->copy_latch[c];
|
{
|
||||||
|
*(uint8_t *)&svga->vram[addr] = tgui->copy_latch[c];
|
||||||
|
addr += ((c & 3) == 3) ? 13 : 1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1044,8 +1075,8 @@ enum
|
||||||
TGUI_SOLIDFILL = 0x4000 /*Pattern all zero?*/
|
TGUI_SOLIDFILL = 0x4000 /*Pattern all zero?*/
|
||||||
};
|
};
|
||||||
|
|
||||||
#define READ(addr, dat) if (tgui->accel.bpp == 0) dat = svga->vram[addr & 0x1fffff]; \
|
#define READ(addr, dat) if (tgui->accel.bpp == 0) dat = svga->vram[dword_remap(addr) & 0x1fffff]; \
|
||||||
else dat = vram_w[addr & 0xfffff];
|
else dat = vram_w[dword_remap_w(addr) & 0xfffff];
|
||||||
|
|
||||||
#define MIX() do \
|
#define MIX() do \
|
||||||
{ \
|
{ \
|
||||||
|
|
@ -1061,13 +1092,13 @@ enum
|
||||||
|
|
||||||
#define WRITE(addr, dat) if (tgui->accel.bpp == 0) \
|
#define WRITE(addr, dat) if (tgui->accel.bpp == 0) \
|
||||||
{ \
|
{ \
|
||||||
svga->vram[addr & 0x1fffff] = dat; \
|
svga->vram[dword_remap(addr) & 0x1fffff] = dat; \
|
||||||
svga->changedvram[((addr) & 0x1fffff) >> 12] = changeframecount; \
|
svga->changedvram[(dword_remap(addr) & 0x1fffff) >> 12] = changeframecount; \
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
vram_w[addr & 0xfffff] = dat; \
|
vram_w[dword_remap_w(addr) & 0xfffff] = dat; \
|
||||||
svga->changedvram[((addr) & 0xfffff) >> 11] = changeframecount; \
|
svga->changedvram[(dword_remap_w(addr) & 0xfffff) >> 11] = changeframecount; \
|
||||||
}
|
}
|
||||||
|
|
||||||
void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue