diff --git a/src/include/86box/vid_svga_render_remap.h b/src/include/86box/vid_svga_render_remap.h new file mode 100644 index 000000000..c2e48f1b2 --- /dev/null +++ b/src/include/86box/vid_svga_render_remap.h @@ -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]; +} diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 6a3331b1d..87952bb13 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -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 diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index a4751d3ea..d22a6e6af 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -742,6 +742,8 @@ et4000_init(const device_t *info) dev->svga.translate_address = get_et4000_addr; + dev->svga.packed_chain4 = 1; + return(dev); } diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index d2cc9b8e3..25e369cc3 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -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 = diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index 96d2af838..ab1a86814 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -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; diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index 49f496942..567d7fd4c 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -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'; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 5977537e3..bb8474ab9 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -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; \ } diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 4b37eda62..727b7f905 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -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; } diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index de84df1f0..2dbd1566f 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -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; diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index aee22a1fe..530b4e2c3 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -27,6 +27,7 @@ #include <86box/video.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +#include <86box/vid_svga_render_remap.h> void svga_render_null(svga_t *svga) @@ -129,11 +130,13 @@ svga_render_text_40(svga_t *svga) xinc = (svga->seqregs[1] & 1) ? 16 : 18; for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { + uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; + drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); if (svga->crtc[0x17] & 0x80) { - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + chr = svga->vram[addr]; + attr = svga->vram[addr+1]; } else chr = attr = 0; @@ -196,11 +199,13 @@ svga_render_text_80(svga_t *svga) xinc = (svga->seqregs[1] & 1) ? 8 : 9; for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { + uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; + drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); if (svga->crtc[0x17] & 0x80) { - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + chr = svga->vram[addr]; + attr = svga->vram[addr+1]; } else chr = attr = 0; @@ -263,11 +268,12 @@ svga_render_text_80_ksc5601(svga_t *svga) xinc = (svga->seqregs[1] & 1) ? 8 : 9; for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { + uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - nextchr = svga->vram[((svga->ma + 4) << 1) & svga->vram_display_mask]; + chr = svga->vram[addr]; + nextchr = svga->vram[addr + 8]; if (svga->crtc[0x17] & 0x80) - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + attr = svga->vram[addr + 1]; else attr = 0; @@ -367,16 +373,17 @@ svga_render_text_80_ksc5601(svga_t *svga) void svga_render_2bpp_lowres(svga_t *svga) { - int changed_offset, x; + int x; uint8_t dat[2]; uint32_t addr, *p; + uint32_t changed_addr; if ((svga->displine + svga->y_add) < 0) return; - changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; + changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) { + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) @@ -384,24 +391,7 @@ svga_render_2bpp_lowres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { - addr = svga->ma; - - if (!(svga->crtc[0x17] & 0x40)) { - addr = (addr << 1) & svga->vram_mask; - 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); + addr = svga->remap_func(svga, svga->ma); dat[0] = svga->vram[addr]; dat[1] = svga->vram[addr | 0x1]; @@ -433,16 +423,17 @@ svga_render_2bpp_lowres(svga_t *svga) void svga_render_2bpp_highres(svga_t *svga) { - int changed_offset, x; + int x; uint8_t dat[2]; uint32_t addr, *p; + uint32_t changed_addr; if ((svga->displine + svga->y_add) < 0) return; - changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; + changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) { + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) @@ -450,24 +441,7 @@ svga_render_2bpp_highres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->ma; - - if (!(svga->crtc[0x17] & 0x40)) { - addr = (addr << 1) & svga->vram_mask; - 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); + addr = svga->remap_func(svga, svga->ma); dat[0] = svga->vram[addr]; dat[1] = svga->vram[addr | 0x1]; @@ -496,6 +470,64 @@ svga_render_2bpp_highres(svga_t *svga) } +void +svga_render_2bpp_headland_highres(svga_t *svga) +{ + int x; + int oddeven; + uint32_t addr, *p; + uint8_t edat[4]; + uint8_t dat; + uint32_t changed_addr; + + if ((svga->displine + svga->y_add) < 0) + return; + + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 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->remap_func(svga, svga->ma); + oddeven = 0; + + if (svga->seqregs[1] & 4) { + oddeven = (addr & 4) ? 1 : 0; + 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 svga_render_4bpp_lowres(svga_t *svga) { @@ -503,11 +535,14 @@ svga_render_4bpp_lowres(svga_t *svga) uint32_t addr, *p; uint8_t edat[4]; uint8_t dat; + uint32_t changed_addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) @@ -515,29 +550,11 @@ svga_render_4bpp_lowres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { - addr = svga->ma; + addr = svga->remap_func(svga, 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) { + oddeven = (addr & 4) ? 1 : 0; edat[0] = svga->vram[addr | oddeven]; edat[2] = svga->vram[addr | oddeven | 0x2]; edat[1] = edat[3] = 0; @@ -573,18 +590,18 @@ svga_render_4bpp_lowres(svga_t *svga) void svga_render_4bpp_highres(svga_t *svga) { - int changed_offset, x; - int oddeven; + int x, oddeven; uint32_t addr, *p; uint8_t edat[4]; uint8_t dat; + uint32_t changed_addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - changed_offset = (svga->ma + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; + changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) { + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; if (svga->firstline_draw == 2000) @@ -592,29 +609,11 @@ svga_render_4bpp_highres(svga_t *svga) svga->lastline_draw = svga->displine; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->ma; + addr = svga->remap_func(svga, 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) { + oddeven = (addr & 4) ? 1 : 0; edat[0] = svga->vram[addr | oddeven]; edat[2] = svga->vram[addr | oddeven | 0x2]; edat[1] = edat[3] = 0; @@ -653,27 +652,44 @@ svga_render_8bpp_lowres(svga_t *svga) int x; uint32_t *p; uint32_t dat; + uint32_t changed_addr; + uint32_t addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 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; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = p[1] = svga->map8[dat & 0xff]; + p[2] = p[3] = svga->map8[(dat >> 8) & 0xff]; + p[4] = p[5] = svga->map8[(dat >> 16) & 0xff]; + p[6] = p[7] = svga->map8[(dat >> 24) & 0xff]; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + svga->ma += 4; + p += 8; + } + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + p[0] = p[1] = svga->map8[dat & 0xff]; + p[2] = p[3] = svga->map8[(dat >> 8) & 0xff]; + p[4] = p[5] = svga->map8[(dat >> 16) & 0xff]; + p[6] = p[7] = svga->map8[(dat >> 24) & 0xff]; - p[0] = p[1] = svga->map8[dat & 0xff]; - p[2] = p[3] = svga->map8[(dat >> 8) & 0xff]; - p[4] = p[5] = svga->map8[(dat >> 16) & 0xff]; - p[6] = p[7] = svga->map8[(dat >> 24) & 0xff]; - - svga->ma += 4; - p += 8; + svga->ma += 4; + p += 8; + } } svga->ma &= svga->vram_display_mask; } @@ -686,38 +702,55 @@ svga_render_8bpp_highres(svga_t *svga) int x; uint32_t *p; uint32_t dat; + uint32_t changed_addr; + uint32_t addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 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; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 8) { + dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = svga->map8[dat & 0xff]; + p[1] = svga->map8[(dat >> 8) & 0xff]; + p[2] = svga->map8[(dat >> 16) & 0xff]; + p[3] = svga->map8[(dat >> 24) & 0xff]; - for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 8) { - dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - p[0] = svga->map8[dat & 0xff]; - p[1] = svga->map8[(dat >> 8) & 0xff]; - p[2] = svga->map8[(dat >> 16) & 0xff]; - p[3] = svga->map8[(dat >> 24) & 0xff]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + p[4] = svga->map8[dat & 0xff]; + p[5] = svga->map8[(dat >> 8) & 0xff]; + p[6] = svga->map8[(dat >> 16) & 0xff]; + p[7] = svga->map8[(dat >> 24) & 0xff]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - p[4] = svga->map8[dat & 0xff]; - p[5] = svga->map8[(dat >> 8) & 0xff]; - p[6] = svga->map8[(dat >> 16) & 0xff]; - p[7] = svga->map8[(dat >> 24) & 0xff]; + svga->ma += 8; + p += 8; + } + } else { + for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 4) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + p[0] = svga->map8[dat & 0xff]; + p[1] = svga->map8[(dat >> 8) & 0xff]; + p[2] = svga->map8[(dat >> 16) & 0xff]; + p[3] = svga->map8[(dat >> 24) & 0xff]; - svga->ma += 8; - p += 8; + svga->ma += 4; + p += 4; + } } svga->ma &= svga->vram_display_mask; } } - void svga_render_8bpp_tseng_lowres(svga_t *svga) { @@ -833,32 +866,49 @@ svga_render_15bpp_lowres(svga_t *svga) int x; uint32_t *p; uint32_t dat; + uint32_t changed_addr, addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 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; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - if (svga->crtc[0x17] & 0x80) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - p[(x << 1)] = p[(x << 1) + 1] = video_15to32[dat & 0xffff]; - p[(x << 1) + 2] = p[(x << 1) + 3] = 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++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + } else + memset(&(p[(x << 1)]), 0x00, 8 * sizeof(uint32_t)); + } + svga->ma += x << 1; + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - p[(x << 1) + 4] = p[(x << 1) + 5] = video_15to32[dat & 0xffff]; - p[(x << 1) + 6] = p[(x << 1) + 7] = video_15to32[dat >> 16]; - } else - memset(&(p[(x << 1)]), 0x00, 8 * sizeof(uint32_t)); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + } else + memset(&(p[x]), 0x00, 2 * sizeof(uint32_t)); + } + svga->ma += 4; } - svga->ma += x << 1; svga->ma &= svga->vram_display_mask; } } @@ -870,38 +920,55 @@ svga_render_15bpp_highres(svga_t *svga) int x; uint32_t *p; uint32_t dat; + uint32_t changed_addr, addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 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; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - if (svga->crtc[0x17] & 0x80) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = video_15to32[dat & 0xffff]; - p[x + 1] = video_15to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = video_15to32[dat & 0xffff]; - p[x + 3] = video_15to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = video_15to32[dat & 0xffff]; - p[x + 5] = video_15to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + } else + memset(&(p[x]), 0x00, 8 * sizeof(uint32_t)); + } + svga->ma += x << 1; + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & 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[x + 7] = video_15to32[dat >> 16]; - } else - memset(&(p[x]), 0x00, 8 * sizeof(uint32_t)); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + } else + memset(&(p[x]), 0x00, 2 * sizeof(uint32_t)); + } + svga->ma += 4; } - svga->ma += x << 1; svga->ma &= svga->vram_display_mask; } } @@ -999,30 +1066,49 @@ svga_render_16bpp_lowres(svga_t *svga) int x; uint32_t *p; uint32_t dat; + uint32_t changed_addr, addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 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; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - if (svga->crtc[0x17] & 0x80) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[(x << 1)] = p[(x << 1) + 1] = video_16to32[dat & 0xffff]; - p[(x << 1) + 2] = p[(x << 1) + 3] = video_16to32[dat >> 16]; + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[(x << 1) + 4] = p[(x << 1) + 5] = video_16to32[dat & 0xffff]; - p[(x << 1) + 6] = p[(x << 1) + 7] = video_16to32[dat >> 16]; - } else - memset(&(p[(x << 1)]), 0x00, 8 * sizeof(uint32_t)); + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } else + memset(&(p[(x << 1)]), 0x00, 8 * sizeof(uint32_t)); + } + svga->ma += x << 1; + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } else + memset(&(p[x]), 0x00, 2 * sizeof(uint32_t)); + } + svga->ma += 4; } - svga->ma += x << 1; svga->ma &= svga->vram_display_mask; } } @@ -1033,38 +1119,57 @@ svga_render_16bpp_highres(svga_t *svga) { int x; uint32_t *p; + uint32_t dat; + uint32_t changed_addr, addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 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; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - if (svga->crtc[0x17] & 0x80) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = video_16to32[dat & 0xffff]; - p[x + 1] = video_16to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = video_16to32[dat & 0xffff]; - p[x + 3] = video_16to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = video_16to32[dat & 0xffff]; - p[x + 5] = video_16to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } else + memset(&(p[x]), 0x00, 8 * sizeof(uint32_t)); + } + svga->ma += x << 1; + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & 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[x + 7] = video_16to32[dat >> 16]; - } else - memset(&(p[x]), 0x00, 8 * sizeof(uint32_t)); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } else + memset(&(p[x]), 0x00, 2 * sizeof(uint32_t)); + + svga->ma += 4; + } } - svga->ma += x << 1; svga->ma &= svga->vram_display_mask; } } @@ -1074,27 +1179,60 @@ void svga_render_24bpp_lowres(svga_t *svga) { int x; - uint32_t fg; + uint32_t *p; + uint32_t changed_addr, addr; + uint32_t dat0, dat1, dat2; if ((svga->displine + svga->y_add) < 0) - return; + return; + + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (svga->crtc[0x17] & 0x80) { + dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); + } else + dat0 = dat1 = dat2 = 0x00000000; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - if (svga->crtc[0x17] & 0x80) - fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); - else - fg = 0x00000000; - svga->ma += 3; - svga->ma &= svga->vram_display_mask; - buffer32->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = - buffer32->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = 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 + svga->scrollcache); x += 4) { + if (svga->crtc[0x17] & 0x80) { + 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]); + } else + dat0 = dat1 = dat2 = 0x00000000; + + 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; + } + } + svga->ma &= svga->vram_display_mask; } - } } @@ -1103,35 +1241,56 @@ svga_render_24bpp_highres(svga_t *svga) { int x; uint32_t *p; - uint32_t dat; + uint32_t changed_addr, addr; + uint32_t dat0, dat1, dat2; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 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; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + if (svga->crtc[0x17] & 0x80) { + dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - if (svga->crtc[0x17] & 0x80) { - dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - p[x] = dat & 0xffffff; + *p++ = dat0 & 0xffffff; + *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); + *p++ = dat2 >> 8; + } else + memset(&(p[x]), 0x0, 4 * sizeof(uint32_t)); - dat = *(uint32_t *)(&svga->vram[(svga->ma + 3) & svga->vram_display_mask]); - p[x + 1] = dat & 0xffffff; + svga->ma += 12; + } + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + if (svga->crtc[0x17] & 0x80) { + 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]); - dat = *(uint32_t *)(&svga->vram[(svga->ma + 6) & svga->vram_display_mask]); - p[x + 2] = dat & 0xffffff; + *p++ = dat0 & 0xffffff; + *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); + *p++ = dat2 >> 8; + } else + memset(&(p[x]), 0x0, 4 * sizeof(uint32_t)); - dat = *(uint32_t *)(&svga->vram[(svga->ma + 9) & svga->vram_display_mask]); - p[x + 3] = dat & 0xffffff; - } else - memset(&(p[x]), 0x0, 4 * sizeof(uint32_t)); - - svga->ma += 12; + svga->ma += 12; + } } svga->ma &= svga->vram_display_mask; } @@ -1142,25 +1301,44 @@ void svga_render_32bpp_lowres(svga_t *svga) { int x; - uint32_t fg; + uint32_t *p; + uint32_t dat; + uint32_t changed_addr, addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 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++) { - if (svga->crtc[0x17] & 0x80) - fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); - else - fg = 0x00000000; - svga->ma += 4; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (svga->crtc[0x17] & 0x80) + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + else + dat = 0x00000000; + *p++ = dat & 0xffffff; + *p++ = dat & 0xffffff; + } + svga->ma += (x * 4); + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + } else + dat = 0x00000000; + *p++ = dat & 0xffffff; + *p++ = dat & 0xffffff; + svga->ma += 4; + } svga->ma &= svga->vram_display_mask; - buffer32->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = - buffer32->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = fg; } } } @@ -1172,25 +1350,41 @@ svga_render_32bpp_highres(svga_t *svga) int x; uint32_t *p; uint32_t dat; + uint32_t changed_addr, addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 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; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = dat & 0xffffff; + } else + memset(&(p[x]), 0x0, 1 * sizeof(uint32_t)); + } + svga->ma += (x * 4); + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + *p++ = dat & 0xffffff; + } else + memset(&(p[x]), 0x0, 1 * sizeof(uint32_t)); - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - if (svga->crtc[0x17] & 0x80) - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - else - dat = 0x00000000; - p[x] = dat & 0xffffff; + svga->ma += 4; + } } - svga->ma += 4; svga->ma &= svga->vram_display_mask; } } @@ -1202,25 +1396,41 @@ svga_render_ABGR8888_highres(svga_t *svga) int x; uint32_t *p; uint32_t dat; + uint32_t changed_addr, addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 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++) { - if (svga->crtc[0x17] & 0x80) - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - else - dat = 0x00000000; - p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + } else + memset(&(p[x]), 0x0, 1 * sizeof(uint32_t)); + } + svga->ma += x*4; + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + } else + memset(&(p[x]), 0x0, 1 * sizeof(uint32_t)); + + svga->ma += 4; + } } - svga->ma += 4; svga->ma &= svga->vram_display_mask; } } @@ -1232,25 +1442,41 @@ svga_render_RGBA8888_highres(svga_t *svga) int x; uint32_t *p; uint32_t dat; + uint32_t changed_addr, addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 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; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (svga->crtc[0x17] & 0x80) { + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = dat >> 8; + } else + memset(&(p[x]), 0x0, 1 * sizeof(uint32_t)); + } + svga->ma += (x * 4); + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (svga->crtc[0x17] & 0x80) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + *p++ = dat >> 8; + } else + memset(&(p[x]), 0x0, 1 * sizeof(uint32_t)); - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - if (svga->crtc[0x17] & 0x80) - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - else - dat = 0x00000000; - p[x] = dat >> 8; + svga->ma += 4; + } } - svga->ma += 4; svga->ma &= svga->vram_display_mask; } } diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index 9dd5fe081..9d2840ed7 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -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); }