mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 01:25:33 -07:00
Port of the reworked svga memory addressing, normal chain4 mapping and ma13/14 mapping for non-CGA modes.
Fixed ET4000/W32 (without letters) hardware cursor. Fixed non-interlaced 1280x1024x8bpp Cirrus mode in the 5434. Added a note regarding the Radius (HT209) 8bpp render. Reworked the TGUI9440, but still WIP.
This commit is contained in:
126
src/include/86box/vid_svga_render_remap.h
Normal file
126
src/include/86box/vid_svga_render_remap.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/*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 & ~0x8000) | \
|
||||
((svga->sc & 1) ? 0x8000 : 0); \
|
||||
if (nr & VAR_ROW1_MA14) \
|
||||
out_addr = (out_addr & ~0x10000) | \
|
||||
((svga->sc & 2) ? 0x10000 : 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] & 0x40)
|
||||
func_nr = svga->packed_chain4 ? VAR_BYTE_MODE : VAR_DWORD_MODE;
|
||||
else if (svga->crtc[0x17] & 0x40)
|
||||
func_nr = VAR_BYTE_MODE;
|
||||
else if (svga->crtc[0x17] & 0x20)
|
||||
func_nr = VAR_WORD_MODE_MA15;
|
||||
else
|
||||
func_nr = VAR_WORD_MODE_MA13;
|
||||
|
||||
if (!(svga->crtc[0x17] & 0x01))
|
||||
func_nr |= VAR_ROW0_MA13;
|
||||
if (!(svga->crtc[0x17] & 0x02))
|
||||
func_nr |= VAR_ROW1_MA14;
|
||||
}
|
||||
|
||||
svga->remap_required = (func_nr != 0);
|
||||
svga->remap_func = address_remap_funcs[func_nr];
|
||||
}
|
||||
@@ -47,6 +47,7 @@
|
||||
#define BIOS_GD5422_PATH "roms/video/cirruslogic/cl5422.bin"
|
||||
#define BIOS_GD5426_PATH "roms/video/cirruslogic/Diamond SpeedStar PRO VLB v3.04.bin"
|
||||
#define BIOS_GD5428_ISA_PATH "roms/video/cirruslogic/5428.bin"
|
||||
#define BIOS_GD5428_MCA_PATH "roms/video/cirruslogic/SVGA141.ROM"
|
||||
#define BIOS_GD5428_PATH "roms/video/cirruslogic/vlbusjapan.BIN"
|
||||
#define BIOS_GD5429_PATH "roms/video/cirruslogic/5429.vbi"
|
||||
#define BIOS_GD5430_VLB_PATH "roms/video/cirruslogic/diamondvlbus.bin"
|
||||
@@ -150,7 +151,7 @@ typedef struct gd54xx_t
|
||||
mem_mapping_t aperture2_mapping;
|
||||
mem_mapping_t vgablt_mapping;
|
||||
|
||||
svga_t svga;
|
||||
svga_t svga, *mb_vga;
|
||||
|
||||
int has_bios, rev,
|
||||
bit32;
|
||||
@@ -214,7 +215,7 @@ typedef struct gd54xx_t
|
||||
int card;
|
||||
|
||||
uint8_t pos_regs[8];
|
||||
svga_t *mb_vga;
|
||||
int vidsys_ena;
|
||||
|
||||
uint32_t lfb_base, vgablt_base;
|
||||
|
||||
@@ -691,7 +692,8 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
|
||||
}
|
||||
}
|
||||
svga->attrff ^= 1;
|
||||
return;
|
||||
return;
|
||||
|
||||
case 0x3c4:
|
||||
svga->seqaddr = val;
|
||||
break;
|
||||
@@ -761,6 +763,8 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
|
||||
svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((val & 0x3f) * 256));
|
||||
break;
|
||||
case 0x07:
|
||||
svga->packed_chain4 = svga->seqregs[7] & 1;
|
||||
svga_recalctimings(svga);
|
||||
if (gd54xx_is_5422(svga))
|
||||
gd543x_recalc_mapping(gd54xx);
|
||||
else
|
||||
@@ -878,7 +882,7 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
|
||||
}
|
||||
|
||||
svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) &&
|
||||
!svga->gdcreg[1]) && svga->chain4;
|
||||
!svga->gdcreg[1]) && ((svga->chain4 && svga->packed_chain4) || svga->fb_only);
|
||||
if (((svga->gdcaddr == 5) && ((val ^ o) & 0x70)) ||
|
||||
((svga->gdcaddr == 6) && ((val ^ o) & 1)))
|
||||
svga_recalctimings(svga);
|
||||
@@ -898,6 +902,8 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
|
||||
svga->adv_flags |= FLAG_EXT_WRITE;
|
||||
if (svga->gdcreg[0xb] & 0x08)
|
||||
svga->adv_flags |= FLAG_LATCH8;
|
||||
if (svga->gdcreg[0xb] & 0x10)
|
||||
svga->adv_flags |= FLAG_ADDR_BY16;
|
||||
gd54xx_recalc_banking(gd54xx);
|
||||
break;
|
||||
|
||||
@@ -1018,6 +1024,11 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
case 0x46e8:
|
||||
pclog("port 46e8 = %02x\n", val & 0x18);
|
||||
break;
|
||||
|
||||
case 0x3d4:
|
||||
svga->crtcreg = val & gd54xx->crtcreg_mask;
|
||||
return;
|
||||
@@ -1595,8 +1606,11 @@ gd54xx_recalctimings(svga_t *svga)
|
||||
if (svga->seqregs[7] & CIRRUS_SR7_BPP_SVGA) {
|
||||
if (linedbl)
|
||||
svga->render = svga_render_8bpp_lowres;
|
||||
else
|
||||
else {
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
if ((svga->dispend == 512) && !svga->interlace && gd54xx_is_5434(svga))
|
||||
svga->hdisp <<= 1;
|
||||
}
|
||||
} else if (svga->gdcreg[5] & 0x40)
|
||||
svga->render = svga_render_8bpp_lowres;
|
||||
|
||||
@@ -1642,8 +1656,9 @@ gd54xx_recalctimings(svga_t *svga)
|
||||
svga->render = svga_render_32bpp_lowres;
|
||||
else
|
||||
svga->render = svga_render_32bpp_highres;
|
||||
if (svga->crtc[0x27] < CIRRUS_ID_CLGD5436)
|
||||
if (svga->crtc[0x27] < CIRRUS_ID_CLGD5436) {
|
||||
svga->rowoffset *= 2;
|
||||
}
|
||||
} else {
|
||||
svga->bpp = 24;
|
||||
if (linedbl)
|
||||
@@ -1986,7 +2001,7 @@ gd54xx_write_modes45(svga_t *svga, uint8_t val, uint32_t addr)
|
||||
|
||||
switch (svga->writemode) {
|
||||
case 4:
|
||||
if (svga->gdcreg[0xb] & 0x10) {
|
||||
if (svga->adv_flags & FLAG_ADDR_BY16) {
|
||||
addr <<= 2;
|
||||
addr &= svga->decode_mask;
|
||||
|
||||
@@ -2008,7 +2023,7 @@ gd54xx_write_modes45(svga_t *svga, uint8_t val, uint32_t addr)
|
||||
break;
|
||||
|
||||
case 5:
|
||||
if (svga->gdcreg[0xb] & 0x10) {
|
||||
if (svga->adv_flags & FLAG_ADDR_BY16) {
|
||||
addr <<= 2;
|
||||
addr &= svga->decode_mask;
|
||||
|
||||
@@ -3686,9 +3701,9 @@ cl_pci_write(int func, int addr, uint8_t val, void *p)
|
||||
static uint8_t
|
||||
gd5428_mca_read(int port, void *p)
|
||||
{
|
||||
gd54xx_t *gd54xx = (gd54xx_t *)p;
|
||||
|
||||
return gd54xx->pos_regs[port & 7];
|
||||
gd54xx_t *gd54xx = (gd54xx_t *)p;
|
||||
|
||||
return gd54xx->pos_regs[port & 7];
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3698,17 +3713,15 @@ gd5428_mca_write(int port, uint8_t val, void *p)
|
||||
|
||||
if (port < 0x102)
|
||||
return;
|
||||
|
||||
gd54xx->pos_regs[port & 7] = val;
|
||||
|
||||
gd54xx->pos_regs[port & 7] = val;
|
||||
gd543x_recalc_mapping(gd54xx);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
gd5428_mca_feedb(void *p)
|
||||
{
|
||||
gd54xx_t *gd54xx = (gd54xx_t *)p;
|
||||
|
||||
return gd54xx->pos_regs[2] & 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3761,6 +3774,8 @@ static void
|
||||
case CIRRUS_ID_CLGD5428:
|
||||
if (gd54xx->vlb)
|
||||
romfn = BIOS_GD5428_PATH;
|
||||
else if (gd54xx->mca)
|
||||
romfn = BIOS_GD5428_MCA_PATH;
|
||||
else
|
||||
romfn = BIOS_GD5428_ISA_PATH;
|
||||
break;
|
||||
@@ -3953,7 +3968,8 @@ static void
|
||||
if (gd54xx->mca) {
|
||||
gd54xx->pos_regs[0] = 0x7b;
|
||||
gd54xx->pos_regs[1] = 0x91;
|
||||
mca_add(gd5428_mca_read, gd5428_mca_write, gd5428_mca_feedb, NULL, gd54xx);
|
||||
mca_add(gd5428_mca_read, gd5428_mca_write, gd5428_mca_feedb, NULL, gd54xx);
|
||||
io_sethandler(0x46e8, 0x0001, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx);
|
||||
}
|
||||
|
||||
if (gd54xx_is_5434(svga)) {
|
||||
@@ -4013,6 +4029,12 @@ gd5428_isa_available(void)
|
||||
return rom_present(BIOS_GD5428_ISA_PATH);
|
||||
}
|
||||
|
||||
static int
|
||||
gd5428_mca_available(void)
|
||||
{
|
||||
return rom_present(BIOS_GD5428_MCA_PATH);
|
||||
}
|
||||
|
||||
static int
|
||||
gd5429_available(void)
|
||||
{
|
||||
@@ -4369,7 +4391,7 @@ const device_t gd5428_mca_device =
|
||||
gd54xx_init,
|
||||
gd54xx_close,
|
||||
NULL,
|
||||
{ gd5428_available },
|
||||
{ gd5428_mca_available },
|
||||
gd54xx_speed_changed,
|
||||
gd54xx_force_redraw,
|
||||
NULL
|
||||
|
||||
@@ -742,6 +742,8 @@ et4000_init(const device_t *info)
|
||||
|
||||
dev->svga.translate_address = get_et4000_addr;
|
||||
|
||||
dev->svga.packed_chain4 = 1;
|
||||
|
||||
return(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,16 +46,6 @@
|
||||
#define BIOS_ROM_PATH_W32P "roms/video/et4000w32/ET4K_W32.BIN"
|
||||
#define BIOS_ROM_PATH_W32P_REVC "roms/video/et4000w32/et4000w32pcardex.BIN"
|
||||
|
||||
#define FIFO_SIZE 65536
|
||||
#define FIFO_MASK (FIFO_SIZE - 1)
|
||||
#define FIFO_ENTRY_SIZE (1 << 31)
|
||||
|
||||
#define FIFO_ENTRIES (et4000->fifo_write_idx - et4000->fifo_read_idx)
|
||||
#define FIFO_FULL ((et4000->fifo_write_idx - et4000->fifo_read_idx) >= (FIFO_SIZE-1))
|
||||
#define FIFO_EMPTY (et4000->fifo_read_idx == et4000->fifo_write_idx)
|
||||
|
||||
#define FIFO_TYPE 0xff000000
|
||||
#define FIFO_ADDR 0x00ffffff
|
||||
|
||||
#define ACL_WRST 1
|
||||
#define ACL_RDST 2
|
||||
@@ -73,20 +63,6 @@ enum
|
||||
ET4000W32P_DIAMOND
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
FIFO_INVALID = (0x00 << 24),
|
||||
FIFO_WRITE_BYTE = (0x01 << 24),
|
||||
FIFO_WRITE_MMU = (0x02 << 24)
|
||||
};
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t addr_type;
|
||||
uint32_t val;
|
||||
} fifo_entry_t;
|
||||
|
||||
|
||||
typedef struct et4000w32p_t
|
||||
{
|
||||
@@ -138,15 +114,6 @@ typedef struct et4000w32p_t
|
||||
uint32_t base[3];
|
||||
uint8_t ctrl;
|
||||
} mmu;
|
||||
|
||||
fifo_entry_t fifo[FIFO_SIZE];
|
||||
volatile int fifo_read_idx, fifo_write_idx;
|
||||
|
||||
thread_t * fifo_thread;
|
||||
event_t * wake_fifo_thread;
|
||||
event_t * fifo_not_full_event;
|
||||
|
||||
uint64_t blitter_time, status_time;
|
||||
} et4000w32p_t;
|
||||
|
||||
|
||||
@@ -198,7 +165,7 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p)
|
||||
et4000w32p_t *et4000 = (et4000w32p_t *)p;
|
||||
svga_t *svga = &et4000->svga;
|
||||
uint8_t old;
|
||||
uint32_t add2addr;
|
||||
uint32_t add2addr = 0;
|
||||
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
@@ -287,18 +254,30 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p)
|
||||
case 0x210b: case 0x211b: case 0x212b: case 0x213b:
|
||||
case 0x214b: case 0x215b: case 0x216b: case 0x217b:
|
||||
et4000->regs[et4000->index] = val;
|
||||
svga->hwcursor.xsize = svga->hwcursor.ysize = (et4000->regs[0xEF] & 4) ? 128 : 64;
|
||||
svga->hwcursor.xsize = svga->hwcursor.ysize = ((et4000->regs[0xEF] & 4) || (et4000->type == ET4000W32)) ? 128 : 64;
|
||||
svga->hwcursor.x = et4000->regs[0xE0] | ((et4000->regs[0xE1] & 7) << 8);
|
||||
svga->hwcursor.y = et4000->regs[0xE4] | ((et4000->regs[0xE5] & 7) << 8);
|
||||
svga->hwcursor.ena = !!(et4000->regs[0xF7] & 0x80);
|
||||
svga->hwcursor.xoff = et4000->regs[0xE2];
|
||||
svga->hwcursor.yoff = et4000->regs[0xE6];
|
||||
|
||||
if (et4000->type == ET4000W32) {
|
||||
switch (svga->bpp) {
|
||||
case 8:
|
||||
svga->hwcursor.xoff += 32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (svga->hwcursor.xsize == 128) {
|
||||
svga->hwcursor.xoff = et4000->regs[0xE2] & 0x7f;
|
||||
svga->hwcursor.yoff = et4000->regs[0xE6] & 0x7f;
|
||||
svga->hwcursor.xoff &= 0x7f;
|
||||
svga->hwcursor.yoff &= 0x7f;
|
||||
} else {
|
||||
svga->hwcursor.xoff = et4000->regs[0xE2] & 0x3f;
|
||||
svga->hwcursor.yoff = et4000->regs[0xE6] & 0x3f;
|
||||
svga->hwcursor.xoff &= 0x3f;
|
||||
svga->hwcursor.yoff &= 0x3f;
|
||||
}
|
||||
svga->hwcursor.addr = (et4000->regs[0xe8] | (et4000->regs[0xe9] << 8) | ((et4000->regs[0xea] & 7) << 16)) << 2;
|
||||
|
||||
add2addr = svga->hwcursor.yoff * ((svga->hwcursor.xsize == 128) ? 32 : 16);
|
||||
svga->hwcursor.addr += add2addr;
|
||||
return;
|
||||
@@ -385,28 +364,42 @@ et4000w32p_recalctimings(svga_t *svga)
|
||||
svga->clock = (cpuclock * (double)(1ull << 32)) / svga->getclock((svga->miscout >> 2) & 3, svga->clock_gen);
|
||||
|
||||
if (svga->adv_flags & FLAG_NOSKEW) {
|
||||
/* On the Cardex ET4000/W32p-based cards, adjust text mode clocks by 1. */
|
||||
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /* Text mode */
|
||||
svga->ma_latch--;
|
||||
/* On the Cardex ET4000/W32p-based cards, adjust text mode clocks by 1. */
|
||||
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /* Text mode */
|
||||
svga->ma_latch--;
|
||||
|
||||
if ((svga->seqregs[1] & 8)) /*40 column*/
|
||||
svga->hdisp += (svga->seqregs[1] & 1) ? 16 : 18;
|
||||
else
|
||||
svga->hdisp += (svga->seqregs[1] & 1) ? 8 : 9;
|
||||
} else {
|
||||
/* Also adjust the graphics mode clocks in some cases. */
|
||||
if ((svga->gdcreg[5] & 0x40) && (svga->bpp != 32)) {
|
||||
if ((svga->bpp == 15) || (svga->bpp == 16) || (svga->bpp == 24))
|
||||
if ((svga->seqregs[1] & 8)) /*40 column*/
|
||||
svga->hdisp += (svga->seqregs[1] & 1) ? 16 : 18;
|
||||
else
|
||||
svga->hdisp += (svga->seqregs[1] & 1) ? 8 : 9;
|
||||
} else {
|
||||
/* Also adjust the graphics mode clocks in some cases. */
|
||||
if ((svga->gdcreg[5] & 0x40) && (svga->bpp != 32)) {
|
||||
if ((svga->bpp == 15) || (svga->bpp == 16) || (svga->bpp == 24))
|
||||
svga->hdisp += (svga->seqregs[1] & 1) ? 16 : 18;
|
||||
else
|
||||
svga->hdisp += (svga->seqregs[1] & 1) ? 8 : 9;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
et4000->adjust_cursor = 0;
|
||||
if (et4000->type == ET4000W32) {
|
||||
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
|
||||
if (svga->gdcreg[5] & 0x40) {
|
||||
switch (svga->bpp) {
|
||||
case 8:
|
||||
if (svga->hdisp == 640 || svga->hdisp == 800 || svga->hdisp == 1024)
|
||||
break;
|
||||
svga->hdisp -= 24;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (svga->bpp) {
|
||||
et4000->adjust_cursor = 0;
|
||||
|
||||
switch (svga->bpp) {
|
||||
case 15: case 16:
|
||||
svga->hdisp >>= 1;
|
||||
if (et4000->type <= ET4000W32P_REVC)
|
||||
@@ -417,7 +410,7 @@ et4000w32p_recalctimings(svga_t *svga)
|
||||
if (et4000->type <= ET4000W32P_REVC)
|
||||
et4000->adjust_cursor = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
svga->render = svga_render_blank;
|
||||
if (!svga->scrblank && svga->attr_palette_enable) {
|
||||
@@ -655,7 +648,7 @@ et4000w32p_accel_write_mmu(et4000w32p_t *et4000, uint32_t addr, uint8_t val)
|
||||
if (!(et4000->acl.internal.ctrl_routing & 0x37))
|
||||
et4000w32p_blit(0xFFFFFF, ~0, 0, 0, et4000);
|
||||
et4000->acl.cpu_input_num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (et4000->acl.internal.ctrl_routing & 7) {
|
||||
et4000->acl.cpu_input = (et4000->acl.cpu_input &~ (0xFF << (et4000->acl.cpu_input_num << 3))) |
|
||||
@@ -679,86 +672,6 @@ et4000w32p_accel_write_mmu(et4000w32p_t *et4000, uint32_t addr, uint8_t val)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fifo_thread(void *param)
|
||||
{
|
||||
et4000w32p_t *et4000 = (et4000w32p_t *)param;
|
||||
|
||||
uint64_t start_time = 0;
|
||||
uint64_t end_time = 0;
|
||||
|
||||
fifo_entry_t *fifo;
|
||||
|
||||
while (1) {
|
||||
thread_set_event(et4000->fifo_not_full_event);
|
||||
thread_wait_event(et4000->wake_fifo_thread, -1);
|
||||
thread_reset_event(et4000->wake_fifo_thread);
|
||||
et4000->blitter_busy = 1;
|
||||
while (!FIFO_EMPTY) {
|
||||
start_time = plat_timer_read();
|
||||
fifo = &et4000->fifo[et4000->fifo_read_idx & FIFO_MASK];
|
||||
|
||||
switch (fifo->addr_type & FIFO_TYPE) {
|
||||
case FIFO_WRITE_BYTE:
|
||||
et4000w32p_accel_write_fifo(et4000, fifo->addr_type & FIFO_ADDR, fifo->val);
|
||||
break;
|
||||
case FIFO_WRITE_MMU:
|
||||
et4000w32p_accel_write_mmu(et4000, fifo->addr_type & FIFO_ADDR, fifo->val);
|
||||
break;
|
||||
}
|
||||
|
||||
et4000->fifo_read_idx++;
|
||||
fifo->addr_type = FIFO_INVALID;
|
||||
|
||||
if (FIFO_ENTRIES > 0xe000)
|
||||
thread_set_event(et4000->fifo_not_full_event);
|
||||
|
||||
end_time = plat_timer_read();
|
||||
et4000->blitter_time += end_time - start_time;
|
||||
}
|
||||
et4000->blitter_busy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static __inline void
|
||||
wake_fifo_thread(et4000w32p_t *et4000)
|
||||
{
|
||||
thread_set_event(et4000->wake_fifo_thread); /* Wake up FIFO thread if moving from idle */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
et4000w32p_wait_fifo_idle(et4000w32p_t *et4000)
|
||||
{
|
||||
while (!FIFO_EMPTY) {
|
||||
wake_fifo_thread(et4000);
|
||||
thread_wait_event(et4000->fifo_not_full_event, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
et4000w32p_queue(et4000w32p_t *et4000, uint32_t addr, uint32_t val, uint32_t type)
|
||||
{
|
||||
fifo_entry_t *fifo = &et4000->fifo[et4000->fifo_write_idx & FIFO_MASK];
|
||||
|
||||
if (FIFO_FULL) {
|
||||
thread_reset_event(et4000->fifo_not_full_event);
|
||||
if (FIFO_FULL)
|
||||
thread_wait_event(et4000->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/
|
||||
}
|
||||
|
||||
fifo->val = val;
|
||||
fifo->addr_type = (addr & FIFO_ADDR) | type;
|
||||
|
||||
et4000->fifo_write_idx++;
|
||||
|
||||
if ((FIFO_ENTRIES > 0xe000) || (FIFO_ENTRIES < 8))
|
||||
wake_fifo_thread(et4000);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
@@ -771,10 +684,7 @@ et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p)
|
||||
case 0x4000: /* MMU 2 */
|
||||
et4000->bank = (addr >> 13) & 3;
|
||||
if (et4000->mmu.ctrl & (1 << et4000->bank)) {
|
||||
if (et4000->type >= ET4000W32P_REVC)
|
||||
et4000w32p_queue(et4000, addr & 0x7fff, val, FIFO_WRITE_MMU);
|
||||
else
|
||||
et4000w32p_accel_write_mmu(et4000, addr & 0x7fff, val);
|
||||
et4000w32p_accel_write_mmu(et4000, addr & 0x7fff, val);
|
||||
} else {
|
||||
if (((addr & 0x1fff) + et4000->mmu.base[et4000->bank]) < svga->vram_max) {
|
||||
svga->vram[(addr & 0x1fff) + et4000->mmu.base[et4000->bank]] = val;
|
||||
@@ -784,10 +694,7 @@ et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p)
|
||||
break;
|
||||
case 0x6000:
|
||||
if ((addr & 0x7fff) >= 0x7f80) {
|
||||
if (et4000->type >= ET4000W32P_REVC)
|
||||
et4000w32p_queue(et4000, addr & 0x7fff, val, FIFO_WRITE_BYTE);
|
||||
else
|
||||
et4000w32p_accel_write_fifo(et4000, addr & 0x7fff, val);
|
||||
et4000w32p_accel_write_fifo(et4000, addr & 0x7fff, val);
|
||||
} else switch (addr & 0x7fff) {
|
||||
case 0x7f00: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFFFFFF00) | val; break;
|
||||
case 0x7f01: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFFFF00FF) | (val << 8); break;
|
||||
@@ -822,9 +729,6 @@ et4000w32p_mmu_read(uint32_t addr, void *p)
|
||||
case 0x4000: /* MMU 2 */
|
||||
bank = (addr >> 13) & 3;
|
||||
if (et4000->mmu.ctrl & (1 << bank)) {
|
||||
if (et4000->type >= ET4000W32P_REVC)
|
||||
et4000w32p_wait_fifo_idle(et4000);
|
||||
|
||||
temp = 0xff;
|
||||
if (et4000->acl.cpu_dat_pos) {
|
||||
et4000->acl.cpu_dat_pos--;
|
||||
@@ -844,10 +748,6 @@ et4000w32p_mmu_read(uint32_t addr, void *p)
|
||||
return svga->vram[(addr&0x1fff) + et4000->mmu.base[bank]];
|
||||
|
||||
case 0x6000:
|
||||
if ((addr & 0x7fff) >= 0x7f80) {
|
||||
if (et4000->type >= ET4000W32P_REVC)
|
||||
et4000w32p_wait_fifo_idle(et4000);
|
||||
}
|
||||
switch (addr & 0x7fff) {
|
||||
case 0x7f00: return et4000->mmu.base[0];
|
||||
case 0x7f01: return et4000->mmu.base[0] >> 8;
|
||||
@@ -867,10 +767,6 @@ et4000w32p_mmu_read(uint32_t addr, void *p)
|
||||
if (et4000->type >= ET4000W32P_REVC) {
|
||||
temp = et4000->acl.status;
|
||||
temp &= ~(ACL_RDST | ACL_WRST);
|
||||
if (!FIFO_EMPTY)
|
||||
temp |= ACL_RDST;
|
||||
if (FIFO_FULL)
|
||||
temp |= ACL_WRST;
|
||||
if (temp == ACL_XYST && (et4000->acl.internal.ctrl_routing == 1 || et4000->acl.internal.ctrl_routing == 2))
|
||||
temp |= ACL_RDST;
|
||||
} else {
|
||||
@@ -1280,13 +1176,29 @@ et4000w32p_hwcursor_draw(svga_t *svga, int displine)
|
||||
int shift = (et4000->adjust_cursor + 1);
|
||||
int width = (svga->hwcursor_latch.xsize - svga->hwcursor_latch.xoff);
|
||||
int pitch = (svga->hwcursor_latch.xsize == 128) ? 32 : 16;
|
||||
int x_acc = 4;
|
||||
int minus_width = 0;
|
||||
uint8_t dat;
|
||||
offset = svga->hwcursor_latch.xoff;
|
||||
|
||||
if (et4000->type == ET4000W32) {
|
||||
switch (svga->bpp) {
|
||||
case 8:
|
||||
minus_width = 0;
|
||||
x_acc = 2;
|
||||
break;
|
||||
case 15: case 16:
|
||||
minus_width = 64;
|
||||
x_acc = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; x < width; x += 4) {
|
||||
for (x = 0; x < (width - minus_width); x += x_acc) {
|
||||
dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)];
|
||||
|
||||
xx = svga->hwcursor_latch.x + svga->x_add + x;
|
||||
|
||||
if (!(xx % shift)) {
|
||||
xx2 = xx / shift;
|
||||
if (!(dat & 2)) buffer32->line[displine][xx2] = (dat & 1) ? 0xFFFFFF : 0;
|
||||
@@ -1318,7 +1230,7 @@ et4000w32p_hwcursor_draw(svga_t *svga, int displine)
|
||||
offset += 4;
|
||||
}
|
||||
|
||||
svga->hwcursor_latch.addr += pitch;
|
||||
svga->hwcursor_latch.addr += pitch;
|
||||
}
|
||||
|
||||
|
||||
@@ -1375,10 +1287,10 @@ et4000w32p_pci_read(int func, int addr, void *p)
|
||||
|
||||
case 0x07: return 1 << 1; /* Medium DEVSEL timing */
|
||||
|
||||
case 0x08: return 0x06; /* Revision ID */
|
||||
case 0x08: return (et4000->rev); /* Revision ID */
|
||||
case 0x09: return 0; /* Programming interface */
|
||||
|
||||
case 0x0a: return 0x00; /* Supports VGA interface, XGA compatible */
|
||||
case 0x0a: return 0x00; /* Supports VGA interface */
|
||||
case 0x0b: return 0x03; /* This has to be done in order to make this card work with the two 486 PCI machines. */
|
||||
|
||||
case 0x10: return 0x00; /* Linear frame buffer address */
|
||||
@@ -1450,8 +1362,17 @@ et4000w32p_init(const device_t *info)
|
||||
et4000w32p_t *et4000 = malloc(sizeof(et4000w32p_t));
|
||||
memset(et4000, 0, sizeof(et4000w32p_t));
|
||||
|
||||
vram_size = device_get_config_int("memory");
|
||||
et4000->interleaved = (vram_size == 2 && (info->local >= ET4000W32I)) ? 1 : 0;
|
||||
et4000->pci = (info->flags & DEVICE_PCI) ? 0x80 : 0x00;
|
||||
et4000->vlb = (info->flags & DEVICE_VLB) ? 0x40 : 0x00;
|
||||
|
||||
/*The ET4000/W32i ISA BIOS seems to not support 2MB of VRAM*/
|
||||
if ((info->local == ET4000W32) || ((info->local == ET4000W32I) && !(et4000->vlb)))
|
||||
vram_size = 1;
|
||||
else
|
||||
vram_size = device_get_config_int("memory");
|
||||
|
||||
/*The interleaved VRAM was introduced by the ET4000/W32i*/
|
||||
et4000->interleaved = ((vram_size == 2) && (info->local != ET4000W32)) ? 1 : 0;
|
||||
|
||||
if (info->flags & DEVICE_PCI)
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000w32_pci);
|
||||
@@ -1467,22 +1388,22 @@ et4000w32p_init(const device_t *info)
|
||||
NULL);
|
||||
|
||||
et4000->vram_mask = (vram_size << 20) - 1;
|
||||
et4000->svga.decode_mask = (vram_size << 20) - 1;
|
||||
|
||||
et4000->type = info->local;
|
||||
|
||||
et4000->pci = (info->flags & DEVICE_PCI) ? 0x80 : 0x00;
|
||||
et4000->vlb = (info->flags & DEVICE_VLB) ? 0x40 : 0x00;
|
||||
|
||||
switch(et4000->type) {
|
||||
case ET4000W32:
|
||||
/* ET4000/W32 */
|
||||
et4000->rev = 0;
|
||||
|
||||
rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32, 0xc0000, 0x8000, 0x7fff, 0,
|
||||
MEM_MAPPING_EXTERNAL);
|
||||
|
||||
et4000->svga.ramdac = device_add(&tseng_ics5301_ramdac_device);
|
||||
et4000->svga.clock_gen = et4000->svga.ramdac;
|
||||
et4000->svga.getclock = sdac_getclock;
|
||||
break;
|
||||
break;
|
||||
|
||||
case ET4000W32I:
|
||||
/* ET4000/W32i rev B */
|
||||
@@ -1577,12 +1498,7 @@ et4000w32p_init(const device_t *info)
|
||||
et4000->pci_regs[0x32] = 0x00;
|
||||
et4000->pci_regs[0x33] = 0xf0;
|
||||
|
||||
if (et4000->type >= ET4000W32P_REVC) {
|
||||
et4000w32_log("Thread started\n");
|
||||
et4000->wake_fifo_thread = thread_create_event();
|
||||
et4000->fifo_not_full_event = thread_create_event();
|
||||
et4000->fifo_thread = thread_create(fifo_thread, et4000);
|
||||
}
|
||||
et4000->svga.packed_chain4 = 1;
|
||||
|
||||
return et4000;
|
||||
}
|
||||
@@ -1644,12 +1560,6 @@ et4000w32p_close(void *p)
|
||||
|
||||
svga_close(&et4000->svga);
|
||||
|
||||
if (et4000->type >= ET4000W32P_REVC) {
|
||||
thread_kill(et4000->fifo_thread);
|
||||
thread_destroy_event(et4000->wake_fifo_thread);
|
||||
thread_destroy_event(et4000->fifo_not_full_event);
|
||||
}
|
||||
|
||||
free(et4000);
|
||||
}
|
||||
|
||||
@@ -1702,7 +1612,7 @@ const device_t et4000w32_device =
|
||||
{ et4000w32_available },
|
||||
et4000w32p_speed_changed,
|
||||
et4000w32p_force_redraw,
|
||||
et4000w32p_config
|
||||
NULL
|
||||
};
|
||||
|
||||
const device_t et4000w32_onboard_device =
|
||||
@@ -1713,7 +1623,7 @@ const device_t et4000w32_onboard_device =
|
||||
{ et4000w32_available },
|
||||
et4000w32p_speed_changed,
|
||||
et4000w32p_force_redraw,
|
||||
et4000w32p_config
|
||||
NULL
|
||||
};
|
||||
|
||||
const device_t et4000w32i_isa_device =
|
||||
@@ -1724,7 +1634,7 @@ const device_t et4000w32i_isa_device =
|
||||
{ et4000w32i_isa_available },
|
||||
et4000w32p_speed_changed,
|
||||
et4000w32p_force_redraw,
|
||||
et4000w32p_config
|
||||
NULL
|
||||
};
|
||||
|
||||
const device_t et4000w32i_vlb_device =
|
||||
|
||||
@@ -127,10 +127,20 @@ ht216_log(const char *fmt, ...)
|
||||
#define ht216_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
/*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_recalc_bank_regs(ht216_t *ht216, int mode)
|
||||
{
|
||||
svga_t *svga = &ht216->svga;
|
||||
|
||||
if (mode) {
|
||||
ht216->read_bank_reg[0] = ht216->ht_regs[0xe8];
|
||||
ht216->write_bank_reg[0] = ht216->ht_regs[0xe8];
|
||||
@@ -142,14 +152,14 @@ ht216_recalc_bank_regs(ht216_t *ht216, int mode)
|
||||
ht216->write_bank_reg[0] = ((ht216->ht_regs[0xf6] & 0x3) << 6);
|
||||
ht216->write_bank_reg[1] = ((ht216->ht_regs[0xf6] & 0x3) << 6);
|
||||
|
||||
if ((ht216->ht_regs[0xfc] & 0x20) || (ht216->ht_regs[0xfc] & 0x04)) {
|
||||
if (svga->packed_chain4 || (ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE)) {
|
||||
ht216->read_bank_reg[0] |= (ht216->misc & 0x20);
|
||||
ht216->read_bank_reg[1] |= (ht216->misc & 0x20);
|
||||
ht216->write_bank_reg[0] |= (ht216->misc & 0x20);
|
||||
ht216->write_bank_reg[1] |= (ht216->misc & 0x20);
|
||||
}
|
||||
|
||||
if ((ht216->ht_regs[0xfc] & 0x20) || ((ht216->ht_regs[0xfc] & 0x06) == 0x04)) {
|
||||
if (svga->packed_chain4 || ((ht216->ht_regs[0xfc] & 0x06) == 0x04)) {
|
||||
ht216->read_bank_reg[0] |= ((ht216->ht_regs[0xf9] & 1) << 4);
|
||||
ht216->read_bank_reg[1] |= ((ht216->ht_regs[0xf9] & 1) << 4);
|
||||
ht216->write_bank_reg[0] |= ((ht216->ht_regs[0xf9] & 1) << 4);
|
||||
@@ -355,7 +365,8 @@ ht216_out(uint16_t addr, uint8_t val, void *p)
|
||||
break;
|
||||
|
||||
case 0xfc:
|
||||
ht216_log("HT216 reg 0xfc write = %02x, mode = 0, chain4 = %x, bit 7 = %02x\n", val, svga->chain4, val & 0x80);
|
||||
ht216_log("HT216 reg 0xfc write = %02x, mode = 0, chain4 = %x, bit 7 = %02x, packedchain = %02x\n", val, svga->chain4, val & 0x80, val & 0x20);
|
||||
svga->packed_chain4 = !!(val & 0x20);
|
||||
ht216_recalc_bank_regs(ht216, 0);
|
||||
ht216_remap(ht216);
|
||||
svga->fullchange = changeframecount;
|
||||
@@ -383,6 +394,11 @@ ht216_out(uint16_t addr, uint8_t val, void *p)
|
||||
else
|
||||
svga->banked_mask = 0xffff;
|
||||
}
|
||||
|
||||
if (svga->gdcaddr <= 8) {
|
||||
svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) &&
|
||||
!svga->gdcreg[1]) && svga->chain4 && svga->packed_chain4;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3D4:
|
||||
@@ -559,82 +575,6 @@ ht216_remap(ht216_t *ht216)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ht216_1_2bpp_highres(svga_t *svga)
|
||||
{
|
||||
int changed_offset, x;
|
||||
int oddeven;
|
||||
uint32_t addr, *p;
|
||||
uint8_t edat[4];
|
||||
uint8_t dat;
|
||||
|
||||
if ((svga->displine + svga->y_add) < 0)
|
||||
return;
|
||||
|
||||
changed_offset = (svga->ma + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12;
|
||||
|
||||
if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) {
|
||||
p = &buffer32->line[svga->displine + svga->y_add][svga->x_add];
|
||||
|
||||
if (svga->firstline_draw == 2000)
|
||||
svga->firstline_draw = svga->displine;
|
||||
svga->lastline_draw = svga->displine;
|
||||
|
||||
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) {
|
||||
addr = svga->ma;
|
||||
oddeven = 0;
|
||||
|
||||
if (!(svga->crtc[0x17] & 0x40)) {
|
||||
addr = (addr << 1) & svga->vram_mask;
|
||||
|
||||
if (svga->seqregs[1] & 4)
|
||||
oddeven = (addr & 4) ? 1 : 0;
|
||||
|
||||
addr &= ~7;
|
||||
|
||||
if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000))
|
||||
addr |= 4;
|
||||
if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000))
|
||||
addr |= 4;
|
||||
}
|
||||
|
||||
if (!(svga->crtc[0x17] & 0x01))
|
||||
addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0);
|
||||
if (!(svga->crtc[0x17] & 0x02))
|
||||
addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0);
|
||||
|
||||
if (svga->seqregs[1] & 4) {
|
||||
edat[0] = svga->vram[addr | oddeven];
|
||||
edat[2] = svga->vram[addr | oddeven | 0x2];
|
||||
edat[1] = edat[3] = 0;
|
||||
} else {
|
||||
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]);
|
||||
}
|
||||
svga->ma += 4;
|
||||
svga->ma &= svga->vram_mask;
|
||||
|
||||
if (svga->crtc[0x17] & 0x80) {
|
||||
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[1] = 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);
|
||||
p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
|
||||
p[3] = 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);
|
||||
p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]];
|
||||
p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
|
||||
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[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]];
|
||||
} else
|
||||
memset(p, 0x00, 8 * sizeof(uint32_t));
|
||||
|
||||
p += 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ht216_recalctimings(svga_t *svga)
|
||||
{
|
||||
@@ -674,7 +614,7 @@ ht216_recalctimings(svga_t *svga)
|
||||
|
||||
if (svga->crtc[0x17] == 0xeb) {
|
||||
svga->rowoffset <<= 1;
|
||||
svga->render = ht216_1_2bpp_highres;
|
||||
svga->render = svga_render_2bpp_headland_highres;
|
||||
}
|
||||
|
||||
if (svga->bpp == 8) {
|
||||
@@ -691,7 +631,7 @@ ht216_recalctimings(svga_t *svga)
|
||||
ht216->adjust_cursor = 1;
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
} else {
|
||||
ht216_log("8bpp low\n");
|
||||
ht216_log("8bpp low, packed = %02x, chain4 = %02x\n", svga->packed_chain4, svga->chain4);
|
||||
svga->render = svga_render_8bpp_lowres;
|
||||
}
|
||||
} else if (ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE) {
|
||||
@@ -702,6 +642,8 @@ ht216_recalctimings(svga_t *svga)
|
||||
svga->hdisp++;
|
||||
svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8;
|
||||
svga->rowoffset <<= 1;
|
||||
if ((svga->crtc[0x17] & 0x60) == 0x20) /*Would result in a garbled screen with trailing cursor glitches*/
|
||||
svga->crtc[0x17] |= 0x40;
|
||||
}
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
}
|
||||
@@ -711,7 +653,7 @@ ht216_recalctimings(svga_t *svga)
|
||||
svga->render = svga_render_15bpp_highres;
|
||||
}
|
||||
|
||||
svga->ma_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 14);
|
||||
svga->ma_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 14);
|
||||
|
||||
if (svga->crtc[0x17] == 0xeb) /*Looks like that 1024x768 mono mode expects 512K of video memory*/
|
||||
svga->vram_display_mask = 0x7ffff;
|
||||
@@ -787,7 +729,6 @@ extalu(int op, uint8_t input_a, uint8_t input_b)
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t cpu_dat_unexpanded)
|
||||
{
|
||||
@@ -801,12 +742,12 @@ ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t cpu_dat_u
|
||||
writemask2 = svga->seqregs[2];
|
||||
|
||||
if (!(svga->gdcreg[6] & 1))
|
||||
svga->fullchange = 2;
|
||||
svga->fullchange = 2;
|
||||
|
||||
if (svga->chain4 || svga->fb_only) {
|
||||
if (svga->chain4) {
|
||||
writemask2 = 1 << (addr & 3);
|
||||
addr &= ~3;
|
||||
} else if (svga->chain2_write && (svga->crtc[0x17] != 0xeb)) {
|
||||
addr = dword_remap(svga, addr) & ~3;
|
||||
} else if (svga->chain2_write && (svga->crtc[0x17] != 0xeb)) {
|
||||
writemask2 &= ~0xa;
|
||||
if (addr & 1)
|
||||
writemask2 <<= 1;
|
||||
@@ -984,9 +925,10 @@ ht216_dm_extalu_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t bi
|
||||
uint8_t input_a = 0, input_b = 0;
|
||||
uint8_t fg, bg;
|
||||
uint8_t output;
|
||||
uint32_t remapped_addr = dword_remap(svga, addr);
|
||||
|
||||
if (ht216->ht_regs[0xcd] & HT_REG_CD_RMWMDE) /*RMW*/
|
||||
input_b = svga->vram[addr];
|
||||
input_b = svga->vram[remapped_addr];
|
||||
else
|
||||
input_b = ht216->bg_latch[addr & 7];
|
||||
|
||||
@@ -1011,8 +953,8 @@ ht216_dm_extalu_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t bi
|
||||
fg = extalu(ht216->ht_regs[0xce] >> 4, input_a, input_b);
|
||||
bg = extalu(ht216->ht_regs[0xce] & 0xf, input_a, input_b);
|
||||
output = (fg & rop_select) | (bg & ~rop_select);
|
||||
svga->vram[addr] = (svga->vram[addr] & ~bit_mask) | (output & bit_mask);
|
||||
svga->changedvram[addr >> 12] = changeframecount;
|
||||
svga->vram[addr] = (svga->vram[remapped_addr] & ~bit_mask) | (output & bit_mask);
|
||||
svga->changedvram[remapped_addr >> 12] = changeframecount;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1027,12 +969,12 @@ ht216_dm_masked_write(ht216_t *ht216, uint32_t addr, uint8_t val, uint8_t bit_ma
|
||||
writemask2 = svga->seqregs[2];
|
||||
|
||||
if (!(svga->gdcreg[6] & 1))
|
||||
svga->fullchange = 2;
|
||||
svga->fullchange = 2;
|
||||
|
||||
if ((svga->chain4 || svga->fb_only) && (svga->writemode < 4)) {
|
||||
if (svga->chain4) {
|
||||
writemask2 = 1 << (addr & 3);
|
||||
addr &= ~3;
|
||||
} else if (svga->chain2_write) {
|
||||
addr = dword_remap(svga, addr) & ~3;
|
||||
} else if (svga->chain2_write) {
|
||||
writemask2 &= ~0xa;
|
||||
if (addr & 1)
|
||||
writemask2 <<= 1;
|
||||
@@ -1304,7 +1246,7 @@ ht216_read_common(ht216_t *ht216, uint32_t addr)
|
||||
|
||||
count = (1 << count);
|
||||
|
||||
if (svga->chain4 || svga->fb_only) {
|
||||
if (svga->chain4 && svga->packed_chain4) {
|
||||
addr &= svga->decode_mask;
|
||||
if (addr >= svga->vram_max)
|
||||
return 0xff;
|
||||
@@ -1312,9 +1254,12 @@ ht216_read_common(ht216_t *ht216, uint32_t addr)
|
||||
if (ht216->ht_regs[0xcd] & HT_REG_CD_ASTODE)
|
||||
latch_addr += (svga->gdcreg[3] & 7);
|
||||
for (i = 0; i < 8; i++)
|
||||
ht216->bg_latch[i] = svga->vram[latch_addr + i];
|
||||
return svga->vram[addr & svga->vram_mask];
|
||||
} else if (svga->chain2_read && (svga->crtc[0x17] != 0xeb)) {
|
||||
ht216->bg_latch[i] = svga->vram[dword_remap(svga, latch_addr + i)];
|
||||
return svga->vram[dword_remap(svga, 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 && (svga->crtc[0x17] != 0xeb)) {
|
||||
readplane = (readplane & 2) | (addr & 1);
|
||||
addr &= ~1;
|
||||
addr <<= 2;
|
||||
|
||||
@@ -47,6 +47,8 @@ typedef struct paradise_t
|
||||
WD90C30
|
||||
} type;
|
||||
|
||||
uint32_t vram_mask;
|
||||
|
||||
uint32_t read_bank[4], write_bank[4];
|
||||
} paradise_t;
|
||||
|
||||
@@ -112,17 +114,20 @@ void paradise_out(uint16_t addr, uint8_t val, void *p)
|
||||
paradise_remap(paradise);
|
||||
return;
|
||||
}
|
||||
if (svga->gdcaddr == 0x9 || svga->gdcaddr == 0xa)
|
||||
if (svga->gdcaddr == 0x9 || svga->gdcaddr == 0xa || svga->gdcaddr == 0xb)
|
||||
{
|
||||
svga->gdcreg[svga->gdcaddr] = val;
|
||||
paradise_remap(paradise);
|
||||
return;
|
||||
}
|
||||
if (svga->gdcaddr == 0xe)
|
||||
{
|
||||
if (svga->gdcaddr == 0xd) {
|
||||
svga->gdcreg[0xd] = val;
|
||||
svga_recalctimings(svga);
|
||||
return;
|
||||
}
|
||||
if (svga->gdcaddr == 0xe) {
|
||||
svga->gdcreg[0xe] = val;
|
||||
paradise_remap(paradise);
|
||||
svga_recalctimings(svga);
|
||||
svga_recalctimings(svga);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@@ -152,6 +157,13 @@ void paradise_out(uint16_t addr, uint8_t val, void *p)
|
||||
svga_recalctimings(¶dise->svga);
|
||||
}
|
||||
}
|
||||
|
||||
switch (svga->crtcreg) {
|
||||
case 0x2f:
|
||||
if (paradise->type != PVGA1A)
|
||||
svga->vram_display_mask = (val & 1) ? 0x3ffff : paradise->vram_mask;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
svga_out(addr, val, svga);
|
||||
@@ -219,8 +231,8 @@ void paradise_remap(paradise_t *paradise)
|
||||
paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0xa] & mask) << 12;
|
||||
paradise->write_bank[1] = paradise->write_bank[3] = ((svga->gdcreg[0xa] & mask) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
}
|
||||
else if (svga->gdcreg[0xe] & 0x08)
|
||||
{
|
||||
else if (svga->gdcreg[0xb] & 0x08)
|
||||
{
|
||||
if (svga->gdcreg[0x6] & 0xc)
|
||||
{
|
||||
paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0xa] & mask) << 12;
|
||||
@@ -243,19 +255,37 @@ void paradise_remap(paradise_t *paradise)
|
||||
paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0x9] & mask) << 12;
|
||||
paradise->write_bank[1] = paradise->write_bank[3] = ((svga->gdcreg[0x9] & mask) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000);
|
||||
}
|
||||
|
||||
if (paradise->type == WD90C11) {
|
||||
paradise->read_bank[1] &= 0x7ffff;
|
||||
paradise->write_bank[1] &= 0x7ffff;
|
||||
} else {
|
||||
paradise->read_bank[1] &= 0xfffff;
|
||||
paradise->write_bank[1] &= 0xfffff;
|
||||
}
|
||||
}
|
||||
|
||||
void paradise_recalctimings(svga_t *svga)
|
||||
{
|
||||
paradise_t *paradise = (paradise_t *) svga->p;
|
||||
|
||||
if (paradise->type == WD90C30)
|
||||
svga->interlace = (svga->crtc[0x2d] & 0x20);
|
||||
if (svga->gdcreg[0xd] & 0x08) svga->ma_latch |= 0x10000;
|
||||
if (svga->gdcreg[0xd] & 0x10) svga->ma_latch |= 0x20000;
|
||||
|
||||
if (svga->gdcreg[0xe] & 0x01) {
|
||||
svga->bpp = 8;
|
||||
svga->lowres = 0;
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
if (paradise->type == WD90C30) {
|
||||
if (svga->crtc[0x3d] & 0x01) svga->vtotal |= 0x400;
|
||||
if (svga->crtc[0x3d] & 0x02) svga->dispend |= 0x400;
|
||||
if (svga->crtc[0x3d] & 0x04) svga->vsyncstart |= 0x400;
|
||||
if (svga->crtc[0x3d] & 0x08) svga->vblankstart |= 0x400;
|
||||
if (svga->crtc[0x3d] & 0x10) svga->split |= 0x400;
|
||||
|
||||
svga->interlace = (svga->crtc[0x2d] & 0x20);
|
||||
}
|
||||
|
||||
svga->lowres = !(svga->gdcreg[0xe] & 0x01);
|
||||
|
||||
if (svga->bpp == 8 && !svga->lowres) {
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,7 +293,6 @@ static void paradise_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
paradise_t *paradise = (paradise_t *)p;
|
||||
addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3];
|
||||
|
||||
svga_write_linear(addr, val, ¶dise->svga);
|
||||
}
|
||||
static void paradise_writew(uint32_t addr, uint16_t val, void *p)
|
||||
@@ -306,6 +335,7 @@ void *paradise_init(const device_t *info, uint32_t memsize)
|
||||
paradise_in, paradise_out,
|
||||
NULL,
|
||||
NULL);
|
||||
paradise->vram_mask = memsize - 1;
|
||||
break;
|
||||
case WD90C11:
|
||||
svga_init(info, ¶dise->svga, paradise, 1 << 19, /*512kb*/
|
||||
@@ -313,6 +343,7 @@ void *paradise_init(const device_t *info, uint32_t memsize)
|
||||
paradise_in, paradise_out,
|
||||
NULL,
|
||||
NULL);
|
||||
paradise->vram_mask = (1 << 19) - 1;
|
||||
break;
|
||||
case WD90C30:
|
||||
svga_init(info, ¶dise->svga, paradise, memsize,
|
||||
@@ -320,11 +351,12 @@ void *paradise_init(const device_t *info, uint32_t memsize)
|
||||
paradise_in, paradise_out,
|
||||
NULL,
|
||||
NULL);
|
||||
paradise->vram_mask = memsize - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
mem_mapping_set_handler(¶dise->svga.mapping, paradise_read, paradise_readw, NULL, paradise_write, paradise_writew, NULL);
|
||||
mem_mapping_set_p(¶dise->svga.mapping, paradise);
|
||||
mem_mapping_set_handler(&svga->mapping, paradise_read, paradise_readw, NULL, paradise_write, paradise_writew, NULL);
|
||||
mem_mapping_set_p(&svga->mapping, paradise);
|
||||
|
||||
/* Common to all three types. */
|
||||
svga->crtc[0x31] = 'W';
|
||||
|
||||
@@ -353,6 +353,28 @@ static uint8_t s3_accel_in(uint16_t port, void *p);
|
||||
static uint8_t s3_pci_read(int func, int addr, void *p);
|
||||
static void s3_pci_write(int func, int addr, uint8_t val, void *p);
|
||||
|
||||
/*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);
|
||||
}
|
||||
static __inline uint32_t
|
||||
dword_remap_l(uint32_t in_addr)
|
||||
{
|
||||
return ((in_addr << 2) & 0xfffc) |
|
||||
((in_addr >> 14) & 0x3) |
|
||||
(in_addr & ~0xffff);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wake_fifo_thread(s3_t *s3)
|
||||
@@ -1635,8 +1657,10 @@ s3_hwcursor_draw(svga_t *svga, int displine)
|
||||
|
||||
for (x = 0; x < 64; x += 16)
|
||||
{
|
||||
dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 8) | svga->vram[svga->hwcursor_latch.addr + 1];
|
||||
dat[1] = (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3];
|
||||
uint32_t remapped_addr = dword_remap(svga->hwcursor_latch.addr);
|
||||
|
||||
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];
|
||||
if (svga->crtc[0x55] & 0x10) {
|
||||
/*X11*/
|
||||
for (xx = 0; xx < 16; xx++) {
|
||||
@@ -2240,6 +2264,7 @@ s3_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
case 0x31:
|
||||
s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4);
|
||||
svga->force_dword_mode = val & 0x08;
|
||||
break;
|
||||
case 0x32:
|
||||
if (svga->crtc[0x31] & 0x30)
|
||||
@@ -3698,9 +3723,9 @@ polygon_setup(s3_t *s3)
|
||||
}
|
||||
|
||||
|
||||
#define READ(addr, dat) if (s3->bpp == 0) dat = svga->vram[ (addr) & s3->vram_mask]; \
|
||||
else if (s3->bpp == 1) dat = vram_w[(addr) & (s3->vram_mask >> 1)]; \
|
||||
else dat = vram_l[(addr) & (s3->vram_mask >> 2)];
|
||||
#define READ(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)];
|
||||
|
||||
#define MIX_READ { \
|
||||
switch ((mix_dat & mix_mask) ? (s3->accel.frgd_mix & 0xf) : (s3->accel.bkgd_mix & 0xf)) \
|
||||
@@ -4005,18 +4030,18 @@ polygon_setup(s3_t *s3)
|
||||
|
||||
#define WRITE(addr, dat) if (s3->bpp == 0) \
|
||||
{ \
|
||||
svga->vram[(addr) & s3->vram_mask] = dat; \
|
||||
svga->changedvram[((addr) & s3->vram_mask) >> 12] = changeframecount; \
|
||||
svga->vram[dword_remap(addr) & s3->vram_mask] = dat; \
|
||||
svga->changedvram[(dword_remap(addr) & s3->vram_mask) >> 12] = changeframecount; \
|
||||
} \
|
||||
else if (s3->bpp == 1) \
|
||||
{ \
|
||||
vram_w[(addr) & (s3->vram_mask >> 1)] = dat; \
|
||||
svga->changedvram[((addr) & (s3->vram_mask >> 1)) >> 11] = changeframecount; \
|
||||
vram_w[dword_remap_w(addr) & (s3->vram_mask >> 1)] = dat; \
|
||||
svga->changedvram[(dword_remap_w(addr) & (s3->vram_mask >> 1)) >> 11] = changeframecount; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
vram_l[(addr) & (s3->vram_mask >> 2)] = dat; \
|
||||
svga->changedvram[((addr) & (s3->vram_mask >> 2)) >> 10] = changeframecount; \
|
||||
vram_l[dword_remap_l(addr) & (s3->vram_mask >> 2)] = dat; \
|
||||
svga->changedvram[(dword_remap_l(addr) & (s3->vram_mask >> 2)) >> 10] = changeframecount; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3886,6 +3886,8 @@ static void *s3_virge_init(const device_t *info)
|
||||
virge->i2c = i2c_gpio_init("ddc_s3_virge");
|
||||
virge->ddc = ddc_init(i2c_gpio_get_bus(virge->i2c));
|
||||
|
||||
virge->svga.packed_chain4 = 1;
|
||||
|
||||
return virge;
|
||||
}
|
||||
|
||||
|
||||
@@ -178,7 +178,7 @@ svga_out(uint16_t addr, uint8_t val, void *p)
|
||||
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->adv_flags & FLAG_ADDR_BY8);
|
||||
!svga->gdcreg[1]) && ((svga->chain4 && svga->packed_chain4) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -261,7 +261,7 @@ svga_out(uint16_t addr, uint8_t val, void *p)
|
||||
}
|
||||
svga->gdcreg[svga->gdcaddr & 15] = val;
|
||||
svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) &&
|
||||
!svga->gdcreg[1]) && svga->chain4;
|
||||
!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))
|
||||
svga_recalctimings(svga);
|
||||
@@ -575,7 +575,9 @@ svga_recalctimings(svga_t *svga)
|
||||
if (svga->dispontime < TIMER_USEC)
|
||||
svga->dispontime = TIMER_USEC;
|
||||
if (svga->dispofftime < TIMER_USEC)
|
||||
svga->dispofftime = TIMER_USEC;
|
||||
svga->dispofftime = TIMER_USEC;
|
||||
|
||||
svga_recalc_remap_func(svga);
|
||||
|
||||
/* Inform the user interface of any DPMS mode changes. */
|
||||
if (svga->dpms) {
|
||||
@@ -1058,9 +1060,14 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
|
||||
|
||||
if ((svga->adv_flags & FLAG_ADDR_BY8) && (svga->writemode < 4))
|
||||
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);
|
||||
addr &= ~3;
|
||||
} else if (svga->chain4 && (svga->writemode < 4)) {
|
||||
writemask2 = 1 << (addr & 3);
|
||||
if (!linear)
|
||||
addr &= ~3;
|
||||
addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff);
|
||||
} else if (svga->chain2_write) {
|
||||
writemask2 &= ~0xa;
|
||||
if (addr & 1)
|
||||
@@ -1239,7 +1246,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
|
||||
|
||||
if (svga->adv_flags & FLAG_ADDR_BY8)
|
||||
addr <<= 3;
|
||||
else if (svga->chain4 || svga->fb_only) {
|
||||
else if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) {
|
||||
addr &= svga->decode_mask;
|
||||
if (svga->translate_address)
|
||||
addr = svga->translate_address(addr, p);
|
||||
@@ -1249,6 +1256,9 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
|
||||
for (i = 0; i < count; i++)
|
||||
svga->latch.b[i] = svga->vram[latch_addr | i];
|
||||
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) {
|
||||
readplane = (readplane & 2) | (addr & 1);
|
||||
addr &= ~1;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -70,8 +70,6 @@
|
||||
#include "cpu.h"
|
||||
#include <86box/plat.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/i2c.h>
|
||||
#include <86box/vid_ddc.h>
|
||||
#include <86box/vid_svga.h>
|
||||
#include <86box/vid_svga_render.h>
|
||||
|
||||
@@ -107,45 +105,19 @@
|
||||
but the Windows 3.1 driver always reads bytes and write words of 0xffff.*/
|
||||
|
||||
#define ROM_TGUI_9400CXI "roms/video/tgui9440/9400CXI.vbi"
|
||||
#define ROM_TGUI_9440 "roms/video/tgui9440/9440.vbi"
|
||||
#define ROM_TGUI_9440 "roms/video/tgui9440/9440.VBI"
|
||||
|
||||
#define EXT_CTRL_16BIT 0x01
|
||||
#define EXT_CTRL_MONO_EXPANSION 0x02
|
||||
#define EXT_CTRL_MONO_TRANSPARENT 0x04
|
||||
#define EXT_CTRL_LATCH_COPY 0x08
|
||||
|
||||
#define FIFO_SIZE 65536
|
||||
#define FIFO_MASK (FIFO_SIZE - 1)
|
||||
#define FIFO_ENTRY_SIZE (1 << 31)
|
||||
|
||||
#define FIFO_ENTRIES (tgui->fifo_write_idx - tgui->fifo_read_idx)
|
||||
#define FIFO_FULL ((tgui->fifo_write_idx - tgui->fifo_read_idx) >= FIFO_SIZE)
|
||||
#define FIFO_EMPTY (tgui->fifo_read_idx == tgui->fifo_write_idx)
|
||||
|
||||
#define FIFO_TYPE 0xff000000
|
||||
#define FIFO_ADDR 0x00ffffff
|
||||
|
||||
enum
|
||||
{
|
||||
TGUI_9400CXI = 0,
|
||||
TGUI_9440
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
FIFO_INVALID = (0x00 << 24),
|
||||
FIFO_WRITE_BYTE = (0x01 << 24),
|
||||
FIFO_WRITE_FB_BYTE = (0x04 << 24),
|
||||
FIFO_WRITE_FB_WORD = (0x05 << 24),
|
||||
FIFO_WRITE_FB_LONG = (0x06 << 24)
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t addr_type;
|
||||
uint32_t val;
|
||||
} fifo_entry_t;
|
||||
|
||||
typedef struct tgui_t
|
||||
{
|
||||
mem_mapping_t linear_mapping;
|
||||
@@ -177,6 +149,7 @@ typedef struct tgui_t
|
||||
int use_src;
|
||||
|
||||
int pitch, bpp;
|
||||
int val_access;
|
||||
|
||||
uint16_t tgui_pattern[8][8];
|
||||
} accel;
|
||||
@@ -184,7 +157,7 @@ typedef struct tgui_t
|
||||
uint8_t ext_gdc_regs[16]; /*TGUI9400CXi only*/
|
||||
uint8_t copy_latch[16];
|
||||
|
||||
uint8_t tgui_3d8, tgui_3d9;
|
||||
uint8_t tgui_3d8, tgui_3d9, port3CD;
|
||||
int oldmode;
|
||||
uint8_t oldctrl1;
|
||||
uint8_t oldctrl2,newctrl2;
|
||||
@@ -197,21 +170,8 @@ typedef struct tgui_t
|
||||
int clock_m, clock_n, clock_k;
|
||||
|
||||
uint32_t vram_size, vram_mask;
|
||||
|
||||
fifo_entry_t fifo[FIFO_SIZE];
|
||||
volatile int fifo_read_idx, fifo_write_idx;
|
||||
|
||||
thread_t *fifo_thread;
|
||||
event_t *wake_fifo_thread;
|
||||
event_t *fifo_not_full_event;
|
||||
|
||||
int blitter_busy;
|
||||
uint64_t blitter_time;
|
||||
uint64_t status_time;
|
||||
|
||||
volatile int write_blitter;
|
||||
|
||||
void *i2c, *ddc;
|
||||
} tgui_t;
|
||||
|
||||
video_timings_t timing_tgui_vlb = {VIDEO_BUS, 4, 8, 16, 4, 8, 16};
|
||||
@@ -219,8 +179,6 @@ video_timings_t timing_tgui_pci = {VIDEO_PCI, 4, 8, 16, 4, 8, 16};
|
||||
|
||||
void tgui_recalcmapping(tgui_t *tgui);
|
||||
|
||||
static void fifo_thread(void *param);
|
||||
|
||||
uint8_t tgui_accel_read(uint32_t addr, void *priv);
|
||||
uint16_t tgui_accel_read_w(uint32_t addr, void *priv);
|
||||
uint32_t tgui_accel_read_l(uint32_t addr, void *priv);
|
||||
@@ -243,6 +201,23 @@ static void tgui_ext_write(uint32_t addr, uint8_t val, void *p);
|
||||
static void tgui_ext_writew(uint32_t addr, uint16_t val, void *p);
|
||||
static void tgui_ext_writel(uint32_t addr, uint32_t val, void *p);
|
||||
|
||||
|
||||
/*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_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
@@ -309,9 +284,11 @@ void tgui_out(uint16_t addr, uint8_t val, void *p)
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
}
|
||||
svga_recalctimings(svga);
|
||||
return;
|
||||
}
|
||||
/*FALLTHROUGH*/
|
||||
break;
|
||||
|
||||
case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
if (tgui->type == TGUI_9400CXI)
|
||||
{
|
||||
@@ -319,7 +296,7 @@ void tgui_out(uint16_t addr, uint8_t val, void *p)
|
||||
return;
|
||||
}
|
||||
tgui->ramdac_state = 0;
|
||||
break;
|
||||
break;
|
||||
|
||||
case 0x3CF:
|
||||
if (svga->gdcaddr == 0x23)
|
||||
@@ -384,16 +361,12 @@ void tgui_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
tgui->linear_base = ((val & 0xf) | ((val >> 2) & 0x30)) << 20;
|
||||
tgui->linear_size = (val & 0x10) ? 0x200000 : 0x100000;
|
||||
tgui->svga.decode_mask = (val & 0x10) ? 0x1fffff : 0xfffff;
|
||||
svga->decode_mask = (val & 0x10) ? 0x1fffff : 0xfffff;
|
||||
}
|
||||
tgui_recalcmapping(tgui);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x37:
|
||||
i2c_gpio_set(tgui->i2c, (val & 0x02) || !(val & 0x04), (val & 0x01) || !(val & 0x08));
|
||||
break;
|
||||
|
||||
case 0x40: case 0x41: case 0x42: case 0x43:
|
||||
case 0x44: case 0x45: case 0x46: case 0x47:
|
||||
if (tgui->type >= TGUI_9440)
|
||||
@@ -462,7 +435,7 @@ uint8_t tgui_in(uint16_t addr, void *p)
|
||||
case TGUI_9400CXI:
|
||||
return 0x93; /*TGUI9400CXi*/
|
||||
case TGUI_9440:
|
||||
return 0xe3; /*TGUI9440AGi*/
|
||||
return 0xa3; /*TGUI9440AGi*/
|
||||
}
|
||||
}
|
||||
if ((svga->seqaddr & 0xf) == 0xd)
|
||||
@@ -479,16 +452,19 @@ uint8_t tgui_in(uint16_t addr, void *p)
|
||||
break;
|
||||
case 0x3C6:
|
||||
if (tgui->type == TGUI_9400CXI)
|
||||
return tkd8001_ramdac_in(addr, svga->ramdac, svga);
|
||||
return tkd8001_ramdac_in(addr, svga->ramdac, svga);
|
||||
if (tgui->ramdac_state == 4)
|
||||
return tgui->ramdac_ctrl;
|
||||
tgui->ramdac_state++;
|
||||
return tgui->ramdac_ctrl;
|
||||
tgui->ramdac_state++;
|
||||
break;
|
||||
case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
if (tgui->type == TGUI_9400CXI)
|
||||
return tkd8001_ramdac_in(addr, svga->ramdac, svga);
|
||||
tgui->ramdac_state = 0;
|
||||
break;
|
||||
case 0x3CD:
|
||||
return tgui->port3CD;
|
||||
|
||||
case 0x3CF:
|
||||
if (tgui->type == TGUI_9400CXI && svga->gdcaddr >= 16 && svga->gdcaddr < 32)
|
||||
return tgui->ext_gdc_regs[svga->gdcaddr & 15];
|
||||
@@ -497,18 +473,6 @@ uint8_t tgui_in(uint16_t addr, void *p)
|
||||
return svga->crtcreg;
|
||||
case 0x3D5:
|
||||
temp = svga->crtc[svga->crtcreg];
|
||||
if (svga->crtcreg == 0x37) {
|
||||
if (!(svga->crtc[0x37] & 0x04)) {
|
||||
temp &= 0xfd;
|
||||
if (i2c_gpio_get_scl(tgui->i2c))
|
||||
temp |= 0x02;
|
||||
}
|
||||
if (!(svga->crtc[0x37] & 0x08)) {
|
||||
temp &= 0xfe;
|
||||
if (i2c_gpio_get_sda(tgui->i2c))
|
||||
temp |= 0x01;
|
||||
}
|
||||
}
|
||||
return temp;
|
||||
case 0x3d8:
|
||||
return tgui->tgui_3d8;
|
||||
@@ -647,6 +611,7 @@ void tgui_recalcmapping(tgui_t *tgui)
|
||||
if (svga->crtc[0x21] & 0x20)
|
||||
{
|
||||
mem_mapping_disable(&svga->mapping);
|
||||
pclog("Linear size = %08x, linear base = %08x\n", tgui->linear_size, tgui->linear_base);
|
||||
mem_mapping_set_addr(&tgui->linear_mapping, tgui->linear_base, tgui->linear_size);
|
||||
if (tgui->type >= TGUI_9440)
|
||||
{
|
||||
@@ -688,7 +653,7 @@ void tgui_recalcmapping(tgui_t *tgui)
|
||||
break;
|
||||
case 0x4: /*64k at A0000*/
|
||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
||||
mem_mapping_enable(&tgui->accel_mapping);
|
||||
mem_mapping_enable(&tgui->accel_mapping);
|
||||
svga->banked_mask = 0xffff;
|
||||
break;
|
||||
case 0x8: /*32k at B0000*/
|
||||
@@ -711,12 +676,15 @@ void tgui_hwcursor_draw(svga_t *svga, int displine)
|
||||
int pitch = (svga->hwcursor.xsize == 64) ? 16 : 8;
|
||||
int byte, bit;
|
||||
uint32_t color;
|
||||
uint32_t remapped_addr;
|
||||
|
||||
if (svga->interlace && svga->hwcursor_oddeven)
|
||||
svga->hwcursor_latch.addr += pitch;
|
||||
svga->hwcursor_latch.addr += pitch;
|
||||
|
||||
remapped_addr = dword_remap(svga->hwcursor_latch.addr);
|
||||
|
||||
for (xx = 0; xx < svga->hwcursor.xsize; xx++) {
|
||||
byte = svga->hwcursor_latch.addr + (xx >> 3);
|
||||
byte = remapped_addr + (xx >> 3);
|
||||
bit = (7 - (xx & 7));
|
||||
dat[0] = (svga->vram[byte] >> bit) & 0x01; /* AND */
|
||||
dat[1] = (svga->vram[(pitch >> 1) + byte] >> bit) & 0x01; /* XOR */
|
||||
@@ -805,14 +773,14 @@ void tgui_pci_write(int func, int addr, uint8_t val, void *p)
|
||||
case 0x12:
|
||||
tgui->linear_base = (tgui->linear_base & 0xff000000) | ((val & 0xe0) << 16);
|
||||
tgui->linear_size = 2 << 20;
|
||||
tgui->svga.decode_mask = 0x1fffff;
|
||||
svga->decode_mask = 0x1fffff;
|
||||
svga->crtc[0x21] = (svga->crtc[0x21] & ~0xf) | (val >> 4);
|
||||
tgui_recalcmapping(tgui);
|
||||
break;
|
||||
case 0x13:
|
||||
tgui->linear_base = (tgui->linear_base & 0xe00000) | (val << 24);
|
||||
tgui->linear_size = 2 << 20;
|
||||
tgui->svga.decode_mask = 0x1fffff;
|
||||
svga->decode_mask = 0x1fffff;
|
||||
svga->crtc[0x21] = (svga->crtc[0x21] & ~0xc0) | (val >> 6);
|
||||
tgui_recalcmapping(tgui);
|
||||
break;
|
||||
@@ -832,9 +800,13 @@ static uint8_t tgui_ext_linear_read(uint32_t addr, void *p)
|
||||
return 0xff;
|
||||
|
||||
addr &= ~0xf;
|
||||
for (c = 0; c < 16; c++)
|
||||
tgui->copy_latch[c] = svga->vram[addr+c];
|
||||
addr = dword_remap(addr);
|
||||
|
||||
for (c = 0; c < 16; c++) {
|
||||
tgui->copy_latch[c] = svga->vram[addr+c];
|
||||
addr += ((c & 3) == 3) ? 13 : 1;
|
||||
}
|
||||
|
||||
return svga->vram[addr & svga->vram_mask];
|
||||
}
|
||||
|
||||
@@ -862,7 +834,9 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p)
|
||||
if (addr >= svga->vram_max)
|
||||
return;
|
||||
addr &= svga->vram_mask;
|
||||
addr &= ~0x7;
|
||||
addr &= (tgui->ext_gdc_regs[0] & 8) ? ~0xf : ~0x7;
|
||||
|
||||
addr = dword_remap(addr);
|
||||
svga->changedvram[addr >> 12] = changeframecount;
|
||||
|
||||
switch (tgui->ext_gdc_regs[0] & 0xf)
|
||||
@@ -873,7 +847,7 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
if (mask & (1 << c))
|
||||
*(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0];
|
||||
addr++;
|
||||
addr += (c == 4) ? 13 : 1;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -883,7 +857,7 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
if (mask & (1 << c))
|
||||
*(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1];
|
||||
addr++;
|
||||
addr += (c == 4) ? 13 : 1;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -893,7 +867,7 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
if ((val & mask) & (1 << c))
|
||||
*(uint8_t *)&svga->vram[addr] = fg[0];
|
||||
addr++;
|
||||
addr += (c == 4) ? 13 : 1;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -903,15 +877,16 @@ static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
if ((val & mask) & (1 << c))
|
||||
*(uint8_t *)&svga->vram[addr] = fg[(c & 1) ^ 1];
|
||||
addr++;
|
||||
addr += (c == 4) ? 13 : 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8: case 0x9: case 0xa: case 0xb:
|
||||
case 0xc: case 0xd: case 0xe: case 0xf:
|
||||
addr &= ~0xf;
|
||||
for (c = 0; c < 16; c++)
|
||||
*(uint8_t *)&svga->vram[addr+c] = tgui->copy_latch[c];
|
||||
for (c = 0; c < 16; c++) {
|
||||
*(uint8_t *)&svga->vram[addr] = tgui->copy_latch[c];
|
||||
addr += ((c & 3) == 3) ? 13 : 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -932,6 +907,8 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p)
|
||||
return;
|
||||
addr &= svga->vram_mask;
|
||||
addr &= ~0xf;
|
||||
|
||||
addr = dword_remap(addr);
|
||||
svga->changedvram[addr >> 12] = changeframecount;
|
||||
|
||||
val = (val >> 8) | (val << 8);
|
||||
@@ -944,7 +921,7 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p)
|
||||
{
|
||||
if (mask & (1 << c))
|
||||
*(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0];
|
||||
addr++;
|
||||
addr += (c & 3) ? 1 : 13;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -954,7 +931,7 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p)
|
||||
{
|
||||
if (mask & (1 << c))
|
||||
*(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1];
|
||||
addr++;
|
||||
addr += (c & 3) ? 1 : 13;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -964,7 +941,7 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p)
|
||||
{
|
||||
if ((val & mask) & (1 << c))
|
||||
*(uint8_t *)&svga->vram[addr] = fg[0];
|
||||
addr++;
|
||||
addr += (c & 3) ? 1 : 13;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -974,14 +951,16 @@ static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p)
|
||||
{
|
||||
if ((val & mask) & (1 << c))
|
||||
*(uint8_t *)&svga->vram[addr] = fg[(c & 1) ^ 1];
|
||||
addr++;
|
||||
addr += (c & 3) ? 1 : 13;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8: case 0x9: case 0xa: case 0xb:
|
||||
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];
|
||||
addr += ((c & 3) == 3) ? 13 : 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1034,8 +1013,8 @@ enum
|
||||
TGUI_SOLIDFILL = 0x4000 /*Pattern all zero?*/
|
||||
};
|
||||
|
||||
#define READ(addr, dat) if (tgui->accel.bpp == 0) dat = svga->vram[addr & 0x1fffff]; \
|
||||
else dat = vram_w[addr & 0xfffff];
|
||||
#define READ(addr, dat) if (tgui->accel.bpp == 0) dat = svga->vram[dword_remap(addr) & tgui->vram_mask]; \
|
||||
else dat = vram_w[dword_remap_w(addr) & (tgui->vram_mask >> 1)];
|
||||
|
||||
#define MIX() do \
|
||||
{ \
|
||||
@@ -1051,13 +1030,13 @@ enum
|
||||
|
||||
#define WRITE(addr, dat) if (tgui->accel.bpp == 0) \
|
||||
{ \
|
||||
svga->vram[addr & 0x1fffff] = dat; \
|
||||
svga->changedvram[((addr) & 0x1fffff) >> 12] = changeframecount; \
|
||||
svga->vram[dword_remap(addr) & tgui->vram_mask] = dat; \
|
||||
svga->changedvram[(dword_remap(addr) & tgui->vram_mask) >> 12] = changeframecount; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
vram_w[addr & 0xfffff] = dat; \
|
||||
svga->changedvram[((addr) & 0xfffff) >> 11] = changeframecount; \
|
||||
vram_w[dword_remap_w(addr) & (tgui->vram_mask >> 1)] = dat; \
|
||||
svga->changedvram[(dword_remap_w(addr) & (tgui->vram_mask >> 1)) >> 11] = changeframecount; \
|
||||
}
|
||||
|
||||
void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
||||
@@ -1127,6 +1106,8 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pclog("Accel command = %i\n", tgui->accel.command);
|
||||
switch (tgui->accel.command)
|
||||
{
|
||||
case TGUI_BITBLT:
|
||||
@@ -1137,7 +1118,7 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
||||
tgui->accel.pat_x = tgui->accel.dst_x;
|
||||
tgui->accel.pat_y = tgui->accel.dst_y;
|
||||
}
|
||||
|
||||
|
||||
switch (tgui->accel.flags & (TGUI_SRCMONO|TGUI_SRCDISP))
|
||||
{
|
||||
case TGUI_SRCCPU:
|
||||
@@ -1149,19 +1130,19 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
||||
}
|
||||
if (tgui->accel.use_src)
|
||||
return;
|
||||
} else {
|
||||
count >>= 3;
|
||||
}
|
||||
else
|
||||
count >>= 3;
|
||||
while (count)
|
||||
{
|
||||
if (tgui->accel.bpp == 0)
|
||||
{
|
||||
src_dat = cpu_dat >> 24;
|
||||
src_dat = cpu_dat >> 24;
|
||||
cpu_dat <<= 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0xff00);
|
||||
src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0xff00);
|
||||
cpu_dat <<= 16;
|
||||
count--;
|
||||
}
|
||||
@@ -1215,7 +1196,7 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
||||
if (tgui->accel.use_src)
|
||||
return;
|
||||
}
|
||||
while (count)
|
||||
while (count--)
|
||||
{
|
||||
src_dat = ((cpu_dat >> 31) ? tgui->accel.fg_col : tgui->accel.bg_col);
|
||||
if (tgui->accel.bpp == 0)
|
||||
@@ -1258,12 +1239,11 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
||||
if (tgui->accel.use_src)
|
||||
return;
|
||||
}
|
||||
count--;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
while (count)
|
||||
while (count--)
|
||||
{
|
||||
READ(tgui->accel.src, src_dat);
|
||||
READ(tgui->accel.dst, dst_dat);
|
||||
@@ -1295,7 +1275,6 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
||||
if (tgui->accel.y > tgui->accel.size_y)
|
||||
return;
|
||||
}
|
||||
count--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1303,16 +1282,268 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui)
|
||||
}
|
||||
}
|
||||
|
||||
static void tgui_accel_write_fifo(tgui_t *tgui, uint32_t addr, uint8_t val)
|
||||
void tgui_accel_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x2122:
|
||||
tgui->accel.ger22 = val;
|
||||
tgui->accel.pitch = 512 << ((val >> 2) & 3);
|
||||
tgui->accel.bpp = (val & 3) ? 1 : 0;
|
||||
tgui->accel.pitch >>= tgui->accel.bpp;
|
||||
break;
|
||||
|
||||
case 0x2124: /*Command*/
|
||||
tgui->accel.command = val;
|
||||
tgui_accel_command(-1, 0, tgui);
|
||||
break;
|
||||
|
||||
case 0x2127: /*ROP*/
|
||||
tgui->accel.rop = val;
|
||||
tgui->accel.use_src = (val & 0x33) ^ ((val >> 2) & 0x33);
|
||||
break;
|
||||
|
||||
case 0x2128: /*Flags*/
|
||||
tgui->accel.flags = (tgui->accel.flags & 0xff00) | val;
|
||||
break;
|
||||
case 0x2129: /*Flags*/
|
||||
tgui->accel.flags = (tgui->accel.flags & 0xff) | (val << 8);
|
||||
break;
|
||||
|
||||
case 0x212b:
|
||||
tgui->accel.offset = val & 7;
|
||||
break;
|
||||
|
||||
case 0x212c: /*Foreground colour*/
|
||||
tgui->accel.fg_col = (tgui->accel.fg_col & 0xff00) | val;
|
||||
break;
|
||||
case 0x212d: /*Foreground colour*/
|
||||
tgui->accel.fg_col = (tgui->accel.fg_col & 0xff) | (val << 8);
|
||||
break;
|
||||
|
||||
case 0x2130: /*Background colour*/
|
||||
tgui->accel.bg_col = (tgui->accel.bg_col & 0xff00) | val;
|
||||
break;
|
||||
case 0x2131: /*Background colour*/
|
||||
tgui->accel.bg_col = (tgui->accel.bg_col & 0xff) | (val << 8);
|
||||
break;
|
||||
|
||||
case 0x2138: /*Dest X*/
|
||||
tgui->accel.dst_x = (tgui->accel.dst_x & 0xff00) | val;
|
||||
break;
|
||||
case 0x2139: /*Dest X*/
|
||||
tgui->accel.dst_x = (tgui->accel.dst_x & 0xff) | (val << 8);
|
||||
break;
|
||||
case 0x213a: /*Dest Y*/
|
||||
tgui->accel.dst_y = (tgui->accel.dst_y & 0xff00) | val;
|
||||
break;
|
||||
case 0x213b: /*Dest Y*/
|
||||
tgui->accel.dst_y = (tgui->accel.dst_y & 0xff) | (val << 8);
|
||||
break;
|
||||
|
||||
case 0x213c: /*Src X*/
|
||||
tgui->accel.src_x = (tgui->accel.src_x & 0xff00) | val;
|
||||
break;
|
||||
case 0x213d: /*Src X*/
|
||||
tgui->accel.src_x = (tgui->accel.src_x & 0xff) | (val << 8);
|
||||
break;
|
||||
case 0x213e: /*Src Y*/
|
||||
tgui->accel.src_y = (tgui->accel.src_y & 0xff00) | val;
|
||||
break;
|
||||
case 0x213f: /*Src Y*/
|
||||
tgui->accel.src_y = (tgui->accel.src_y & 0xff) | (val << 8);
|
||||
break;
|
||||
|
||||
case 0x2140: /*Size X*/
|
||||
tgui->accel.size_x = (tgui->accel.size_x & 0xff00) | val;
|
||||
break;
|
||||
case 0x2141: /*Size X*/
|
||||
tgui->accel.size_x = (tgui->accel.size_x & 0xff) | (val << 8);
|
||||
break;
|
||||
case 0x2142: /*Size Y*/
|
||||
tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val;
|
||||
break;
|
||||
case 0x2143: /*Size Y*/
|
||||
tgui->accel.size_y = (tgui->accel.size_y & 0xff) | (val << 8);
|
||||
break;
|
||||
|
||||
case 0x2180: case 0x2181: case 0x2182: case 0x2183:
|
||||
case 0x2184: case 0x2185: case 0x2186: case 0x2187:
|
||||
case 0x2188: case 0x2189: case 0x218a: case 0x218b:
|
||||
case 0x218c: case 0x218d: case 0x218e: case 0x218f:
|
||||
case 0x2190: case 0x2191: case 0x2192: case 0x2193:
|
||||
case 0x2194: case 0x2195: case 0x2196: case 0x2197:
|
||||
case 0x2198: case 0x2199: case 0x219a: case 0x219b:
|
||||
case 0x219c: case 0x219d: case 0x219e: case 0x219f:
|
||||
case 0x21a0: case 0x21a1: case 0x21a2: case 0x21a3:
|
||||
case 0x21a4: case 0x21a5: case 0x21a6: case 0x21a7:
|
||||
case 0x21a8: case 0x21a9: case 0x21aa: case 0x21ab:
|
||||
case 0x21ac: case 0x21ad: case 0x21ae: case 0x21af:
|
||||
case 0x21b0: case 0x21b1: case 0x21b2: case 0x21b3:
|
||||
case 0x21b4: case 0x21b5: case 0x21b6: case 0x21b7:
|
||||
case 0x21b8: case 0x21b9: case 0x21ba: case 0x21bb:
|
||||
case 0x21bc: case 0x21bd: case 0x21be: case 0x21bf:
|
||||
case 0x21c0: case 0x21c1: case 0x21c2: case 0x21c3:
|
||||
case 0x21c4: case 0x21c5: case 0x21c6: case 0x21c7:
|
||||
case 0x21c8: case 0x21c9: case 0x21ca: case 0x21cb:
|
||||
case 0x21cc: case 0x21cd: case 0x21ce: case 0x21cf:
|
||||
case 0x21d0: case 0x21d1: case 0x21d2: case 0x21d3:
|
||||
case 0x21d4: case 0x21d5: case 0x21d6: case 0x21d7:
|
||||
case 0x21d8: case 0x21d9: case 0x21da: case 0x21db:
|
||||
case 0x21dc: case 0x21dd: case 0x21de: case 0x21df:
|
||||
case 0x21e0: case 0x21e1: case 0x21e2: case 0x21e3:
|
||||
case 0x21e4: case 0x21e5: case 0x21e6: case 0x21e7:
|
||||
case 0x21e8: case 0x21e9: case 0x21ea: case 0x21eb:
|
||||
case 0x21ec: case 0x21ed: case 0x21ee: case 0x21ef:
|
||||
case 0x21f0: case 0x21f1: case 0x21f2: case 0x21f3:
|
||||
case 0x21f4: case 0x21f5: case 0x21f6: case 0x21f7:
|
||||
case 0x21f8: case 0x21f9: case 0x21fa: case 0x21fb:
|
||||
case 0x21fc: case 0x21fd: case 0x21fe: case 0x21ff:
|
||||
tgui->accel.pattern[addr & 0x7f] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void tgui_accel_out_w(uint16_t addr, uint16_t val, void *p)
|
||||
{
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
tgui_accel_out(addr, val, tgui);
|
||||
tgui_accel_out(addr + 1, val >> 8, tgui);
|
||||
}
|
||||
|
||||
void tgui_accel_out_l(uint16_t addr, uint32_t val, void *p)
|
||||
{
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
tgui_accel_out(addr, val, tgui);
|
||||
tgui_accel_out(addr + 1, val >> 8, tgui);
|
||||
tgui_accel_out(addr + 2, val >> 16, tgui);
|
||||
tgui_accel_out(addr + 3, val >> 24, tgui);
|
||||
}
|
||||
|
||||
uint8_t tgui_accel_in(uint16_t addr, void *p)
|
||||
{
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x2120: /*Status*/
|
||||
return 0;
|
||||
|
||||
case 0x2127: /*ROP*/
|
||||
return tgui->accel.rop;
|
||||
|
||||
case 0x2128: /*Flags*/
|
||||
return tgui->accel.flags & 0xff;
|
||||
case 0x2129: /*Flags*/
|
||||
return tgui->accel.flags >> 8;
|
||||
|
||||
case 0x212b:
|
||||
return tgui->accel.offset;
|
||||
|
||||
case 0x212c: /*Background colour*/
|
||||
return tgui->accel.bg_col & 0xff;
|
||||
case 0x212d: /*Background colour*/
|
||||
return tgui->accel.bg_col >> 8;
|
||||
|
||||
case 0x2130: /*Foreground colour*/
|
||||
return tgui->accel.fg_col & 0xff;
|
||||
case 0x2131: /*Foreground colour*/
|
||||
return tgui->accel.fg_col >> 8;
|
||||
|
||||
case 0x2138: /*Dest X*/
|
||||
return tgui->accel.dst_x & 0xff;
|
||||
case 0x2139: /*Dest X*/
|
||||
return tgui->accel.dst_x >> 8;
|
||||
case 0x213a: /*Dest Y*/
|
||||
return tgui->accel.dst_y & 0xff;
|
||||
case 0x213b: /*Dest Y*/
|
||||
return tgui->accel.dst_y >> 8;
|
||||
|
||||
case 0x213c: /*Src X*/
|
||||
return tgui->accel.src_x & 0xff;
|
||||
case 0x213d: /*Src X*/
|
||||
return tgui->accel.src_x >> 8;
|
||||
case 0x213e: /*Src Y*/
|
||||
return tgui->accel.src_y & 0xff;
|
||||
case 0x213f: /*Src Y*/
|
||||
return tgui->accel.src_y >> 8;
|
||||
|
||||
case 0x2140: /*Size X*/
|
||||
return tgui->accel.size_x & 0xff;
|
||||
case 0x2141: /*Size X*/
|
||||
return tgui->accel.size_x >> 8;
|
||||
case 0x2142: /*Size Y*/
|
||||
return tgui->accel.size_y & 0xff;
|
||||
case 0x2143: /*Size Y*/
|
||||
return tgui->accel.size_y >> 8;
|
||||
|
||||
case 0x2180: case 0x2181: case 0x2182: case 0x2183:
|
||||
case 0x2184: case 0x2185: case 0x2186: case 0x2187:
|
||||
case 0x2188: case 0x2189: case 0x218a: case 0x218b:
|
||||
case 0x218c: case 0x218d: case 0x218e: case 0x218f:
|
||||
case 0x2190: case 0x2191: case 0x2192: case 0x2193:
|
||||
case 0x2194: case 0x2195: case 0x2196: case 0x2197:
|
||||
case 0x2198: case 0x2199: case 0x219a: case 0x219b:
|
||||
case 0x219c: case 0x219d: case 0x219e: case 0x219f:
|
||||
case 0x21a0: case 0x21a1: case 0x21a2: case 0x21a3:
|
||||
case 0x21a4: case 0x21a5: case 0x21a6: case 0x21a7:
|
||||
case 0x21a8: case 0x21a9: case 0x21aa: case 0x21ab:
|
||||
case 0x21ac: case 0x21ad: case 0x21ae: case 0x21af:
|
||||
case 0x21b0: case 0x21b1: case 0x21b2: case 0x21b3:
|
||||
case 0x21b4: case 0x21b5: case 0x21b6: case 0x21b7:
|
||||
case 0x21b8: case 0x21b9: case 0x21ba: case 0x21bb:
|
||||
case 0x21bc: case 0x21bd: case 0x21be: case 0x21bf:
|
||||
case 0x21c0: case 0x21c1: case 0x21c2: case 0x21c3:
|
||||
case 0x21c4: case 0x21c5: case 0x21c6: case 0x21c7:
|
||||
case 0x21c8: case 0x21c9: case 0x21ca: case 0x21cb:
|
||||
case 0x21cc: case 0x21cd: case 0x21ce: case 0x21cf:
|
||||
case 0x21d0: case 0x21d1: case 0x21d2: case 0x21d3:
|
||||
case 0x21d4: case 0x21d5: case 0x21d6: case 0x21d7:
|
||||
case 0x21d8: case 0x21d9: case 0x21da: case 0x21db:
|
||||
case 0x21dc: case 0x21dd: case 0x21de: case 0x21df:
|
||||
case 0x21e0: case 0x21e1: case 0x21e2: case 0x21e3:
|
||||
case 0x21e4: case 0x21e5: case 0x21e6: case 0x21e7:
|
||||
case 0x21e8: case 0x21e9: case 0x21ea: case 0x21eb:
|
||||
case 0x21ec: case 0x21ed: case 0x21ee: case 0x21ef:
|
||||
case 0x21f0: case 0x21f1: case 0x21f2: case 0x21f3:
|
||||
case 0x21f4: case 0x21f5: case 0x21f6: case 0x21f7:
|
||||
case 0x21f8: case 0x21f9: case 0x21fa: case 0x21fb:
|
||||
case 0x21fc: case 0x21fd: case 0x21fe: case 0x21ff:
|
||||
return tgui->accel.pattern[addr & 0x7f];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t tgui_accel_in_w(uint16_t addr, void *p)
|
||||
{
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
return tgui_accel_in(addr, tgui) | (tgui_accel_in(addr + 1, tgui) << 8);
|
||||
}
|
||||
|
||||
uint32_t tgui_accel_in_l(uint16_t addr, void *p)
|
||||
{
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
return tgui_accel_in_w(addr, tgui) | (tgui_accel_in_w(addr + 2, tgui) << 16);
|
||||
}
|
||||
|
||||
|
||||
void tgui_accel_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
|
||||
if ((addr & ~0xff) != 0xbff00)
|
||||
return;
|
||||
|
||||
switch (addr & 0xff)
|
||||
{
|
||||
case 0x22:
|
||||
tgui->accel.ger22 = val;
|
||||
tgui->accel.pitch = 512 << ((val >> 2) & 3);
|
||||
tgui->accel.bpp = (val & 3) ? 1 : 0;
|
||||
tgui->accel.pitch >>= tgui->accel.bpp;
|
||||
break;
|
||||
case 0x22:
|
||||
tgui->accel.ger22 = val;
|
||||
tgui->accel.pitch = 512 << ((val >> 2) & 3);
|
||||
tgui->accel.bpp = (val & 3) ? 1 : 0;
|
||||
tgui->accel.pitch >>= tgui->accel.bpp;
|
||||
break;
|
||||
|
||||
case 0x24: /*Command*/
|
||||
tgui->accel.command = val;
|
||||
@@ -1425,109 +1656,6 @@ static void tgui_accel_write_fifo(tgui_t *tgui, uint32_t addr, uint8_t val)
|
||||
}
|
||||
}
|
||||
|
||||
static void tgui_accel_write_fifo_fb_b(tgui_t *tgui, uint32_t addr, uint8_t val)
|
||||
{
|
||||
tgui_accel_command(8, val << 24, tgui);
|
||||
}
|
||||
static void tgui_accel_write_fifo_fb_w(tgui_t *tgui, uint32_t addr, uint16_t val)
|
||||
{
|
||||
tgui_accel_command(16, (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)) << 16, tgui);
|
||||
}
|
||||
static void tgui_accel_write_fifo_fb_l(tgui_t *tgui, uint32_t addr, uint32_t val)
|
||||
{
|
||||
tgui_accel_command(32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), tgui);
|
||||
}
|
||||
|
||||
static void fifo_thread(void *param)
|
||||
{
|
||||
tgui_t *tgui = (tgui_t *)param;
|
||||
|
||||
while (1)
|
||||
{
|
||||
thread_set_event(tgui->fifo_not_full_event);
|
||||
thread_wait_event(tgui->wake_fifo_thread, -1);
|
||||
thread_reset_event(tgui->wake_fifo_thread);
|
||||
tgui->blitter_busy = 1;
|
||||
while (!FIFO_EMPTY)
|
||||
{
|
||||
uint64_t start_time = plat_timer_read();
|
||||
uint64_t end_time;
|
||||
fifo_entry_t *fifo = &tgui->fifo[tgui->fifo_read_idx & FIFO_MASK];
|
||||
|
||||
switch (fifo->addr_type & FIFO_TYPE)
|
||||
{
|
||||
case FIFO_WRITE_BYTE:
|
||||
tgui_accel_write_fifo(tgui, fifo->addr_type & FIFO_ADDR, fifo->val);
|
||||
break;
|
||||
case FIFO_WRITE_FB_BYTE:
|
||||
tgui_accel_write_fifo_fb_b(tgui, fifo->addr_type & FIFO_ADDR, fifo->val);
|
||||
break;
|
||||
case FIFO_WRITE_FB_WORD:
|
||||
tgui_accel_write_fifo_fb_w(tgui, fifo->addr_type & FIFO_ADDR, fifo->val);
|
||||
break;
|
||||
case FIFO_WRITE_FB_LONG:
|
||||
tgui_accel_write_fifo_fb_l(tgui, fifo->addr_type & FIFO_ADDR, fifo->val);
|
||||
break;
|
||||
}
|
||||
|
||||
tgui->fifo_read_idx++;
|
||||
fifo->addr_type = FIFO_INVALID;
|
||||
|
||||
if (FIFO_ENTRIES > 0xe000)
|
||||
thread_set_event(tgui->fifo_not_full_event);
|
||||
|
||||
end_time = plat_timer_read();
|
||||
tgui->blitter_time += end_time - start_time;
|
||||
}
|
||||
tgui->blitter_busy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void wake_fifo_thread(tgui_t *tgui)
|
||||
{
|
||||
thread_set_event(tgui->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/
|
||||
}
|
||||
|
||||
static void tgui_wait_fifo_idle(tgui_t *tgui)
|
||||
{
|
||||
while (!FIFO_EMPTY)
|
||||
{
|
||||
wake_fifo_thread(tgui);
|
||||
thread_wait_event(tgui->fifo_not_full_event, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void tgui_queue(tgui_t *tgui, uint32_t addr, uint32_t val, uint32_t type)
|
||||
{
|
||||
fifo_entry_t *fifo = &tgui->fifo[tgui->fifo_write_idx & FIFO_MASK];
|
||||
|
||||
if (FIFO_FULL)
|
||||
{
|
||||
thread_reset_event(tgui->fifo_not_full_event);
|
||||
if (FIFO_FULL)
|
||||
{
|
||||
thread_wait_event(tgui->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/
|
||||
}
|
||||
}
|
||||
|
||||
fifo->val = val;
|
||||
fifo->addr_type = (addr & FIFO_ADDR) | type;
|
||||
|
||||
tgui->fifo_write_idx++;
|
||||
|
||||
if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8)
|
||||
wake_fifo_thread(tgui);
|
||||
}
|
||||
|
||||
|
||||
void tgui_accel_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
if ((addr & ~0xff) != 0xbff00)
|
||||
return;
|
||||
tgui_queue(tgui, addr, val, FIFO_WRITE_BYTE);
|
||||
}
|
||||
|
||||
void tgui_accel_write_w(uint32_t addr, uint16_t val, void *p)
|
||||
{
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
@@ -1549,13 +1677,9 @@ uint8_t tgui_accel_read(uint32_t addr, void *p)
|
||||
tgui_t *tgui = (tgui_t *)p;
|
||||
if ((addr & ~0xff) != 0xbff00)
|
||||
return 0xff;
|
||||
if ((addr & 0xff) != 0x20)
|
||||
tgui_wait_fifo_idle(tgui);
|
||||
switch (addr & 0xff)
|
||||
{
|
||||
case 0x20: /*Status*/
|
||||
if (!FIFO_EMPTY)
|
||||
return 1 << 5;
|
||||
return 0;
|
||||
|
||||
case 0x27: /*ROP*/
|
||||
@@ -1661,9 +1785,9 @@ void tgui_accel_write_fb_b(uint32_t addr, uint8_t val, void *p)
|
||||
tgui_t *tgui = (tgui_t *)svga->p;
|
||||
|
||||
if (tgui->write_blitter)
|
||||
tgui_queue(tgui, addr, val, FIFO_WRITE_FB_BYTE);
|
||||
tgui_accel_command(8, val << 24, tgui);
|
||||
else
|
||||
svga_write_linear(addr, val, svga);
|
||||
svga_write_linear(addr, val, svga);
|
||||
}
|
||||
|
||||
void tgui_accel_write_fb_w(uint32_t addr, uint16_t val, void *p)
|
||||
@@ -1672,9 +1796,9 @@ void tgui_accel_write_fb_w(uint32_t addr, uint16_t val, void *p)
|
||||
tgui_t *tgui = (tgui_t *)svga->p;
|
||||
|
||||
if (tgui->write_blitter)
|
||||
tgui_queue(tgui, addr, val, FIFO_WRITE_FB_WORD);
|
||||
tgui_accel_command(16, (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)) << 16, tgui);
|
||||
else
|
||||
svga_writew_linear(addr, val, svga);
|
||||
svga_writew_linear(addr, val, svga);
|
||||
}
|
||||
|
||||
void tgui_accel_write_fb_l(uint32_t addr, uint32_t val, void *p)
|
||||
@@ -1683,9 +1807,9 @@ void tgui_accel_write_fb_l(uint32_t addr, uint32_t val, void *p)
|
||||
tgui_t *tgui = (tgui_t *)svga->p;
|
||||
|
||||
if (tgui->write_blitter)
|
||||
tgui_queue(tgui, addr, val, FIFO_WRITE_FB_LONG);
|
||||
tgui_accel_command(32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), tgui);
|
||||
else
|
||||
svga_writel_linear(addr, val, svga);
|
||||
svga_writel_linear(addr, val, svga);
|
||||
}
|
||||
|
||||
static void *tgui_init(const device_t *info)
|
||||
@@ -1736,30 +1860,40 @@ static void *tgui_init(const device_t *info)
|
||||
mem_mapping_disable(&tgui->accel_mapping);
|
||||
|
||||
io_sethandler(0x03c0, 0x0020, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui);
|
||||
if (tgui->type >= TGUI_9440)
|
||||
if (tgui->type >= TGUI_9440) {
|
||||
io_sethandler(0x43c8, 0x0002, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui);
|
||||
io_sethandler(0x2120, 0x0001, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui);
|
||||
io_sethandler(0x2122, 0x0001, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui);
|
||||
io_sethandler(0x2124, 0x0001, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui);
|
||||
io_sethandler(0x2127, 0x0001, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui);
|
||||
io_sethandler(0x2128, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui);
|
||||
io_sethandler(0x212b, 0x0001, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui);
|
||||
io_sethandler(0x212c, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui);
|
||||
io_sethandler(0x2130, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui);
|
||||
io_sethandler(0x2134, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui);
|
||||
io_sethandler(0x2138, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui);
|
||||
io_sethandler(0x213a, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui);
|
||||
io_sethandler(0x213c, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui);
|
||||
io_sethandler(0x213e, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui);
|
||||
io_sethandler(0x2140, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui);
|
||||
io_sethandler(0x2142, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui);
|
||||
io_sethandler(0x2180, 0x0080, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui);
|
||||
}
|
||||
|
||||
if ((info->flags & DEVICE_PCI) && (tgui->type >= TGUI_9440))
|
||||
pci_add_card(PCI_ADD_VIDEO, tgui_pci_read, tgui_pci_write, tgui);
|
||||
|
||||
tgui->i2c = i2c_gpio_init("ddc_tgui9440");
|
||||
tgui->ddc = ddc_init(i2c_gpio_get_bus(tgui->i2c));
|
||||
|
||||
tgui->wake_fifo_thread = thread_create_event();
|
||||
tgui->fifo_not_full_event = thread_create_event();
|
||||
tgui->fifo_thread = thread_create(fifo_thread, tgui);
|
||||
|
||||
return tgui;
|
||||
}
|
||||
|
||||
static int tgui9400cxi_available()
|
||||
{
|
||||
return rom_present("roms/video/tgui9440/9400CXI.vbi");
|
||||
return rom_present(ROM_TGUI_9400CXI);
|
||||
}
|
||||
|
||||
static int tgui9440_available()
|
||||
{
|
||||
return rom_present("roms/video/tgui9440/9440.vbi");
|
||||
return rom_present(ROM_TGUI_9440);
|
||||
}
|
||||
|
||||
void tgui_close(void *p)
|
||||
@@ -1768,13 +1902,6 @@ void tgui_close(void *p)
|
||||
|
||||
svga_close(&tgui->svga);
|
||||
|
||||
ddc_close(tgui->ddc);
|
||||
i2c_gpio_close(tgui->i2c);
|
||||
|
||||
thread_kill(tgui->fifo_thread);
|
||||
thread_destroy_event(tgui->wake_fifo_thread);
|
||||
thread_destroy_event(tgui->fifo_not_full_event);
|
||||
|
||||
free(tgui);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user