From f102fee4977a7dc4be25a994436b0f81f2665c15 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 3 Oct 2024 14:56:23 +0200 Subject: [PATCH 1/7] Major video changes of the day (October 3rd, 2024) 8514/A changes: 1. Correct interlaced display resolution. 2. Added a limit to cursor coordinates. 3. Test/WIP features of the add-on Mach8 side (ATI 8514/A Ultra) such as configurable BIOS. 4. Made the CMD 5 of the acceleration (Polygon Boundary) more accurate per manual (as much as I could regarding the clipping). Cirrus related: 1. Added SUBSYS PCI vendor/device ID of the 5480 (per manual). IBM VGA: 1. Built-in/option rom-less VGA don't need the "available" flag. ATI Mach8/32: 1. As with 8514/A, corrected interlaced display. XGA-1/-2: 1. Moved the XGA R/W memory size tests out of the SVGA R/W routines to reflect the per card basis, although anything that uses its own SVGA mapping would call the tests there (such as Cirrus, Headland and ATI) when not accessing the LFB. This finally puts an end to the XGA MCA mapping enabling bugs. 2. Re-organized the ISA standalone and non-standalone (INMOS) sides of the chips so that they work properly and remove the FILE rom loading hack from init. 3. The Memory Mapped R/W sides now account for instance in their address range. 4. INMOS only: prevent any ROM address access to anything lower than 0xc8000 to not conflict with the main BIOS rom loading. 5. Fixed native pitch by using the correct register, this fixes non 1024x768 resolutions under NT. 6. More logs when enabled to see any future bugs. --- src/include/86box/vid_8514a.h | 2 + src/include/86box/vid_svga.h | 8 +- src/include/86box/vid_vga.h | 6 +- src/include/86box/vid_xga.h | 11 +- src/video/vid_8514a.c | 72 ++-- src/video/vid_ati_mach8.c | 35 +- src/video/vid_cl54xx.c | 31 ++ src/video/vid_et4000.c | 20 +- src/video/vid_ht216.c | 15 +- src/video/vid_svga.c | 94 +---- src/video/vid_vga.c | 5 +- src/video/vid_xga.c | 628 ++++++++++++++++++++-------------- 12 files changed, 513 insertions(+), 414 deletions(-) diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index def3f0f2b..d834a6f42 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -41,6 +41,8 @@ typedef union { typedef struct ibm8514_t { rom_t bios_rom; + rom_t bios_rom2; + rom_t bios_rom3; hwcursor8514_t hwcursor; hwcursor8514_t hwcursor_latch; uint8_t pos_regs[8]; diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index fef9b2122..18b7b672a 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -171,9 +171,11 @@ typedef struct svga_t { pc_timer_t timer; pc_timer_t timer8514; + pc_timer_t timer_xga; double clock; double clock8514; + double clock_xga; double multiplier; @@ -319,9 +321,13 @@ extern void ati8514_pos_write(uint16_t port, uint8_t val, void *priv); extern void ati8514_init(svga_t *svga, void *ext8514, void *dev8514); #endif -extern void xga_poll(void *priv, svga_t *svga); +extern void xga_write_test(uint32_t addr, uint8_t val, void *priv); +extern uint8_t xga_read_test(uint32_t addr, void *priv); +extern void xga_poll(void *priv); extern void xga_recalctimings(svga_t *svga); +extern uint32_t svga_decode_addr(svga_t *svga, uint32_t addr, int write); + extern int svga_init(const device_t *info, svga_t *svga, void *priv, int memsize, void (*recalctimings_ex)(struct svga_t *svga), uint8_t (*video_in)(uint16_t addr, void *priv), diff --git a/src/include/86box/vid_vga.h b/src/include/86box/vid_vga.h index bc552b285..0ffbeb4cd 100644 --- a/src/include/86box/vid_vga.h +++ b/src/include/86box/vid_vga.h @@ -28,9 +28,7 @@ typedef struct vga_t { rom_t bios_rom; } vga_t; -static video_timings_t timing_vga = { VIDEO_ISA, 8, 16, 32, 8, 16, 32 }; - -void vga_out(uint16_t addr, uint8_t val, void *priv); -uint8_t vga_in(uint16_t addr, void *priv); +extern void vga_out(uint16_t addr, uint8_t val, void *priv); +extern uint8_t vga_in(uint16_t addr, void *priv); #endif /*VIDEO_VGA_H*/ diff --git a/src/include/86box/vid_xga.h b/src/include/86box/vid_xga.h index 0686972ca..90a3c69aa 100644 --- a/src/include/86box/vid_xga.h +++ b/src/include/86box/vid_xga.h @@ -31,10 +31,12 @@ typedef struct xga_hwcursor_t { } xga_hwcursor_t; typedef struct xga_t { + mem_mapping_t membios_mapping; mem_mapping_t memio_mapping; mem_mapping_t linear_mapping; mem_mapping_t video_mapping; rom_t bios_rom; + rom_t membios_rom; rom_t vga_bios_rom; xga_hwcursor_t hwcursor; xga_hwcursor_t hwcursor_latch; @@ -47,8 +49,8 @@ typedef struct xga_t { uint8_t pos_regs[8]; uint8_t disp_addr; - uint8_t dac_mask; - uint8_t dac_status; + uint8_t dac_mask; + uint8_t dac_status; uint8_t cfg_reg; uint8_t instance; uint8_t op_mode; @@ -87,6 +89,8 @@ typedef struct xga_t { uint8_t instance_isa; uint8_t instance_num; uint8_t ext_mem_addr; + uint8_t vga_post; + uint8_t addr_test; uint8_t *vram; uint8_t *changedvram; @@ -167,6 +171,9 @@ typedef struct xga_t { uint32_t write_bank; uint32_t px_map_base; uint32_t pallook[512]; + uint32_t bios_diag; + + PALETTE xgapal; uint64_t dispontime; uint64_t dispofftime; diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index e8ae527b5..944a14a88 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -44,8 +44,6 @@ #ifdef ATI_8514_ULTRA #define BIOS_MACH8_ROM_PATH "roms/video/mach8/11301113140.BIN" - -static video_timings_t timing_8514ultra_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; #endif static void ibm8514_accel_outb(uint16_t port, uint8_t val, void *priv); @@ -2407,9 +2405,9 @@ rect_fill_pix: dev->accel.sx += (dev->accel.cur_x & 3); } - if (dev->accel.cmd & 0x20) { + if (dev->accel.cmd & 0x20) dev->accel.cx -= (dev->accel.sx) + 1; - } else + else dev->accel.cx += (dev->accel.sx) + 1; if (dev->accel.cmd & 2) { @@ -3006,9 +3004,7 @@ rect_fill: else dev->accel.oldcy = dev->accel.cy - 1; - dev->accel.oldcx = 0; - - ibm8514_log("Polygon Boundary activated=%04x, len=%d, cur(%d,%d), frgdmix=%02x, err=%d, clipping: l=%d, r=%d, t=%d, b=%d, pixcntl=%02x.\n", dev->accel.cmd, dev->accel.sy, dev->accel.cur_x_nolimit, dev->accel.cy, dev->accel.frgd_mix & 0x1f, dev->accel.err_term, dev->accel.clip_left, clip_r, dev->accel.clip_top, clip_b, compare_mode, dev->accel.multifunc[0x0a]); + ibm8514_log("Polygon Boundary activated=%04x, len=%d, cur(%d,%d), frgdmix=%02x, err=%d, clipping: l=%d, r=%d, t=%d, b=%d, pixcntl=%02x.\n", dev->accel.cmd, dev->accel.sy, dev->accel.cx, dev->accel.cy, dev->accel.frgd_mix & 0x1f, dev->accel.err_term, dev->accel.multifunc[2], dev->accel.multifunc[4], dev->accel.clip_top, clip_b, dev->accel.multifunc[0x0a]); if (ibm8514_cpu_src(svga)) { dev->data_available = 0; @@ -3122,10 +3118,8 @@ rect_fill: } } else { while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.cx < 0) - dev->accel.cx = 0; - if (dev->accel.cy < 0) - dev->accel.cy = 0; + if (dev->accel.cx < dev->accel.clip_left) + dev->accel.cx = dev->accel.clip_left; if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { @@ -3155,12 +3149,8 @@ rect_fill: if ((dev->accel.cmd & 0x14) == 0x14) { if (dev->accel.sy) { - if (dev->accel.cmd & 0x40) { + if (dev->accel.oldcy != dev->accel.cy) { WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } else { - if (dev->accel.oldcy != dev->accel.cy) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } } } } @@ -3178,6 +3168,7 @@ rect_fill: break; if (dev->accel.cmd & 0x40) { + dev->accel.oldcy = dev->accel.cy; if (dev->accel.cmd & 0x80) dev->accel.cy++; else @@ -4159,12 +4150,12 @@ ibm8514_poll(void *priv) if (dev->on[0] || dev->on[1]) { ibm8514_log("ON!\n"); if (!dev->linepos) { - if ((dev->displine == dev->hwcursor_latch.y) && dev->hwcursor_latch.ena) { + if ((dev->displine == ((dev->hwcursor_latch.y < 0) ? 0 : dev->hwcursor_latch.y)) && dev->hwcursor_latch.ena) { dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - dev->hwcursor_latch.yoff; dev->hwcursor_oddeven = 0; } - if ((dev->displine == (dev->hwcursor_latch.y + 1)) && dev->hwcursor_latch.ena && dev->interlace) { + if ((dev->displine == (((dev->hwcursor_latch.y < 0) ? 0 : dev->hwcursor_latch.y) + 1)) && dev->hwcursor_latch.ena && dev->interlace) { dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - (dev->hwcursor_latch.yoff + 1); dev->hwcursor_oddeven = 1; } @@ -4195,7 +4186,7 @@ ibm8514_poll(void *priv) if (dev->hwcursor_on) { if (svga->hwcursor_draw) - svga->hwcursor_draw(svga, dev->displine + svga->y_add); + svga->hwcursor_draw(svga, (dev->displine + svga->y_add + ((dev->hwcursor_latch.y >= 0) ? 0 : dev->hwcursor_latch.y)) & 2047); dev->hwcursor_on--; if (dev->hwcursor_on && dev->interlace) dev->hwcursor_on--; @@ -4333,15 +4324,15 @@ ibm8514_recalctimings(svga_t *svga) else svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; - if (dev->interlace) - dev->dispend >>= 1; - if (dev->dispend == 766) dev->dispend += 2; if (dev->dispend == 478) dev->dispend += 2; + if (dev->interlace) + dev->dispend >>= 1; + dev->pitch = 1024; dev->rowoffset = 0x80; svga->map8 = dev->pallook; @@ -4405,6 +4396,10 @@ ibm8514_mca_reset(void *priv) static void * ibm8514_init(const device_t *info) { +#ifdef ATI_8514_ULTRA + uint32_t bios_addr = 0; +#endif + if (svga_get_pri() == NULL) return NULL; @@ -4426,6 +4421,7 @@ ibm8514_init(const device_t *info) #ifdef ATI_8514_ULTRA dev->extensions = device_get_config_int("extensions"); + bios_addr = device_get_config_hex20("bios_addr"); switch (dev->extensions) { case 1: @@ -4446,10 +4442,14 @@ ibm8514_init(const device_t *info) } else { rom_init(&dev->bios_rom, BIOS_MACH8_ROM_PATH, - 0xd0000, 0x2000, 0x1fff, + bios_addr, 0x1000, 0xfff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&dev->bios_rom2, + BIOS_MACH8_ROM_PATH, + bios_addr + 0x1000, 0x800, 0x7ff, + 0x1000, MEM_MAPPING_EXTERNAL); ati_eeprom_load(&mach->eeprom, "ati8514.nvr", 0); - dev->bios_addr = dev->bios_rom.mapping.base; + mach->accel.scratch0 = (((bios_addr >> 7) - 0x1000) >> 4); } ati8514_init(svga, svga->ext8514, svga->dev8514); break; @@ -4538,6 +4538,30 @@ static const device_config_t ext8514_config[] = { } } }, + { + .name = "bios_addr", + .description = "BIOS address", + .type = CONFIG_HEX20, + .default_string = "", + .default_int = 0xc8000, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "C800h", .value = 0xc8000 }, + { .description = "CA00h", .value = 0xca000 }, + { .description = "CC00h", .value = 0xcc000 }, + { .description = "CE00h", .value = 0xce000 }, + { .description = "D000h", .value = 0xd0000 }, + { .description = "D200h", .value = 0xd2000 }, + { .description = "D400h", .value = 0xd4000 }, + { .description = "D600h", .value = 0xd6000 }, + { .description = "D800h", .value = 0xd8000 }, + { .description = "DA00h", .value = 0xda000 }, + { .description = "DC00h", .value = 0xdc000 }, + { .description = "DE00h", .value = 0xde000 }, + { .description = "" } + }, + }, { .type = CONFIG_END } diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 46d884adf..d41f65ed9 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -37,6 +37,7 @@ #include <86box/i2c.h> #include <86box/vid_ddc.h> #include <86box/vid_8514a.h> +#include <86box/vid_xga.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> #include <86box/vid_ati_eeprom.h> @@ -2478,11 +2479,13 @@ ati8514_recalctimings(svga_t *svga) dev->dispend = dev->vdisp; } - if (dev->accel.advfunc_cntl & 0x04) { + if (dev->accel.advfunc_cntl & 0x04) svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 44900000.0; - } else { + else svga->clock8514 = (cpuclock * (double) (1ULL << 32)) / 25175000.0; - } + + if (dev->interlace) + dev->dispend >>= 1; if (dev->dispend == 766) dev->dispend += 2; @@ -3456,7 +3459,7 @@ mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, u static void mach_accel_out_call(uint16_t port, uint8_t val, mach_t *mach, svga_t *svga, ibm8514_t *dev) { - if (port != 0x7aee && port != 0x7aef && port != 0x42e8 && port != 0x42e9 && port != 0x46e8 && port != 0x46e9) + if (port != 0x7aee && port != 0x7aef && port != 0x42e8 && port != 0x42e9) mach_log("[%04X:%08X]: Port CALL OUT=%04x, val=%02x.\n", CS, cpu_state.pc, port, val); switch (port) { @@ -4290,26 +4293,6 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) case 0x52ee: case 0x52ef: READ8(port, mach->accel.scratch0); -#ifdef ATI_8514_ULTRA - if (mach->mca_bus) { - if (!(port & 1)) { - if (svga->ext8514 != NULL) - temp = dev->pos_regs[4]; - } else { - if (svga->ext8514 != NULL) - temp = dev->pos_regs[5]; - } - } else { - if (svga->ext8514 != NULL) { - temp = ((dev->bios_addr >> 7) - 0x1000) >> 4; - if (port & 1) { - temp &= ~0x80; - temp |= 0x01; - } - } else - temp = 0x00; - } -#endif break; case 0x56ee: @@ -4368,7 +4351,7 @@ mach_accel_in_call(uint16_t port, mach_t *mach, svga_t *svga, ibm8514_t *dev) default: break; } - if (port != 0x62ee && port != 0x62ef && port != 0x42e8 && port != 0x42e9) + if (port != 0x62ee && port != 0x62ef && port != 0x42e8 && port != 0x42e9 && port != 0x02e8 && port != 0x02e9) mach_log("[%04X:%08X]: Port NORMAL IN=%04x, temp=%04x.\n", CS, cpu_state.pc, port, temp); return temp; @@ -4641,6 +4624,7 @@ mach32_write_common(uint32_t addr, uint8_t val, int linear, mach_t *mach, svga_t dev->vram[addr] = val; return; } else { + xga_write_test(addr, val, svga); addr = mach32_decode_addr(svga, addr, 1); if (addr == 0xffffffff) return; @@ -4858,6 +4842,7 @@ mach32_read_common(uint32_t addr, int linear, mach_t *mach, svga_t *svga) if (linear) { return dev->vram[addr & dev->vram_mask]; } else { + (void) xga_read_test(addr, svga); addr = mach32_decode_addr(svga, addr, 0); if (addr == 0xffffffff) return 0xff; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index bf27a700a..01210a9d9 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -37,6 +37,7 @@ #include <86box/video.h> #include <86box/i2c.h> #include <86box/vid_ddc.h> +#include <86box/vid_xga.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> #include <86box/plat_fallthrough.h> @@ -2195,6 +2196,8 @@ gd54xx_write(uint32_t addr, uint8_t val, void *priv) return; } + xga_write_test(addr, val, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; svga_write_linear(addr, val, svga); @@ -2212,6 +2215,9 @@ gd54xx_writew(uint32_t addr, uint16_t val, void *priv) return; } + xga_write_test(addr, val, svga); + xga_write_test(addr + 1, val >> 8, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; @@ -2237,6 +2243,11 @@ gd54xx_writel(uint32_t addr, uint32_t val, void *priv) return; } + xga_write_test(addr, val, svga); + xga_write_test(addr + 1, val >> 8, svga); + xga_write_test(addr + 2, val >> 16, svga); + xga_write_test(addr + 3, val >> 24, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; @@ -2762,6 +2773,8 @@ gd54xx_read(uint32_t addr, void *priv) if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) return gd54xx_mem_sys_dest_read(gd54xx, 0); + (void) xga_read_test(addr, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_read_linear(addr, svga); @@ -2780,6 +2793,9 @@ gd54xx_readw(uint32_t addr, void *priv) return ret; } + (void) xga_read_test(addr, svga); + (void) xga_read_test(addr + 1, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_readw_linear(addr, svga); @@ -2800,6 +2816,11 @@ gd54xx_readl(uint32_t addr, void *priv) return ret; } + (void) xga_read_test(addr, svga); + (void) xga_read_test(addr + 1, svga); + (void) xga_read_test(addr + 2, svga); + (void) xga_read_test(addr + 3, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_readl_linear(addr, svga); @@ -3826,6 +3847,16 @@ cl_pci_read(UNUSED(int func), int addr, void *priv) ret = (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) ? ((gd54xx->vgablt_base >> 24) & 0xff) : 0x00; break; + case 0x2c: + ret = (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) ? gd54xx->bios_rom.rom[0x7ffc] : 0x00; + break; + case 0x2d: + ret = (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) ? gd54xx->bios_rom.rom[0x7ffd] : 0x00; + break; + case 0x2e: + ret = (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) ? gd54xx->bios_rom.rom[0x7ffe] : 0x00; + break; + case 0x30: ret = (gd54xx->pci_regs[0x30] & 0x01); /*BIOS ROM address*/ break; diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index c223d37ba..0ac7050f4 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -125,15 +125,6 @@ et4000_in(uint16_t addr, void *priv) addr ^= 0x60; switch (addr) { - case 0x3c2: - if (dev->type == ET4000_TYPE_MCA) { - if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x4e) - return 0; - else - return 0x10; - } - break; - case 0x3c5: if ((svga->seqaddr & 0xf) == 7) return svga->seqregs[svga->seqaddr & 0xf] | 4; @@ -770,12 +761,16 @@ et4000_mca_write(int port, uint8_t val, void *priv) /* Save the MCA register value. */ et4000->pos_regs[port & 7] = val; + mem_mapping_disable(&et4000->bios_rom.mapping); + if (et4000->pos_regs[2] & 1) + mem_mapping_enable(&et4000->bios_rom.mapping); } static uint8_t et4000_mca_feedb(UNUSED(void *priv)) { - return 1; + et4000_t *et4000 = (et4000_t *) priv; + return et4000->pos_regs[2] & 1; } static void * @@ -889,7 +884,10 @@ et4000_init(const device_t *info) dev->vram_mask = dev->vram_size - 1; rom_init(&dev->bios_rom, fn, - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + + if (dev->type == ET4000_TYPE_MCA) + mem_mapping_disable(&dev->bios_rom.mapping); dev->svga.translate_address = get_et4000_addr; diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index 213cf9ed4..7d868a63b 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -33,6 +33,7 @@ #include <86box/rom.h> #include <86box/device.h> #include <86box/video.h> +#include <86box/vid_xga.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> #include <86box/plat_fallthrough.h> @@ -1217,6 +1218,8 @@ ht216_write(uint32_t addr, uint8_t val, void *priv) svga_t *svga = &ht216->svga; uint32_t prev_addr = addr; + xga_write_test(addr, val, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + ht216->write_banks[(addr >> 15) & 1]; @@ -1238,6 +1241,9 @@ ht216_writew(uint32_t addr, uint16_t val, void *priv) svga_t *svga = &ht216->svga; uint32_t prev_addr = addr; + xga_write_test(addr, val, svga); + xga_write_test(addr + 1, val >> 8, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + ht216->write_banks[(addr >> 15) & 1]; @@ -1261,6 +1267,11 @@ ht216_writel(uint32_t addr, uint32_t val, void *priv) svga_t *svga = &ht216->svga; uint32_t prev_addr = addr; + xga_write_test(addr, val, svga); + xga_write_test(addr + 1, val >> 8, svga); + xga_write_test(addr + 2, val >> 16, svga); + xga_write_test(addr + 3, val >> 24, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + ht216->write_banks[(addr >> 15) & 1]; @@ -1422,9 +1433,11 @@ static uint8_t ht216_read(uint32_t addr, void *priv) { ht216_t *ht216 = (ht216_t *) priv; - const svga_t *svga = &ht216->svga; + svga_t *svga = &ht216->svga; uint32_t prev_addr = addr; + (void) xga_read_test(addr, svga); + addr &= svga->banked_mask; addr = (addr & 0x7fff) + ht216->read_banks[(addr >> 15) & 1]; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index bd31abd23..cecdcf840 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -559,11 +559,12 @@ svga_set_ramdac_type(svga_t *svga, int type) } if (xga_active && xga) { if (svga->ramdac_type == RAMDAC_8BIT) - xga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); - else - xga->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4, - (svga->vgapal[c].g & 0x3f) * 4, - (svga->vgapal[c].b & 0x3f) * 4); + xga->pallook[c] = makecol32(xga->xgapal[c].r, xga->xgapal[c].g, xga->xgapal[c].b); + else { + xga->pallook[c] = makecol32((xga->xgapal[c].r & 0x3f) * 4, + (xga->xgapal[c].g & 0x3f) * 4, + (xga->xgapal[c].b & 0x3f) * 4); + } } if (svga->ramdac_type == RAMDAC_8BIT) svga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); @@ -669,11 +670,11 @@ svga_recalctimings(svga_t *svga) } if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->seqregs[1] & 8) { /*40 column*/ + if (svga->seqregs[1] & 8) { /*40 column*/ svga->render = svga_render_text_40; - } else { + } else svga->render = svga_render_text_80; - } + svga->hdisp_old = svga->hdisp; } else { svga->hdisp_old = svga->hdisp; @@ -1036,7 +1037,7 @@ svga_poll(void *priv) if (!svga->override) { if (xga_active && xga && xga->on) { if ((xga->disp_cntl_2 & 7) >= 2) { - xga_poll(xga, svga); + xga_poll(svga); return; } } @@ -1407,7 +1408,7 @@ svga_close(svga_t *svga) svga_pri = NULL; } -static uint32_t +uint32_t svga_decode_addr(svga_t *svga, uint32_t addr, int write) { int memory_map_mode = (svga->gdcreg[6] >> 2) & 3; @@ -1448,7 +1449,6 @@ static __inline void svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = (xga_t *) svga->xga; int writemask2 = svga->writemask; int reset_wm = 0; latch_t vall; @@ -1462,40 +1462,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *priv) cycles -= svga->monitor->mon_video_timing_write_b; if (!linear) { - if (xga_active && xga) { - if (((xga->op_mode & 7) >= 4) && (xga->aperture_cntl >= 1)) { - if (val == 0xa5) { /*Memory size test of XGA*/ - xga->test = val; - if (addr == 0xa0001) - xga->a5_test = 1; - else if (addr == 0xafffe) - xga->a5_test = 2; - - xga->on = 0; - vga_on = 1; - xga->disp_cntl_2 = 0; - svga_log("XGA test1 addr = %05x.\n", addr); - return; - } else if (val == 0x5a) { - xga->test = val; - xga->on = 0; - vga_on = 1; - xga->disp_cntl_2 = 0; - svga_log("XGA test2 addr = %05x.\n", addr); - return; - } else if ((addr == 0xa0000) || (addr == 0xa0010)) { - addr += xga->write_bank; - xga->vram[addr & xga->vram_mask] = val; - svga_log("XGA Linear endian reverse write, val = %02x, addr = %05x, banked mask = %04x.\n", val, addr, svga->banked_mask); - if (!xga->a5_test) - xga->linear_endian_reverse = 1; - return; - } - } else { - xga->on = 0; - vga_on = 1; - } - } + xga_write_test(addr, val, svga); addr = svga_decode_addr(svga, addr, 1); if (addr == 0xffffffff) @@ -1670,12 +1637,11 @@ static __inline uint8_t svga_read_common(uint32_t addr, uint8_t linear, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = (xga_t *) svga->xga; uint32_t latch_addr = 0; int readplane = svga->readplane; uint8_t count; uint8_t temp; - uint8_t ret; + uint8_t ret = 0x00; if (svga->adv_flags & FLAG_ADDR_BY8) readplane = svga->gdcreg[4] & 7; @@ -1683,39 +1649,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *priv) cycles -= svga->monitor->mon_video_timing_read_b; if (!linear) { - if (xga_active && xga) { - if (((xga->op_mode & 7) >= 4) && (xga->aperture_cntl >= 1)) { - if (xga->test == 0xa5) { /*Memory size test of XGA*/ - if (addr == 0xa0001) { - ret = xga->test; - xga->on = 1; - vga_on = 0; - } else if ((addr == 0xa0000) && (xga->a5_test == 1)) { /*This is required by XGAKIT to pass the memory test*/ - svga_log("A5 test bank = %x.\n", addr); - addr += xga->read_bank; - ret = xga->vram[addr & xga->vram_mask]; - } else { - ret = xga->test; - xga->on = 1; - vga_on = 0; - } - svga_log("A5 read: XGA ON = %d, addr = %05x, ret = %02x, test1 = %x.\n", xga->on, addr, ret, xga->a5_test); - return ret; - } else if (xga->test == 0x5a) { - ret = xga->test; - xga->on = 1; - vga_on = 0; - svga_log("5A read: XGA ON = %d.\n", xga->on); - return ret; - } else if ((addr == 0xa0000) || (addr == 0xa0010)) { - addr += xga->read_bank; - return xga->vram[addr & xga->vram_mask]; - } - } else { - xga->on = 0; - vga_on = 1; - } - } + (void) xga_read_test(addr, svga); addr = svga_decode_addr(svga, addr, 0); if (addr == 0xffffffff) diff --git a/src/video/vid_vga.c b/src/video/vid_vga.c index 8b2e761a3..881a3c6fd 100644 --- a/src/video/vid_vga.c +++ b/src/video/vid_vga.c @@ -31,6 +31,7 @@ #include <86box/vid_svga.h> #include <86box/vid_vga.h> +static video_timings_t timing_vga = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; static video_timings_t timing_ps1_svga_isa = { .type = VIDEO_ISA, .write_b = 6, .write_w = 8, .write_l = 16, .read_b = 6, .read_w = 8, .read_l = 16 }; static video_timings_t timing_ps1_svga_mca = { .type = VIDEO_MCA, .write_b = 6, .write_w = 8, .write_l = 16, .read_b = 6, .read_w = 8, .read_l = 16 }; @@ -207,7 +208,7 @@ const device_t ps1vga_device = { .init = ps1vga_init, .close = vga_close, .reset = NULL, - { .available = vga_available }, + { .available = NULL }, .speed_changed = vga_speed_changed, .force_redraw = vga_force_redraw, .config = NULL @@ -221,7 +222,7 @@ const device_t ps1vga_mca_device = { .init = ps1vga_init, .close = vga_close, .reset = NULL, - { .available = vga_available }, + { .available = NULL }, .speed_changed = vga_speed_changed, .force_redraw = vga_force_redraw, .config = NULL diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 8946d7122..ff82a834a 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -157,6 +157,14 @@ xga_updatemapping(svga_t *svga) break; case 1: xga_log("XGA: VGA mode address decode enabled.\n"); + if (xga->base_addr_1mb) { + mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000); + mem_mapping_enable(&xga->linear_mapping); + } else if (xga->linear_base) { + mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000); + mem_mapping_enable(&xga->linear_mapping); + } else + mem_mapping_disable(&xga->linear_mapping); break; case 2: xga_log("XGA: 132-Column mode address decode disabled.\n"); @@ -203,8 +211,8 @@ void xga_recalctimings(svga_t *svga) { xga_t *xga = (xga_t *) svga->xga; - if (xga->on) { + xga->h_total = xga->htotal + 1; xga->v_total = xga->vtotal + 1; xga->dispend = xga->vdispend + 1; xga->v_syncstart = xga->vsyncstart + 1; @@ -213,7 +221,7 @@ xga_recalctimings(svga_t *svga) xga->h_disp = (xga->hdisp + 1) << 3; - xga->rowoffset = xga->hdisp + 1; + xga->rowoffset = xga->pix_map_width; xga->interlace = !!(xga->disp_cntl_1 & 0x08); xga->rowcount = (xga->disp_cntl_2 & 0xc0) >> 6; @@ -228,11 +236,6 @@ xga_recalctimings(svga_t *svga) xga->ma_latch = xga->disp_start_addr; - if ((xga->disp_cntl_2 & 7) == 2) - xga->rowoffset >>= 1; - else if ((xga->disp_cntl_2 & 7) == 4) - xga->rowoffset <<= 1; - xga_log("XGA ClkSel1 = %d, ClkSel2 = %02x.\n", (xga->clk_sel_1 >> 2) & 3, xga->clk_sel_2 & 0x80); switch ((xga->clk_sel_1 >> 2) & 3) { case 0: @@ -373,12 +376,15 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) case 0x40: xga->disp_start_addr = (xga->disp_start_addr & 0x7ff00) | val; + xga_log("DISPSTARTADDR0=%x.\n", xga->disp_start_addr); break; case 0x41: xga->disp_start_addr = (xga->disp_start_addr & 0x700ff) | (val << 8); + xga_log("DISPSTARTADDR8=%x.\n", xga->disp_start_addr); break; case 0x42: xga->disp_start_addr = (xga->disp_start_addr & 0x0ffff) | ((val & 0x07) << 16); + xga_log("DISPSTARTADDR16=%x.\n", xga->disp_start_addr); svga_recalctimings(svga); break; @@ -387,10 +393,11 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) break; case 0x44: xga->pix_map_width = (xga->pix_map_width & 0xff) | ((val & 0x07) << 8); + svga_recalctimings(svga); break; case 0x50: - xga_log("Reg50 write = %02x.\n", val); + xga_log("Reg50 write=%02x.\n", val); xga->disp_cntl_1 = val; svga_recalctimings(svga); break; @@ -430,18 +437,9 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) xga->cursor_data_on, xga->sprite_pal_addr_idx, xga->aperture_cntl); break; - case 0x62: - xga->sprite_pal_addr_idx_prefetch = (xga->sprite_pal_addr_idx_prefetch & 0x3f00) | val; - xga->dac_pos = 0; - xga->dac_addr = val & 0xff; - break; - case 0x63: - xga->sprite_pal_addr_idx_prefetch = (xga->sprite_pal_addr_idx_prefetch & 0xff) | ((val & 0x3f) << 8); - xga->sprite_pos_prefetch = xga->sprite_pal_addr_idx_prefetch & 0x1ff; - break; - case 0x64: xga->dac_mask = val; + xga_log("DAC mask=%02x.\n", val); break; case 0x65: @@ -458,10 +456,11 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) case 2: xga->pal_b = val; index = xga->dac_addr & 0xff; - svga->vgapal[index].r = xga->dac_r; - svga->vgapal[index].g = xga->dac_g; - svga->vgapal[index].b = xga->pal_b; - xga->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b); + xga->xgapal[index].r = xga->dac_r; + xga->xgapal[index].g = xga->dac_g; + xga->xgapal[index].b = xga->pal_b; + xga->pallook[index] = makecol32(xga->xgapal[index].r, xga->xgapal[index].g, xga->xgapal[index].b); + xga_log("XGA Pallook=%06x, idx=%d.\n", xga->pallook[index], index); xga->dac_pos = 0; xga->dac_addr = (xga->dac_addr + 1) & 0xff; break; @@ -472,19 +471,10 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) break; case 0x66: + xga_log("Palette Sequence=%02x.\n", val); xga->pal_seq = val; break; - case 0x67: - xga->dac_r = val; - break; - case 0x68: - xga->pal_b = val; - break; - case 0x69: - xga->dac_g = val; - break; - case 0x6a: xga->sprite_data[xga->sprite_pos] = val; xga->sprite_pos = (xga->sprite_pos + 1) & 0x3ff; @@ -592,6 +582,9 @@ xga_ext_inb(uint16_t addr, void *priv) case 0x0e: case 0x0f: switch (xga->regs_idx) { + case 0: + ret = (xga->bus & DEVICE_MCA) ? 0x02 : 0x01; + break; case 4: if (xga->bus & DEVICE_MCA) ret = 0x01; /*32-bit MCA*/ @@ -724,13 +717,6 @@ xga_ext_inb(uint16_t addr, void *priv) ret = xga->sprite_pal_addr_idx >> 8; break; - case 0x62: - ret = xga->sprite_pal_addr_idx_prefetch & 0xff; - break; - case 0x63: - ret = xga->sprite_pal_addr_idx_prefetch >> 8; - break; - case 0x64: ret = xga->dac_mask; break; @@ -740,16 +726,16 @@ xga_ext_inb(uint16_t addr, void *priv) switch (xga->dac_pos) { case 0: xga->dac_pos++; - ret = svga->vgapal[index].r; + ret = xga->xgapal[index].r; break; case 1: xga->dac_pos++; - ret = svga->vgapal[index].g; + ret = xga->xgapal[index].g; break; case 2: xga->dac_pos = 0; xga->dac_addr = (xga->dac_addr + 1) & 0xff; - ret = svga->vgapal[index].b; + ret = xga->xgapal[index].b; break; default: @@ -761,21 +747,10 @@ xga_ext_inb(uint16_t addr, void *priv) ret = xga->pal_seq; break; - case 0x67: - ret = xga->dac_r; - break; - case 0x68: - ret = xga->pal_b; - break; - case 0x69: - ret = xga->dac_g; - break; - case 0x6a: - xga_log("Sprite POS Read = %d, addr idx = %04x\n", xga->sprite_pos, - xga->sprite_pal_addr_idx_prefetch); - ret = xga->sprite_data[xga->sprite_pos_prefetch]; - xga->sprite_pos_prefetch = (xga->sprite_pos_prefetch + 1) & 0x3ff; + xga_log("Sprite POS Read=%d.\n", xga->sprite_pos); + ret = xga->sprite_data[xga->sprite_pos]; + xga->sprite_pos = (xga->sprite_pos + 1) & 0x3ff; break; case 0x70: @@ -914,7 +889,7 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b uint8_t px; int skip = 0; - if (addr < xga->linear_base || (addr > (xga->linear_base + 0xfffff))) + if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) skip = 1; addr += (y * (width >> 3)); @@ -953,7 +928,7 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int uint8_t px; int skip = 0; - if (addr < xga->linear_base || (addr > (xga->linear_base + 0xfffff))) + if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) skip = 1; switch (xga->accel.px_map_format[map] & 7) { @@ -1025,7 +1000,7 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui uint8_t mask; int skip = 0; - if (addr < xga->linear_base || (addr > (xga->linear_base + 0xfffff))) + if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff))) skip = 1; switch (xga->accel.px_map_format[map] & 7) { @@ -1743,9 +1718,12 @@ xga_bitblt(svga_t *svga) static void xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) { + uint32_t min_addr = (0x1c00 + (xga->instance << 7)); + uint32_t max_addr = (0x1c00 + (xga->instance << 7)) + 0x7f; + addr &= 0x1fff; - if (addr >= 0x1800) { + if ((addr >= min_addr) && (addr <= max_addr)) { switch (addr & 0x7f) { case 0x11: xga->accel.control = val; @@ -2255,7 +2233,7 @@ xga_memio_writeb(uint32_t addr, uint8_t val, void *priv) xga_mem_write(addr, val, xga, svga, 1); - xga_log("Write MEMIOB = %04x, val = %02x\n", addr & 0x7f, val); + xga_log("[%04X:%08X]: Write MEMIOB = %04x, val = %02x\n", CS, cpu_state.pc, addr, val); } static void @@ -2266,7 +2244,7 @@ xga_memio_writew(uint32_t addr, uint16_t val, void *priv) xga_mem_write(addr, val, xga, svga, 2); - xga_log("Write MEMIOW = %04x, val = %04x\n", addr & 0x7f, val); + xga_log("[%04X:%08X]: Write MEMIOW = %04x, val = %04x\n", CS, cpu_state.pc, addr, val); } static void @@ -2277,21 +2255,25 @@ xga_memio_writel(uint32_t addr, uint32_t val, void *priv) xga_mem_write(addr, val, xga, svga, 4); - xga_log("Write MEMIOL = %04x, val = %08x\n", addr & 0x7f, val); + xga_log("[%04X:%08X]: Write MEMIOL = %04x, val = %08x\n", CS, cpu_state.pc, addr, val); } static uint8_t xga_mem_read(uint32_t addr, xga_t *xga, UNUSED(svga_t *svga)) { + uint32_t min_addr = (0x1c00 + (xga->instance << 7)); + uint32_t max_addr = (0x1c00 + (xga->instance << 7)) + 0x7f; uint8_t temp = 0; addr &= 0x1fff; - if (addr < 0x1800) { + if (addr < 0x1c00) { if (xga_standalone_enabled) temp = xga->bios_rom.rom[addr]; else temp = xga->vga_bios_rom.rom[addr]; - } else { + } else if ((addr >= 0x1c00) && (addr <= 0x1c7f) && xga->instance) { + temp = 0xff; + } else if ((addr >= min_addr) && (addr <= max_addr)) { switch (addr & 0x7f) { case 0x11: temp = xga->accel.control; @@ -2360,7 +2342,6 @@ xga_mem_read(uint32_t addr, xga_t *xga, UNUSED(svga_t *svga)) break; } } - return temp; } @@ -2479,7 +2460,7 @@ xga_render_overscan_left(xga_t *xga, svga_t *svga) if (svga->scrblank || (xga->h_disp == 0)) return; - uint32_t *line_ptr = svga->monitor->target_buffer->line[xga->displine + svga->y_add]; + uint32_t *line_ptr = buffer32->line[xga->displine + svga->y_add]; for (int i = 0; i < svga->x_add; i++) *line_ptr++ = svga->overscan_color; } @@ -2495,7 +2476,7 @@ xga_render_overscan_right(xga_t *xga, svga_t *svga) if (svga->scrblank || (xga->h_disp == 0)) return; - uint32_t *line_ptr = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add + xga->h_disp]; + uint32_t *line_ptr = &buffer32->line[xga->displine + svga->y_add][svga->x_add + xga->h_disp]; right = (overscan_x >> 1); for (int i = 0; i < right; i++) *line_ptr++ = svga->overscan_color; @@ -2512,10 +2493,11 @@ xga_render_4bpp(svga_t *svga) return; if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) { - p = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add]; + p = &buffer32->line[xga->displine + svga->y_add][svga->x_add]; if (xga->firstline_draw == 2000) xga->firstline_draw = xga->displine; + xga->lastline_draw = xga->displine; for (int x = 0; x <= xga->h_disp; x += 16) { @@ -2557,7 +2539,7 @@ xga_render_8bpp(svga_t *svga) return; if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) { - p = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add]; + p = &buffer32->line[xga->displine + svga->y_add][svga->x_add]; if (xga->firstline_draw == 2000) xga->firstline_draw = xga->displine; @@ -2595,7 +2577,7 @@ xga_render_16bpp(svga_t *svga) return; if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) { - p = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add]; + p = &buffer32->line[xga->displine + svga->y_add][svga->x_add]; if (xga->firstline_draw == 2000) xga->firstline_draw = xga->displine; @@ -2623,17 +2605,51 @@ xga_render_16bpp(svga_t *svga) } } +void +xga_write_test(uint32_t addr, uint8_t val, void *priv) +{ + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + + if (xga_active && xga) { + if (((xga->op_mode & 7) >= 1) && (xga->aperture_cntl >= 1)) { + if (val == 0xa5) { /*Memory size test of XGA*/ + xga->test = val; + if (addr == 0xa0001) + xga->a5_test = 1; + else if (addr == 0xafffe) + xga->a5_test = 2; + + xga->on = 0; + vga_on = 1; + xga->disp_cntl_2 = 0; + xga_log("XGA test1 addr=%05x, test=%02x.\n", addr, xga->a5_test); + } else if (val == 0x5a) { + xga->test = val; + xga->on = 0; + vga_on = 1; + xga->disp_cntl_2 = 0; + xga_log("XGA test2 addr = %05x.\n", addr); + } else if ((addr == 0xa0000) || (addr == 0xa0010)) { + addr += xga->write_bank; + xga->vram[addr & xga->vram_mask] = val; + xga_log("XGA Linear endian reverse write, val = %02x, addr = %05x, banked mask = %04x, a5test=%d.\n", val, addr, svga->banked_mask, xga->a5_test); + if (!xga->a5_test) + xga->linear_endian_reverse = 1; + } + } else { + xga->on = 0; + vga_on = 1; + } + } +} + static void xga_write(uint32_t addr, uint8_t val, void *priv) { svga_t *svga = (svga_t *) priv; xga_t *xga = (xga_t *) svga->xga; - if (!xga->on) { - svga_write(addr, val, svga); - return; - } - addr &= xga->banked_mask; addr += xga->write_bank; @@ -2655,12 +2671,6 @@ static void xga_writew(uint32_t addr, uint16_t val, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = (xga_t *) svga->xga; - - if (!xga->on) { - svga_writew(addr, val, svga); - return; - } xga_write(addr, val & 0xff, svga); xga_write(addr + 1, val >> 8, svga); @@ -2670,12 +2680,6 @@ static void xga_writel(uint32_t addr, uint32_t val, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = (xga_t *) svga->xga; - - if (!xga->on) { - svga_writel(addr, val, svga); - return; - } xga_write(addr, val & 0xff, svga); xga_write(addr + 1, (val >> 8) & 0xff, svga); @@ -2683,6 +2687,49 @@ xga_writel(uint32_t addr, uint32_t val, void *priv) xga_write(addr + 3, (val >> 24) & 0xff, svga); } +uint8_t +xga_read_test(uint32_t addr, void *priv) +{ + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; + uint8_t ret = 0x00; + + if (xga_active && xga) { + if (((xga->op_mode & 7) >= 1) && (xga->aperture_cntl >= 1)) { + if (xga->test == 0xa5) { /*Memory size test of XGA*/ + if (addr == 0xa0001) { + ret = xga->test; + xga->on = 1; + vga_on = 0; + } else if ((addr == 0xa0000) && (xga->a5_test == 1)) { /*This is required by XGAKIT to pass the memory test*/ + xga_log("A5 test bank = %x.\n", addr); + addr += xga->read_bank; + ret = xga->vram[addr & xga->vram_mask]; + } else { + ret = xga->test; + xga->on = 1; + vga_on = 0; + } + xga_log("A5 read: XGA ON = %d, addr = %05x, ret = %02x, test1 = %x.\n", xga->on, addr, ret, xga->a5_test); + return ret; + } else if (xga->test == 0x5a) { + ret = xga->test; + xga->on = 1; + vga_on = 0; + xga_log("5A read: XGA ON = %d.\n", xga->on); + return ret; + } else if ((addr == 0xa0000) || (addr == 0xa0010)) { + addr += xga->read_bank; + return xga->vram[addr & xga->vram_mask]; + } + } else { + xga->on = 0; + vga_on = 1; + } + } + return ret; +} + static uint8_t xga_read(uint32_t addr, void *priv) { @@ -2690,11 +2737,6 @@ xga_read(uint32_t addr, void *priv) xga_t *xga = (xga_t *) svga->xga; uint8_t ret = 0xff; - if (!xga->on) { - ret = svga_read(addr, svga); - return ret; - } - addr &= xga->banked_mask; addr += xga->read_bank; @@ -2717,14 +2759,8 @@ static uint16_t xga_readw(uint32_t addr, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = (xga_t *) svga->xga; uint16_t ret = 0xffff; - if (!xga->on) { - ret = svga_readw(addr, svga); - return ret; - } - ret = xga_read(addr, svga); ret |= (xga_read(addr + 1, svga) << 8); @@ -2735,14 +2771,8 @@ static uint32_t xga_readl(uint32_t addr, void *priv) { svga_t *svga = (svga_t *) priv; - xga_t *xga = (xga_t *) svga->xga; uint32_t ret = 0xffffffff; - if (!xga->on) { - ret = svga_readl(addr, svga); - return ret; - } - ret = xga_read(addr, svga); ret |= (xga_read(addr + 1, svga) << 8); ret |= (xga_read(addr + 2, svga) << 16); @@ -2883,43 +2913,11 @@ xga_readl_linear(uint32_t addr, void *priv) return ret; } -static void -xga_do_render(svga_t *svga) -{ - xga_t *xga = (xga_t *) svga->xga; - - xga_log("DISPCNTL = %d, vga = %d.\n", xga->disp_cntl_2 & 7, vga_on); - switch (xga->disp_cntl_2 & 7) { - case 2: - xga_render_4bpp(svga); - break; - case 3: - xga_render_8bpp(svga); - break; - case 4: - xga_render_16bpp(svga); - break; - default: - break; - } - - svga->x_add = (overscan_x >> 1); - xga_render_overscan_left(xga, svga); - xga_render_overscan_right(xga, svga); - svga->x_add = (overscan_x >> 1); - - if (xga->hwcursor_on) { - xga_hwcursor_draw(svga, xga->displine + svga->y_add); - xga->hwcursor_on--; - if (xga->hwcursor_on && xga->interlace) - xga->hwcursor_on--; - } -} - void -xga_poll(void *priv, svga_t *svga) +xga_poll(void *priv) { - xga_t *xga = (xga_t *) priv; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; uint32_t x; int wx; int wy; @@ -2936,6 +2934,7 @@ xga_poll(void *priv, svga_t *svga) } timer_advance_u64(&svga->timer, svga->dispofftime); + svga->cgastat |= 1; xga->linepos = 1; if (xga->dispon) { @@ -2951,7 +2950,32 @@ xga_poll(void *priv, svga_t *svga) if (xga->hwcursor_on) xga->changedvram[xga->ma >> 12] = xga->changedvram[(xga->ma >> 12) + 1] = xga->interlace ? 3 : 2; - xga_do_render(svga); + xga_log("DISPCNTL = %d, vga = %d.\n", xga->disp_cntl_2 & 7, vga_on); + switch (xga->disp_cntl_2 & 7) { + case 2: + xga_render_4bpp(svga); + break; + case 3: + xga_render_8bpp(svga); + break; + case 4: + xga_render_16bpp(svga); + break; + default: + break; + } + + svga->x_add = (overscan_x >> 1); + xga_render_overscan_left(xga, svga); + xga_render_overscan_right(xga, svga); + svga->x_add = (overscan_x >> 1); + + if (xga->hwcursor_on) { + xga_hwcursor_draw(svga, xga->displine + svga->y_add); + xga->hwcursor_on--; + if (xga->hwcursor_on && xga->interlace) + xga->hwcursor_on--; + } if (xga->lastline < xga->displine) xga->lastline = xga->displine; @@ -2960,10 +2984,15 @@ xga_poll(void *priv, svga_t *svga) xga->displine++; if (xga->interlace) xga->displine++; + if ((svga->cgastat & 8) && ((xga->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines) + svga->cgastat &= ~8; if (xga->displine > 1500) xga->displine = 0; } else { timer_advance_u64(&svga->timer, svga->dispontime); + if (xga->dispon) + svga->cgastat &= ~1; + xga->h_disp_on = 0; xga->linepos = 0; @@ -2971,6 +3000,7 @@ xga_poll(void *priv, svga_t *svga) if (xga->sc == xga->rowcount) { xga->sc = 0; + xga_log("MA=%08x, MALATCH=%x.\n", xga->ma, xga->ma_latch); xga->maback += (xga->rowoffset << 3); if (xga->interlace) xga->maback += (xga->rowoffset << 3); @@ -3010,6 +3040,7 @@ xga_poll(void *priv, svga_t *svga) } if (xga->vc == xga->v_syncstart) { xga->dispon = 0; + svga->cgastat |= 8; x = xga->h_disp; if (xga->interlace && !xga->oddeven) @@ -3057,13 +3088,10 @@ xga_poll(void *priv, svga_t *svga) static uint8_t xga_mca_read(int port, void *priv) { - const svga_t *svga = (svga_t *) priv; - const xga_t *xga = (xga_t *) svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = (xga_t *) svga->xga; uint8_t ret = xga->pos_regs[port & 7]; - if (((port & 7) == 3) && !(ret & 1)) /*Always enable the mapping.*/ - ret |= 1; - xga_log("[%04X:%08X]: POS Read Port = %x, val = %02x\n", CS, cpu_state.pc, port & 7, xga->pos_regs[port & 7]); @@ -3081,7 +3109,6 @@ xga_mca_write(int port, uint8_t val, void *priv) return; io_removehandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); - mem_mapping_disable(&xga->bios_rom.mapping); mem_mapping_disable(&xga->memio_mapping); xga->on = 0; vga_on = 1; @@ -3090,8 +3117,6 @@ xga_mca_write(int port, uint8_t val, void *priv) /* Save the MCA register value. */ xga->pos_regs[port & 7] = val; - if (!(xga->pos_regs[4] & 1) && (mem_size >= 16384)) /*MCA 4MB addressing on systems with more than 16MB of memory*/ - xga->pos_regs[4] |= 1; if (xga->pos_regs[2] & 1) { xga->instance = (xga->pos_regs[2] & 0x0e) >> 1; @@ -3101,10 +3126,10 @@ xga_mca_write(int port, uint8_t val, void *priv) io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); - if (xga->pos_regs[3] & 1) - mem_mapping_set_addr(&xga->bios_rom.mapping, xga->rom_addr, 0x2000); - else - mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr + 0x1c00 + (xga->instance * 0x80), 0x80); + if (xga->rom_addr) { + mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr, 0x2000); + xga_log("ROM address=%05x.\n", xga->rom_addr); + } } xga_log("[%04X:%08X]: POS Write Port = %x, val = %02x, linear base = %08x, instance = %d, " @@ -3118,6 +3143,7 @@ xga_mca_feedb(void *priv) const svga_t *svga = (svga_t *) priv; const xga_t *xga = (xga_t *) svga->xga; + xga_log("FeedB.\n"); return xga->pos_regs[2] & 1; } @@ -3127,10 +3153,10 @@ xga_mca_reset(void *priv) svga_t *svga = (svga_t *) priv; xga_t *xga = (xga_t *) svga->xga; - mem_mapping_disable(&xga->bios_rom.mapping); mem_mapping_disable(&xga->memio_mapping); xga->on = 0; vga_on = 1; + xga_log("MCA Reset.\n"); xga_mca_write(0x102, 0, svga); xga->linear_endian_reverse = 0; xga->a5_test = 0; @@ -3142,7 +3168,10 @@ xga_reset(void *priv) svga_t *svga = (svga_t *) priv; xga_t *xga = (xga_t *) svga->xga; - mem_mapping_disable(&xga->bios_rom.mapping); + if (!(xga->bus & DEVICE_MCA) && !xga_standalone_enabled) + mem_mapping_disable(&xga->bios_rom.mapping); + + xga_log("Normal Reset.\n"); mem_mapping_disable(&xga->memio_mapping); xga->on = 0; vga_on = 1; @@ -3155,32 +3184,31 @@ xga_pos_in(uint16_t addr, void *priv) { svga_t *svga = (svga_t *) priv; xga_t *xga = (xga_t *) svga->xga; - uint8_t ret = 0xff; + uint8_t ret = 0x00; if (!xga_standalone_enabled) { switch (addr) { case 0x0100: case 0x0101: - if (xga->instance_isa == xga->instance_num) + if (xga->instance == xga->instance_num) ret = xga->pos_regs[addr & 7]; else ret = 0xff; + + xga_log("%03xRead=%02x.\n", addr, ret); break; case 0x0102: + ret = xga->pos_regs[2]; + break; case 0x0105: - ret = xga->pos_regs[addr & 7]; - break; - case 0x0106: - ret = xga->pos_idx >> 8; - break; - case 0x0107: - ret = xga->pos_idx & 0xff; + ret = xga->pos_regs[5]; + xga_log("POS IDX Read 010%x ret = %02x.\n", addr & 7, ret); break; case 0x0103: - if (!(xga->pos_idx & 3)) + if ((xga->pos_idx & 3) == 0) { ret = xga->pos_regs[3]; - else - ret = 0; + ret |= (xga->dma_channel << 3); + } xga_log("POS IDX for 0103 = %d, ret = %02x.\n", xga->pos_idx & 3, ret); break; @@ -3195,31 +3223,25 @@ xga_pos_in(uint16_t addr, void *priv) case 2: ret = xga->pos_regs[1]; break; - case 3: - ret = 0; - break; default: break; } - xga_log("POS IDX for 0104 = %d, ret = %02x.\n", xga->pos_idx & 3, ret); break; - case 0x0108: - case 0x0109: - case 0x010a: - case 0x010b: - case 0x010c: - case 0x010d: - case 0x010e: - case 0x010f: - xga->instance_num = addr & 7; - if (xga->instance_isa == xga->instance_num) - ret = xga->instance_isa; - else - ret = 0; + case 0x0106: + ret = xga->pos_idx >> 8; + break; + case 0x0107: + ret = xga->pos_idx & 0xff; + break; + case 0x0108 ... 0x010f: + xga->instance_num = addr & 0x07; + if (xga->instance == xga->instance_num) + ret = xga->instance; ret |= xga->isa_pos_enable; + xga_log("%03xRead=%02x.\n", addr, ret); break; default: @@ -3227,12 +3249,15 @@ xga_pos_in(uint16_t addr, void *priv) } } else { switch (addr) { + case 0x0096: + ret = xga->vga_post; + break; case 0x0100: case 0x0101: ret = xga->pos_regs[addr & 7]; break; case 0x0103: - ret = xga->pos_regs[3] | 7; + ret = xga->pos_regs[3] | 0x06; ret |= (xga->dma_channel << 3); break; case 0x0102: @@ -3242,26 +3267,11 @@ xga_pos_in(uint16_t addr, void *priv) case 0x0107: ret = (xga_mca_read(addr, svga)); break; - case 0x0108: - case 0x0109: - case 0x010a: - case 0x010b: - case 0x010c: - case 0x010d: - case 0x010e: - case 0x010f: - xga->instance_num = addr & 7; - if (xga->instance_isa == xga->instance_num) - ret = xga->instance_isa; - else - ret = 0; - - ret |= xga->isa_pos_enable; - break; default: break; } + xga_log("XGA Standalone ISA Read Port=%04x, Ret=%02x.\n", addr, ret); } return ret; } @@ -3274,6 +3284,44 @@ xga_pos_out(uint16_t addr, uint8_t val, void *priv) if (!xga_standalone_enabled) { switch (addr) { + case 0x0096: + xga->vga_post = val; + xga_log("096Write=%02x.\n", val); + break; + case 0x0102: + xga->pos_regs[2] = (val & 0x01); + xga->pos_regs[2] |= ((xga->instance_isa << 1) | xga->ext_mem_addr); + io_removehandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); + mem_mapping_disable(&xga->memio_mapping); + if (xga->pos_regs[2] & 0x01) { + xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000); + xga->instance = (xga->pos_regs[2] & 0x0e) >> 1; + xga->linear_base = ((xga->pos_regs[4] & 0xfe) * 0x1000000) + (xga->instance << 22); + xga->base_addr_1mb = (xga->pos_regs[5] & 0x0f) << 20; + io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); + xga_log("XGA ISA ROM address=%05x, instance=%d.\n", xga->rom_addr, xga->instance); + if (xga->rom_addr >= 0xc8000) + mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr, 0x2000); + else + mem_mapping_disable(&xga->memio_mapping); + } + xga_log("102Write=%02x.\n", val); + break; + case 0x0103: + if ((xga->pos_idx & 3) == 0) + xga->pos_regs[3] = val; + + xga_log("[%04X:%08X]: 103Write=%02x.\n", CS, cpu_state.pc, val); + break; + case 0x0104: + xga_log("104Write=%02x.\n", val); + if ((xga->pos_idx & 3) == 0) + xga->pos_regs[4] = val; + break; + case 0x0105: + xga_log("105Write=%02x.\n", val); + xga->pos_regs[5] = val; + break; case 0x0106: xga->pos_idx = (xga->pos_idx & 0x00ff) | (val << 8); break; @@ -3281,15 +3329,9 @@ xga_pos_out(uint16_t addr, uint8_t val, void *priv) xga->pos_idx = (xga->pos_idx & 0xff00) | val; xga_log("POS IDX Write = %04x.\n", xga->pos_idx); break; - case 0x0108: - case 0x0109: - case 0x010a: - case 0x010b: - case 0x010c: - case 0x010d: - case 0x010e: - case 0x010f: - xga->instance_num = addr & 7; + case 0x0108 ... 0x010f: + xga_log("%03xWrite=%02x.\n", addr, val); + xga->instance_num = addr & 0x07; xga->isa_pos_enable = val & 0x08; break; @@ -3297,17 +3339,10 @@ xga_pos_out(uint16_t addr, uint8_t val, void *priv) break; } } else { + xga_log("XGA Standalone ISA Write Port=%04x, Val=%02x.\n", addr, val); switch (addr) { - case 0x0108: - case 0x0109: - case 0x010a: - case 0x010b: - case 0x010c: - case 0x010d: - case 0x010e: - case 0x010f: - xga->instance_num = addr & 7; - xga->isa_pos_enable = val & 0x08; + case 0x0096: + xga->vga_post = val; break; default: @@ -3324,8 +3359,6 @@ xga_init(const device_t *info) svga_t *svga = svga_get_pri(); xga_t *xga = (xga_t *) calloc(1, sizeof(xga_t)); - FILE *fp; - uint8_t *rom = NULL; svga->xga = xga; @@ -3346,21 +3379,6 @@ xga_init(const device_t *info) xga->linear_endian_reverse = 0; xga->a5_test = 0; - fp = rom_fopen(xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, "rb"); - (void) fseek(fp, 0L, SEEK_END); - (void) fseek(fp, 0L, SEEK_SET); - - rom = malloc(xga->bios_rom.sz); - memset(rom, 0xff, xga->bios_rom.sz); - (void) !fread(rom, xga->bios_rom.sz, 1, fp); - (void) fclose(fp); - - xga->bios_rom.rom = rom; - xga->bios_rom.mask = xga->bios_rom.sz - 1; - if (fp != NULL) { - free(rom); - } - if (info->flags & DEVICE_MCA) { video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_xga_mca); xga->base_addr_1mb = 0; @@ -3368,29 +3386,30 @@ xga_init(const device_t *info) xga->instance = 0; xga->rom_addr = 0; rom_init(&xga->bios_rom, xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, 0xc0000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&xga->bios_rom.mapping); } else { - if (!xga_standalone_enabled) + xga->pos_regs[4] = 0x02; + if (!xga_standalone_enabled) { rom_init(&xga->vga_bios_rom, INMOS_XGA_BIOS_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_xga_isa); - - xga->pos_regs[2] = 1 | (xga->instance_isa << 1) | xga->ext_mem_addr; - xga->instance = (xga->pos_regs[2] & 0x0e) >> 1; - xga->pos_regs[4] = 2; - if (mem_size >= 16384) { - xga->pos_regs[4] |= 1; - xga->pos_regs[5] = 0; } else { - xga->pos_regs[5] = ((mem_size * 64) >> 0x10) + 1; - if (xga->pos_regs[5] == 0x10) { + xga->pos_regs[2] = (xga->instance_isa << 1) | xga->ext_mem_addr; + xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000); + xga->instance = (xga->pos_regs[2] & 0x0e) >> 1; + xga->pos_regs[2] |= 0x01; + if (mem_size >= 16384) { + xga->pos_regs[4] |= 0x01; xga->pos_regs[5] = 0; - xga->pos_regs[4] |= 1; + } else { + xga->pos_regs[5] = ((mem_size * 64) >> 0x10) + 1; + if (xga->pos_regs[5] == 0x10) { + xga->pos_regs[5] = 0x00; + xga->pos_regs[4] |= 0x01; + } } + xga->base_addr_1mb = (xga->pos_regs[5] & 0x0f) << 20; + xga->linear_base = ((xga->pos_regs[4] & 0xfe) * 0x1000000) + (xga->instance << 22); + rom_init(&xga->bios_rom, xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, xga->rom_addr, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); } - - xga->base_addr_1mb = (xga->pos_regs[5] & 0x0f) << 20; - xga->linear_base = ((xga->pos_regs[4] & 0xfe) * 0x1000000) + (xga->instance << 22); - xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000); } mem_mapping_add(&xga->video_mapping, 0, 0, xga_read, xga_readw, xga_readl, @@ -3399,9 +3418,14 @@ xga_init(const device_t *info) mem_mapping_add(&xga->linear_mapping, 0, 0, xga_read_linear, xga_readw_linear, xga_readl_linear, xga_write_linear, xga_writew_linear, xga_writel_linear, NULL, MEM_MAPPING_EXTERNAL, svga); - mem_mapping_add(&xga->memio_mapping, 0, 0, xga_memio_readb, xga_memio_readw, xga_memio_readl, + if (xga_standalone_enabled) + mem_mapping_add(&xga->memio_mapping, 0, 0, xga_memio_readb, xga_memio_readw, xga_memio_readl, xga_memio_writeb, xga_memio_writew, xga_memio_writel, - !xga_standalone_enabled ? xga->vga_bios_rom.rom : xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga); + xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga); + else + mem_mapping_add(&xga->memio_mapping, 0, 0, xga_memio_readb, xga_memio_readw, xga_memio_readl, + xga_memio_writeb, xga_memio_writew, xga_memio_writel, + xga->vga_bios_rom.rom, MEM_MAPPING_EXTERNAL, svga); mem_mapping_disable(&xga->linear_mapping); mem_mapping_disable(&xga->memio_mapping); @@ -3412,13 +3436,12 @@ xga_init(const device_t *info) if (xga->bus & DEVICE_MCA) { mca_add(xga_mca_read, xga_mca_write, xga_mca_feedb, xga_mca_reset, svga); } else { - io_sethandler(0x0100, 0x0008, xga_pos_in, NULL, NULL, NULL, NULL, NULL, svga); - if (!xga_standalone_enabled) - io_sethandler(0x0106, 0x0002, NULL, NULL, NULL, xga_pos_out, NULL, NULL, svga); - - io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); - io_sethandler(0x0108, 0x0008, xga_pos_in, NULL, NULL, xga_pos_out, NULL, NULL, svga); - mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr + 0x1c00 + (xga->instance * 0x80), 0x80); + io_sethandler(0x0096, 0x0001, xga_pos_in, NULL, NULL, xga_pos_out, NULL, NULL, svga); + io_sethandler(0x0100, 0x0010, xga_pos_in, NULL, NULL, xga_pos_out, NULL, NULL, svga); + if (xga_standalone_enabled) { + io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); + mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr, 0x2000); + } } return svga; } @@ -3598,6 +3621,83 @@ static const device_config_t xga_isa_configuration[] = { // clang-format on }; +static const device_config_t xga_inmos_isa_configuration[] = { + // clang-format off + { + .name = "type", + .description = "XGA type", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "XGA-1", + .value = 0 + }, + { + .description = "XGA-2", + .value = 1 + }, + { .description = "" } + } + }, + { + .name = "instance", + .description = "Instance", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 6, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "0 (2100h-210Fh)", .value = 0 }, + { .description = "1 (2110h-211Fh)", .value = 1 }, + { .description = "2 (2120h-212Fh)", .value = 2 }, + { .description = "3 (2130h-213Fh)", .value = 3 }, + { .description = "4 (2140h-214Fh)", .value = 4 }, + { .description = "5 (2150h-215Fh)", .value = 5 }, + { .description = "6 (2160h-216Fh)", .value = 6 }, + { .description = "7 (2170h-217Fh)", .value = 7 }, + { .description = "" } + }, + }, + { + .name = "ext_mem_addr", + .description = "MMIO address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x0040, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "C800h", .value = 0x0040 }, + { .description = "CA00h", .value = 0x0050 }, + { .description = "CC00h", .value = 0x0060 }, + { .description = "CE00h", .value = 0x0070 }, + { .description = "" } + }, + }, + { + .name = "dma", + .description = "DMA channel", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 7, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0 }, + { .description = "DMA 6", .value = 6 }, + { .description = "DMA 7", .value = 7 }, + { .description = "" } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + const device_t xga_device = { .name = "XGA (MCA)", .internal_name = "xga_mca", @@ -3637,7 +3737,7 @@ const device_t inmos_isa_device = { { .available = inmos_xga_available }, .speed_changed = xga_speed_changed, .force_redraw = xga_force_redraw, - .config = xga_isa_configuration + .config = xga_inmos_isa_configuration }; void From 513572135993f21f6d57d14964f09397010450a9 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 5 Oct 2024 21:24:54 +0200 Subject: [PATCH 2/7] XGA changes of the day (October 5th, 2024) 1. SVGA decode mask shouldn't be used in XGA native mode, fixes wrong locks in LFB access. 2. INMOS XGA only: more accurate emulation per INMOS G201 MCA/ISA manual, including the MMIO access and port 0x96, allowing full BIOS and MMIO access at the same time on 0xc0000. --- src/video/vid_xga.c | 162 +++++++++++++++++++++----------------------- 1 file changed, 78 insertions(+), 84 deletions(-) diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index ff82a834a..e8d6ef715 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -171,6 +171,14 @@ xga_updatemapping(svga_t *svga) break; case 3: xga_log("XGA: 132-Column mode address decode enabled.\n"); + if (xga->base_addr_1mb) { + mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000); + mem_mapping_enable(&xga->linear_mapping); + } else if (xga->linear_base) { + mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000); + mem_mapping_enable(&xga->linear_mapping); + } else + mem_mapping_disable(&xga->linear_mapping); break; default: xga_log("XGA: Extended Graphics mode.\n"); @@ -506,10 +514,6 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv) xga->aperture_cntl = val & 3; xga_updatemapping(svga); break; - case 4: - if ((xga->disp_cntl_2 & 7) == 4) - xga->aperture_cntl = 0; - break; case 8: xga->ap_idx = val; xga_log("Aperture CNTL = %d, val = %02x, up to bit6 = %02x\n", xga->aperture_cntl, @@ -1718,12 +1722,24 @@ xga_bitblt(svga_t *svga) static void xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) { - uint32_t min_addr = (0x1c00 + (xga->instance << 7)); - uint32_t max_addr = (0x1c00 + (xga->instance << 7)) + 0x7f; + uint32_t min_addr; + uint32_t max_addr; + int mmio_addr_enable = 0; - addr &= 0x1fff; + if (xga_standalone_enabled) { + addr &= 0x1fff; + min_addr = (0x1c00 + (xga->instance << 7)); + max_addr = (0x1c00 + (xga->instance << 7)) + 0x7f; + } else { + addr &= 0x7fff; + min_addr = (0x7c00 + (xga->instance << 7)); + max_addr = (0x7c00 + (xga->instance << 7)) + 0x7f; + } - if ((addr >= min_addr) && (addr <= max_addr)) { + if ((addr >= min_addr) && (addr <= max_addr)) + mmio_addr_enable = 1; + + if (mmio_addr_enable) { switch (addr & 0x7f) { case 0x11: xga->accel.control = val; @@ -2166,7 +2182,6 @@ exec_command: xga->accel.px_map_format[xga->accel.src_map] & 0x0f, xga->accel.plane_mask); #endif - switch ((xga->accel.command >> 24) & 0x0f) { case 2: /*Short Stroke Vectors Read */ xga_log("Short Stroke Vectors Read.\n"); @@ -2261,19 +2276,34 @@ xga_memio_writel(uint32_t addr, uint32_t val, void *priv) static uint8_t xga_mem_read(uint32_t addr, xga_t *xga, UNUSED(svga_t *svga)) { - uint32_t min_addr = (0x1c00 + (xga->instance << 7)); - uint32_t max_addr = (0x1c00 + (xga->instance << 7)) + 0x7f; + uint32_t min_addr; + uint32_t max_addr; uint8_t temp = 0; + int mmio_addr_enable = 0; - addr &= 0x1fff; - if (addr < 0x1c00) { - if (xga_standalone_enabled) + if (xga_standalone_enabled) { + addr &= 0x1fff; + min_addr = (0x1c00 + (xga->instance << 7)); + max_addr = (0x1c00 + (xga->instance << 7)) + 0x7f; + if (addr < 0x1c00) temp = xga->bios_rom.rom[addr]; - else - temp = xga->vga_bios_rom.rom[addr]; - } else if ((addr >= 0x1c00) && (addr <= 0x1c7f) && xga->instance) { - temp = 0xff; - } else if ((addr >= min_addr) && (addr <= max_addr)) { + else if ((addr >= 0x1c00) && (addr <= 0x1c7f) && xga->instance) + temp = 0xff; + else if ((addr >= min_addr) && (addr <= max_addr)) + mmio_addr_enable = 1; + } else { + addr &= 0x7fff; + min_addr = (0x7c00 + (xga->instance << 7)); + max_addr = (0x7c00 + (xga->instance << 7)) + 0x7f; + if (addr < 0x7c00) + temp = xga->bios_rom.rom[addr]; + else if ((addr >= 0x7c00) && (addr <= 0x7c7f) && xga->instance) + temp = 0xff; + else if ((addr >= min_addr) && (addr <= max_addr)) + mmio_addr_enable = 1; + } + + if (mmio_addr_enable) { switch (addr & 0x7f) { case 0x11: temp = xga->accel.control; @@ -2341,6 +2371,7 @@ xga_mem_read(uint32_t addr, xga_t *xga, UNUSED(svga_t *svga)) default: break; } + xga_log("MMIO Addr=%02x, ret=%02x.\n", addr & 0x7f, temp); } return temp; } @@ -2740,8 +2771,10 @@ xga_read(uint32_t addr, void *priv) addr &= xga->banked_mask; addr += xga->read_bank; - if (addr >= xga->vram_size) + if (addr >= xga->vram_size) { + xga_log("Over Read ADDR=%x.\n", addr); return ret; + } cycles -= svga->monitor->mon_video_timing_read_b; @@ -2792,7 +2825,7 @@ xga_write_linear(uint32_t addr, uint8_t val, void *priv) return; } - addr &= svga->decode_mask; + addr &= (xga->vram_size - 1); if (addr >= xga->vram_size) { xga_log("Write Linear Over!.\n"); @@ -2857,10 +2890,10 @@ xga_read_linear(uint32_t addr, void *priv) if (!xga->on) return svga_read_linear(addr, svga); - addr &= svga->decode_mask; + addr &= (xga->vram_size - 1); if (addr >= xga->vram_size) { - xga_log("Read Linear Over!.\n"); + xga_log("Read Linear Over ADDR=%x!.\n", addr); return ret; } @@ -3168,11 +3201,10 @@ xga_reset(void *priv) svga_t *svga = (svga_t *) priv; xga_t *xga = (xga_t *) svga->xga; - if (!(xga->bus & DEVICE_MCA) && !xga_standalone_enabled) - mem_mapping_disable(&xga->bios_rom.mapping); - xga_log("Normal Reset.\n"); - mem_mapping_disable(&xga->memio_mapping); + if (xga_standalone_enabled) + mem_mapping_disable(&xga->memio_mapping); + xga->on = 0; vga_on = 1; xga->linear_endian_reverse = 0; @@ -3198,7 +3230,7 @@ xga_pos_in(uint16_t addr, void *priv) xga_log("%03xRead=%02x.\n", addr, ret); break; case 0x0102: - ret = xga->pos_regs[2]; + ret = xga->pos_regs[2] | 0x30; break; case 0x0105: ret = xga->pos_regs[5]; @@ -3271,8 +3303,8 @@ xga_pos_in(uint16_t addr, void *priv) default: break; } - xga_log("XGA Standalone ISA Read Port=%04x, Ret=%02x.\n", addr, ret); } + xga_log("[%04X:%08X]: XGA POS IN addr=%04x, ret=%02x.\n", CS, cpu_state.pc, addr, ret); return ret; } @@ -3282,30 +3314,28 @@ xga_pos_out(uint16_t addr, uint8_t val, void *priv) svga_t *svga = (svga_t *) priv; xga_t *xga = (xga_t *) svga->xga; + xga_log("[%04X:%08X]: XGA POS OUT addr=%04x, val=%02x.\n", CS, cpu_state.pc, addr, val); if (!xga_standalone_enabled) { switch (addr) { case 0x0096: - xga->vga_post = val; + xga->instance_num = val & 0x07; + xga->isa_pos_enable = val & 0x08; xga_log("096Write=%02x.\n", val); break; case 0x0102: - xga->pos_regs[2] = (val & 0x01); - xga->pos_regs[2] |= ((xga->instance_isa << 1) | xga->ext_mem_addr); + xga_log("[%04X:%08X]: 102Write=%02x.\n", CS, cpu_state.pc, val); + xga->pos_regs[2] = val | 0x02; /*Instance 0 is not recommended on AT bus/ISA bus systems, so force it to use instance 1.*/ io_removehandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); mem_mapping_disable(&xga->memio_mapping); if (xga->pos_regs[2] & 0x01) { - xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000); + xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xc0) >> 6) * 0x8000); xga->instance = (xga->pos_regs[2] & 0x0e) >> 1; xga->linear_base = ((xga->pos_regs[4] & 0xfe) * 0x1000000) + (xga->instance << 22); xga->base_addr_1mb = (xga->pos_regs[5] & 0x0f) << 20; io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); xga_log("XGA ISA ROM address=%05x, instance=%d.\n", xga->rom_addr, xga->instance); - if (xga->rom_addr >= 0xc8000) - mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr, 0x2000); - else - mem_mapping_disable(&xga->memio_mapping); + mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr, 0x8000); } - xga_log("102Write=%02x.\n", val); break; case 0x0103: if ((xga->pos_idx & 3) == 0) @@ -3375,7 +3405,6 @@ xga_init(const device_t *info) xga->on = 0; xga->hwcursor.cur_xsize = 64; xga->hwcursor.cur_ysize = 64; - xga->bios_rom.sz = 0x2000; xga->linear_endian_reverse = 0; xga->a5_test = 0; @@ -3387,10 +3416,16 @@ xga_init(const device_t *info) xga->rom_addr = 0; rom_init(&xga->bios_rom, xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, 0xc0000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); mem_mapping_disable(&xga->bios_rom.mapping); + mem_mapping_add(&xga->memio_mapping, 0, 0, xga_memio_readb, xga_memio_readw, xga_memio_readl, + xga_memio_writeb, xga_memio_writew, xga_memio_writel, + xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga); } else { xga->pos_regs[4] = 0x02; if (!xga_standalone_enabled) { - rom_init(&xga->vga_bios_rom, INMOS_XGA_BIOS_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xga->bios_rom, INMOS_XGA_BIOS_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); /*VGA BIOS only*/ + mem_mapping_add(&xga->memio_mapping, 0, 0, xga_memio_readb, xga_memio_readw, xga_memio_readl, + xga_memio_writeb, xga_memio_writew, xga_memio_writel, + xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga); } else { xga->pos_regs[2] = (xga->instance_isa << 1) | xga->ext_mem_addr; xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000); @@ -3409,6 +3444,9 @@ xga_init(const device_t *info) xga->base_addr_1mb = (xga->pos_regs[5] & 0x0f) << 20; xga->linear_base = ((xga->pos_regs[4] & 0xfe) * 0x1000000) + (xga->instance << 22); rom_init(&xga->bios_rom, xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, xga->rom_addr, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_add(&xga->memio_mapping, 0, 0, xga_memio_readb, xga_memio_readw, xga_memio_readl, + xga_memio_writeb, xga_memio_writew, xga_memio_writel, + xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga); } } @@ -3418,14 +3456,6 @@ xga_init(const device_t *info) mem_mapping_add(&xga->linear_mapping, 0, 0, xga_read_linear, xga_readw_linear, xga_readl_linear, xga_write_linear, xga_writew_linear, xga_writel_linear, NULL, MEM_MAPPING_EXTERNAL, svga); - if (xga_standalone_enabled) - mem_mapping_add(&xga->memio_mapping, 0, 0, xga_memio_readb, xga_memio_readw, xga_memio_readl, - xga_memio_writeb, xga_memio_writew, xga_memio_writel, - xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga); - else - mem_mapping_add(&xga->memio_mapping, 0, 0, xga_memio_readb, xga_memio_readw, xga_memio_readl, - xga_memio_writeb, xga_memio_writew, xga_memio_writel, - xga->vga_bios_rom.rom, MEM_MAPPING_EXTERNAL, svga); mem_mapping_disable(&xga->linear_mapping); mem_mapping_disable(&xga->memio_mapping); @@ -3643,42 +3673,6 @@ static const device_config_t xga_inmos_isa_configuration[] = { { .description = "" } } }, - { - .name = "instance", - .description = "Instance", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = 6, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "0 (2100h-210Fh)", .value = 0 }, - { .description = "1 (2110h-211Fh)", .value = 1 }, - { .description = "2 (2120h-212Fh)", .value = 2 }, - { .description = "3 (2130h-213Fh)", .value = 3 }, - { .description = "4 (2140h-214Fh)", .value = 4 }, - { .description = "5 (2150h-215Fh)", .value = 5 }, - { .description = "6 (2160h-216Fh)", .value = 6 }, - { .description = "7 (2170h-217Fh)", .value = 7 }, - { .description = "" } - }, - }, - { - .name = "ext_mem_addr", - .description = "MMIO address", - .type = CONFIG_HEX16, - .default_string = "", - .default_int = 0x0040, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "C800h", .value = 0x0040 }, - { .description = "CA00h", .value = 0x0050 }, - { .description = "CC00h", .value = 0x0060 }, - { .description = "CE00h", .value = 0x0070 }, - { .description = "" } - }, - }, { .name = "dma", .description = "DMA channel", From b493b41ab2698c895638760721ba8a098716b0c4 Mon Sep 17 00:00:00 2001 From: Jos van Mourik Date: Sun, 6 Oct 2024 01:12:21 +0200 Subject: [PATCH 3/7] Implement touchscreen calibrate extended --- src/device/mouse_microtouch_touchscreen.c | 57 ++++++++++++++++++++--- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/src/device/mouse_microtouch_touchscreen.c b/src/device/mouse_microtouch_touchscreen.c index ce87a4b68..fed1f2d85 100644 --- a/src/device/mouse_microtouch_touchscreen.c +++ b/src/device/mouse_microtouch_touchscreen.c @@ -60,12 +60,13 @@ const char* mtouch_identity[] = { }; typedef struct mouse_microtouch_t { - double baud_rate, abs_x, abs_x_old, abs_y, abs_y_old; + double abs_x, abs_x_old, abs_y, abs_y_old; + double scale_x, scale_y, off_x, off_y; int but, but_old; char cmd[256]; - int cmd_pos; + int baud_rate, cmd_pos; uint8_t format, mode; - bool mode_status; + bool mode_status, cal_ex; uint8_t id, cal_cntr, pen_mode; bool soh; bool in_reset, reset; @@ -92,10 +93,37 @@ microtouch_calibrate_timer(void *priv) { mouse_microtouch_t *mtouch = (mouse_microtouch_t *) priv; - if (!fifo8_num_used(&mtouch->resp)) { - mtouch->cal_cntr--; - fifo8_push_all(&mtouch->resp, (uint8_t *) "\x01\x31\x0D", 3); /* 1 */ + if ((mtouch->cal_cntr == 2 && (mtouch->abs_x > 0.25 || mtouch->abs_y < 0.75)) || \ + (mtouch->cal_cntr == 1 && (mtouch->abs_x < 0.75 || mtouch->abs_y > 0.25))) { + return; } + + mtouch->cal_cntr--; + fifo8_push_all(&mtouch->resp, (uint8_t *) "\x01\x31\x0D", 3); /* 1 */ + + if (mtouch->cal_ex) { + if (!mtouch->cal_cntr) { + double x1_ref = 0.125; + double y1_ref = 0.875; + double x2_ref = 0.875; + double y2_ref = 0.125; + double x1 = mtouch->abs_x_old; + double y1 = mtouch->abs_y_old; + double x2 = mtouch->abs_x; + double y2 = mtouch->abs_y; + + mtouch->scale_x = (x2_ref - x1_ref) / (x2 - x1); + mtouch->off_x = x1_ref - mtouch->scale_x * x1; + mtouch->scale_y = (y2_ref - y1_ref) / (y2 - y1); + mtouch->off_y = y1_ref - mtouch->scale_y * y1; + mtouch->cal_ex = false; + + pclog("CAL: x1=%f, y1=%f, x2=%f, y2=%f\n", x1, y1, x2, y2); + pclog("CAL: scale_x=%f, scale_y=%f, off_x=%f, off_y=%f\n", mtouch->scale_x, mtouch->scale_y, mtouch->off_x, mtouch->off_y); + } + mtouch->abs_x_old = mtouch->abs_x; + mtouch->abs_y_old = mtouch->abs_y; + } } void @@ -104,7 +132,15 @@ microtouch_process_commands(mouse_microtouch_t *mtouch) mtouch->cmd[strcspn(mtouch->cmd, "\r")] = '\0'; pclog("MT Command: %s\n", mtouch->cmd); - if (mtouch->cmd[0] == 'C' && (mtouch->cmd[1] == 'N' || mtouch->cmd[1] == 'X')) { /* Calibrate New/Extended */ + if (mtouch->cmd[0] == 'C' && mtouch->cmd[1] == 'N') { /* Calibrate New */ + mtouch->cal_cntr = 2; + } + else if (mtouch->cmd[0] == 'C' && mtouch->cmd[1] == 'X') { /* Calibrate Extended */ + mtouch->scale_x = 1; + mtouch->scale_y = 1; + mtouch->off_x = 0; + mtouch->off_y = 0; + mtouch->cal_ex = true; mtouch->cal_cntr = 2; } else if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'D') { /* Format Decimal */ @@ -376,6 +412,9 @@ mtouch_poll(void *priv) dev->abs_y = dev->abs_y / (double) monitors[index].mon_ysize; } + dev->abs_x = dev->scale_x * dev->abs_x + dev->off_x; + dev->abs_y = dev->scale_y * dev->abs_y + dev->off_y; + if (dev->abs_x >= 1.0) dev->abs_x = 1.0; if (dev->abs_y >= 1.0) dev->abs_y = 1.0; if (dev->abs_x <= 0.0) dev->abs_x = 0.0; @@ -408,6 +447,10 @@ mtouch_init(const device_t *info) dev->id = device_get_config_int("identity"); dev->pen_mode = 3; dev->mode = MODE_STREAM; + dev->scale_x = 1; + dev->scale_y = 1; + dev->off_x = 0; + dev->off_y = 0; if (dev->id < 2) { /* legacy controllers */ dev->format = FORMAT_DEC; From 09bbbacede18408a53702b010b85c45692b2a26f Mon Sep 17 00:00:00 2001 From: Jos van Mourik Date: Tue, 8 Oct 2024 20:42:47 +0200 Subject: [PATCH 4/7] Refer to microtouch struct as dev in all functions --- src/device/mouse_microtouch_touchscreen.c | 208 +++++++++++----------- 1 file changed, 105 insertions(+), 103 deletions(-) diff --git a/src/device/mouse_microtouch_touchscreen.c b/src/device/mouse_microtouch_touchscreen.c index fed1f2d85..653ed0662 100644 --- a/src/device/mouse_microtouch_touchscreen.c +++ b/src/device/mouse_microtouch_touchscreen.c @@ -81,178 +81,179 @@ static mouse_microtouch_t *mtouch_inst = NULL; void microtouch_reset_complete(void *priv) { - mouse_microtouch_t *mtouch = (mouse_microtouch_t *) priv; + mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; - mtouch->reset = true; - mtouch->in_reset = false; - fifo8_push_all(&mtouch->resp, (uint8_t *) "\x01\x30\x0D", 3); /* 0 */ + dev->reset = true; + dev->in_reset = false; + fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x30\x0D", 3); /* 0 */ } void microtouch_calibrate_timer(void *priv) { - mouse_microtouch_t *mtouch = (mouse_microtouch_t *) priv; + mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; - if ((mtouch->cal_cntr == 2 && (mtouch->abs_x > 0.25 || mtouch->abs_y < 0.75)) || \ - (mtouch->cal_cntr == 1 && (mtouch->abs_x < 0.75 || mtouch->abs_y > 0.25))) { + if ((dev->cal_cntr == 2 && (dev->abs_x > 0.25 || dev->abs_y < 0.75)) || \ + (dev->cal_cntr == 1 && (dev->abs_x < 0.75 || dev->abs_y > 0.25))) { return; } - mtouch->cal_cntr--; - fifo8_push_all(&mtouch->resp, (uint8_t *) "\x01\x31\x0D", 3); /* 1 */ + dev->cal_cntr--; + fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x31\x0D", 3); /* 1 */ - if (mtouch->cal_ex) { - if (!mtouch->cal_cntr) { + if (dev->cal_ex) { + if (!dev->cal_cntr) { double x1_ref = 0.125; double y1_ref = 0.875; double x2_ref = 0.875; double y2_ref = 0.125; - double x1 = mtouch->abs_x_old; - double y1 = mtouch->abs_y_old; - double x2 = mtouch->abs_x; - double y2 = mtouch->abs_y; + double x1 = dev->abs_x_old; + double y1 = dev->abs_y_old; + double x2 = dev->abs_x; + double y2 = dev->abs_y; - mtouch->scale_x = (x2_ref - x1_ref) / (x2 - x1); - mtouch->off_x = x1_ref - mtouch->scale_x * x1; - mtouch->scale_y = (y2_ref - y1_ref) / (y2 - y1); - mtouch->off_y = y1_ref - mtouch->scale_y * y1; - mtouch->cal_ex = false; + dev->scale_x = (x2_ref - x1_ref) / (x2 - x1); + dev->off_x = x1_ref - dev->scale_x * x1; + dev->scale_y = (y2_ref - y1_ref) / (y2 - y1); + dev->off_y = y1_ref - dev->scale_y * y1; + dev->cal_ex = false; pclog("CAL: x1=%f, y1=%f, x2=%f, y2=%f\n", x1, y1, x2, y2); - pclog("CAL: scale_x=%f, scale_y=%f, off_x=%f, off_y=%f\n", mtouch->scale_x, mtouch->scale_y, mtouch->off_x, mtouch->off_y); + pclog("CAL: scale_x=%f, scale_y=%f, off_x=%f, off_y=%f\n", dev->scale_x, dev->scale_y, dev->off_x, dev->off_y); } - mtouch->abs_x_old = mtouch->abs_x; - mtouch->abs_y_old = mtouch->abs_y; + dev->abs_x_old = dev->abs_x; + dev->abs_y_old = dev->abs_y; } } void -microtouch_process_commands(mouse_microtouch_t *mtouch) +microtouch_process_commands(mouse_microtouch_t *dev) { - mtouch->cmd[strcspn(mtouch->cmd, "\r")] = '\0'; - pclog("MT Command: %s\n", mtouch->cmd); + dev->cmd[strcspn(dev->cmd, "\r")] = '\0'; + pclog("MT Command: %s\n", dev->cmd); - if (mtouch->cmd[0] == 'C' && mtouch->cmd[1] == 'N') { /* Calibrate New */ - mtouch->cal_cntr = 2; + if (dev->cmd[0] == 'C' && dev->cmd[1] == 'N') { /* Calibrate New */ + dev->cal_cntr = 2; } - else if (mtouch->cmd[0] == 'C' && mtouch->cmd[1] == 'X') { /* Calibrate Extended */ - mtouch->scale_x = 1; - mtouch->scale_y = 1; - mtouch->off_x = 0; - mtouch->off_y = 0; - mtouch->cal_ex = true; - mtouch->cal_cntr = 2; + else if (dev->cmd[0] == 'C' && dev->cmd[1] == 'X') { /* Calibrate Extended */ + dev->scale_x = 1; + dev->scale_y = 1; + dev->off_x = 0; + dev->off_y = 0; + dev->cal_ex = true; + dev->cal_cntr = 2; } - else if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'D') { /* Format Decimal */ - mtouch->format = FORMAT_DEC; - mtouch->mode_status = false; + else if (dev->cmd[0] == 'F' && dev->cmd[1] == 'D') { /* Format Decimal */ + dev->format = FORMAT_DEC; + dev->mode_status = false; } - else if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'O') { /* Finger Only */ - mtouch->pen_mode = 1; + else if (dev->cmd[0] == 'F' && dev->cmd[1] == 'O') { /* Finger Only */ + dev->pen_mode = 1; } - else if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'H') { /* Format Hexadecimal */ - mtouch->format = FORMAT_HEX; - mtouch->mode_status = false; + else if (dev->cmd[0] == 'F' && dev->cmd[1] == 'H') { /* Format Hexadecimal */ + dev->format = FORMAT_HEX; + dev->mode_status = false; } - else if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'R') { /* Format Raw */ - mtouch->format = FORMAT_RAW; - mtouch->mode = MODE_INACTIVE; - mtouch->cal_cntr = 0; + else if (dev->cmd[0] == 'F' && dev->cmd[1] == 'R') { /* Format Raw */ + dev->format = FORMAT_RAW; + dev->mode = MODE_INACTIVE; + dev->cal_cntr = 0; } - else if (mtouch->cmd[0] == 'F' && mtouch->cmd[1] == 'T') { /* Format Tablet */ - mtouch->format = FORMAT_TABLET; + else if (dev->cmd[0] == 'F' && dev->cmd[1] == 'T') { /* Format Tablet */ + dev->format = FORMAT_TABLET; } - else if (mtouch->cmd[0] == 'G' && mtouch->cmd[1] == 'P' && mtouch->cmd[2] == '1') { /* Get Parameter Block 1 */ - fifo8_push_all(&mtouch->resp, (uint8_t *) "\x01\x41\x0D", 3); /* A */ - fifo8_push_all(&mtouch->resp, (uint8_t *) "0000000000000000000000000\r", 26); + else if (dev->cmd[0] == 'G' && dev->cmd[1] == 'P' && dev->cmd[2] == '1') { /* Get Parameter Block 1 */ + fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x41\x0D", 3); /* A */ + fifo8_push_all(&dev->resp, (uint8_t *) "0000000000000000000000000\r", 26); } - else if (mtouch->cmd[0] == 'M' && mtouch->cmd[1] == 'D' && mtouch->cmd[2] == 'U') { /* Mode Down/Up */ - mtouch->mode = MODE_DOWNUP; + else if (dev->cmd[0] == 'M' && dev->cmd[1] == 'D' && dev->cmd[2] == 'U') { /* Mode Down/Up */ + dev->mode = MODE_DOWNUP; } - else if (mtouch->cmd[0] == 'M' && mtouch->cmd[1] == 'I') { /* Mode Inactive */ - mtouch->mode = MODE_INACTIVE; + else if (dev->cmd[0] == 'M' && dev->cmd[1] == 'I') { /* Mode Inactive */ + dev->mode = MODE_INACTIVE; } - else if (mtouch->cmd[0] == 'M' && mtouch->cmd[1] == 'P') { /* Mode Point */ - mtouch->mode = MODE_POINT; + else if (dev->cmd[0] == 'M' && dev->cmd[1] == 'P') { /* Mode Point */ + dev->mode = MODE_POINT; } - else if (mtouch->cmd[0] == 'M' && mtouch->cmd[1] == 'T') { /* Mode Status */ - mtouch->mode_status = true; + else if (dev->cmd[0] == 'M' && dev->cmd[1] == 'T') { /* Mode Status */ + dev->mode_status = true; } - else if (mtouch->cmd[0] == 'M' && mtouch->cmd[1] == 'S') { /* Mode Stream */ - mtouch->mode = MODE_STREAM; + else if (dev->cmd[0] == 'M' && dev->cmd[1] == 'S') { /* Mode Stream */ + dev->mode = MODE_STREAM; } - else if (mtouch->cmd[0] == 'O' && mtouch->cmd[1] == 'I') { /* Output Identity */ - fifo8_push(&mtouch->resp, 0x01); - fifo8_push_all(&mtouch->resp, (uint8_t *) mtouch_identity[mtouch->id], 6); - fifo8_push(&mtouch->resp, 0x0D); + else if (dev->cmd[0] == 'O' && dev->cmd[1] == 'I') { /* Output Identity */ + fifo8_push(&dev->resp, 0x01); + fifo8_push_all(&dev->resp, (uint8_t *) mtouch_identity[dev->id], 6); + fifo8_push(&dev->resp, 0x0D); return; } - else if (mtouch->cmd[0] == 'O' && mtouch->cmd[1] == 'S') { /* Output Status */ - if (mtouch->reset) { - fifo8_push_all(&mtouch->resp, (uint8_t *) "\x01\x40\x60\x0D", 4); + else if (dev->cmd[0] == 'O' && dev->cmd[1] == 'S') { /* Output Status */ + if (dev->reset) { + fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x40\x60\x0D", 4); } else { - fifo8_push_all(&mtouch->resp, (uint8_t *) "\x01\x40\x40\x0D", 4); + fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x40\x40\x0D", 4); } return; } - else if (mtouch->cmd[0] == 'P') { - if (strlen(mtouch->cmd) == 2) { /* Pen */ - if (mtouch->cmd[1] == 'F') mtouch->pen_mode = 3; /* Pen or Finger */ - else if (mtouch->cmd[1] == 'O') mtouch->pen_mode = 2; /* Pen Only */ + else if (dev->cmd[0] == 'P') { + if (strlen(dev->cmd) == 2) { /* Pen */ + if (dev->cmd[1] == 'F') dev->pen_mode = 3; /* Pen or Finger */ + else if (dev->cmd[1] == 'O') dev->pen_mode = 2; /* Pen Only */ } - else if (strlen(mtouch->cmd) == 5) { /* Serial Options */ - if (mtouch->cmd[4] == 1) mtouch->baud_rate = 19200; - else if (mtouch->cmd[4] == 2) mtouch->baud_rate = 9600; - else if (mtouch->cmd[4] == 3) mtouch->baud_rate = 4600; - else if (mtouch->cmd[4] == 4) mtouch->baud_rate = 2400; - else if (mtouch->cmd[4] == 5) mtouch->baud_rate = 1200; + else if (strlen(dev->cmd) == 5) { /* Serial Options */ + if (dev->cmd[4] == 1) dev->baud_rate = 19200; + else if (dev->cmd[4] == 2) dev->baud_rate = 9600; + else if (dev->cmd[4] == 3) dev->baud_rate = 4600; + else if (dev->cmd[4] == 4) dev->baud_rate = 2400; + else if (dev->cmd[4] == 5) dev->baud_rate = 1200; - timer_stop(&mtouch->host_to_serial_timer); - timer_on_auto(&mtouch->host_to_serial_timer, (1000000. / mtouch->baud_rate) * 10); + timer_stop(&dev->host_to_serial_timer); + timer_on_auto(&dev->host_to_serial_timer, (1000000. / dev->baud_rate) * 10); } } - else if (mtouch->cmd[0] == 'R') { /* Reset */ - mtouch->in_reset = true; - mtouch->cal_cntr = 0; - mtouch->pen_mode = 3; + else if (dev->cmd[0] == 'R') { /* Reset */ + dev->in_reset = true; + dev->cal_cntr = 0; + dev->pen_mode = 3; - if (mtouch->cmd[0] == 'D') { /* Restore Defaults */ - mtouch->mode = MODE_STREAM; - mtouch->mode_status = false; + if (dev->cmd[0] == 'D') { /* Restore Defaults */ + dev->mode = MODE_STREAM; + dev->mode_status = false; - if (mtouch->id < 2) { - mtouch->format = FORMAT_DEC; + if (dev->id < 2) { + dev->format = FORMAT_DEC; } else { - mtouch->format = FORMAT_TABLET; + dev->format = FORMAT_TABLET; } } - timer_on_auto(&mtouch->reset_timer, 500. * 1000.); + timer_on_auto(&dev->reset_timer, 500. * 1000.); return; } - else if (mtouch->cmd[0] == 'S' && mtouch->cmd[1] == 'P' && mtouch->cmd[2] == '1') { /* Set Parameter Block 1 */ - fifo8_push_all(&mtouch->resp, (uint8_t *) "\x01\x41\x0D", 3); /* A */ + else if (dev->cmd[0] == 'S' && dev->cmd[1] == 'P' && dev->cmd[2] == '1') { /* Set Parameter Block 1 */ + fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x41\x0D", 3); /* A */ return; } - else if (mtouch->cmd[0] == 'U' && mtouch->cmd[1] == 'T') { /* Unit Type */ - fifo8_push(&mtouch->resp, 0x01); + else if (dev->cmd[0] == 'U' && dev->cmd[1] == 'T') { /* Unit Type */ + fifo8_push(&dev->resp, 0x01); - if (mtouch->id == 2) { - fifo8_push_all(&mtouch->resp, (uint8_t *) "TP****00", 8); + if (dev->id == 2) { + fifo8_push_all(&dev->resp, (uint8_t *) "TP****00", 8); } else { - fifo8_push_all(&mtouch->resp, (uint8_t *) "QM****00", 8); + fifo8_push_all(&dev->resp, (uint8_t *) "QM****00", 8); } - fifo8_push(&mtouch->resp, 0x0D); + fifo8_push(&dev->resp, 0x0D); return; } - fifo8_push_all(&mtouch->resp, (uint8_t *) "\x01\x30\x0D", 3); /* 0 */ + fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x30\x0D", 3); /* 0 */ } void mtouch_write(serial_t *serial, void *priv, uint8_t data) { mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; + if (data == '\x1') { dev->soh = 1; } @@ -276,9 +277,9 @@ mtouch_write(serial_t *serial, void *priv, uint8_t data) static int mtouch_prepare_transmit(void *priv) { - char buffer[16]; mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; + char buffer[16]; double abs_x = dev->abs_x; double abs_y = dev->abs_y; int but = dev->but; @@ -358,6 +359,7 @@ void mtouch_write_to_host(void *priv) { mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; + if (dev->serial == NULL) goto no_write_to_machine; if ((dev->serial->type >= SERIAL_16550) && dev->serial->fifo_enabled) { From ea5ef55bd13f504c26d075ce73f72867c1d4cea3 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 11 Oct 2024 16:50:12 -0300 Subject: [PATCH 5/7] qt: Fix another media menu string deallocation crash --- src/qt/qt_mediahistorymanager.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/qt/qt_mediahistorymanager.cpp b/src/qt/qt_mediahistorymanager.cpp index cd9be766b..2acdc8e5b 100644 --- a/src/qt/qt_mediahistorymanager.cpp +++ b/src/qt/qt_mediahistorymanager.cpp @@ -336,17 +336,16 @@ MediaHistoryManager::removeMissingImages(device_index_list_t &device_history) continue; } - char *p = checked_path.toUtf8().data(); char temp[MAX_IMAGE_PATH_LEN -1] = { 0 }; - if (path_abs(p)) { - if (strlen(p) > (MAX_IMAGE_PATH_LEN - 1)) - fatal("removeMissingImages(): strlen(p) > 2047\n"); + if (path_abs(checked_path.toUtf8().data())) { + if (checked_path.length() > (MAX_IMAGE_PATH_LEN - 1)) + fatal("removeMissingImages(): checked_path.length() > 2047\n"); else - snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s", p); + snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s", checked_path.toUtf8().constData()); } else snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, - path_get_slash(usr_path), p); + path_get_slash(usr_path), checked_path.toUtf8().constData()); path_normalize(temp); QString qstr = QString::fromUtf8(temp); From a25892664a71494ba41ce27c0b4a1f4c13952f72 Mon Sep 17 00:00:00 2001 From: Jos van Mourik Date: Fri, 11 Oct 2024 22:33:46 +0200 Subject: [PATCH 6/7] Add NVR saving for calibration data, cleanup --- src/device/mouse_microtouch_touchscreen.c | 104 ++++++++++++++++++---- 1 file changed, 87 insertions(+), 17 deletions(-) diff --git a/src/device/mouse_microtouch_touchscreen.c b/src/device/mouse_microtouch_touchscreen.c index 653ed0662..fa9640eba 100644 --- a/src/device/mouse_microtouch_touchscreen.c +++ b/src/device/mouse_microtouch_touchscreen.c @@ -36,7 +36,10 @@ #include <86box/plat.h> #include <86box/fifo8.h> #include <86box/fifo.h> -#include <86box/video.h> /* Needed to account for overscan. */ +#include <86box/video.h> +#include <86box/nvr.h> + +#define NVR_SIZE 16 enum mtouch_formats { FORMAT_DEC = 1, @@ -60,16 +63,17 @@ const char* mtouch_identity[] = { }; typedef struct mouse_microtouch_t { - double abs_x, abs_x_old, abs_y, abs_y_old; - double scale_x, scale_y, off_x, off_y; - int but, but_old; char cmd[256]; + double abs_x, abs_x_old, abs_y, abs_y_old; + float scale_x, scale_y, off_x, off_y; + int but, but_old; int baud_rate, cmd_pos; uint8_t format, mode; - bool mode_status, cal_ex; uint8_t id, cal_cntr, pen_mode; - bool soh; + bool mode_status, cal_ex, soh; bool in_reset, reset; + uint8_t *nvr; + char nvr_path[64]; serial_t *serial; Fifo8 resp; pc_timer_t host_to_serial_timer; @@ -78,8 +82,68 @@ typedef struct mouse_microtouch_t { static mouse_microtouch_t *mtouch_inst = NULL; -void -microtouch_reset_complete(void *priv) +static void +mtouch_savenvr(void *priv) +{ + mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; + + FILE *fp; + + fp = nvr_fopen(dev->nvr_path, "wb"); + if (fp) { + fwrite(dev->nvr, 1, NVR_SIZE, fp); + fclose(fp); + fp = NULL; + } +} + +static void +mtouch_writenvr(void *priv, float scale_x, float scale_y, float off_x, float off_y) +{ + mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; + + memcpy(&dev->nvr[0], &scale_x, 4); + memcpy(&dev->nvr[4], &scale_y, 4); + memcpy(&dev->nvr[8], &off_x, 4); + memcpy(&dev->nvr[12], &off_y, 4); + + pclog("NVR WRITE: %f, %f, %f, %f\n", scale_x, scale_y, off_x, off_y); +} + +static void +mtouch_readnvr(void *priv) +{ + mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; + memcpy(&dev->scale_x, &dev->nvr[0], 4); + memcpy(&dev->scale_y, &dev->nvr[4], 4); + memcpy(&dev->off_x, &dev->nvr[8], 4); + memcpy(&dev->off_y, &dev->nvr[12], 4); + + pclog("NVR READ: %f, %f, %f, %f\n", dev->scale_x, dev->scale_y, dev->off_x, dev->off_y); +} + +static void +mtouch_initnvr(void *priv) +{ + mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; + FILE *fp; + + /* Allocate and initialize the EEPROM. */ + dev->nvr = (uint8_t *) malloc(NVR_SIZE); + memset(dev->nvr, 0x00, NVR_SIZE); + + fp = nvr_fopen(dev->nvr_path, "rb"); + if (fp) { + if (fread(dev->nvr, 1, NVR_SIZE, fp) != NVR_SIZE) + fatal("mtouch_initnvr(): Error reading data\n"); + fclose(fp); + fp = NULL; + } else + mtouch_writenvr(dev, 1, 1, 0, 0); +} + +static void +mtouch_reset_complete(void *priv) { mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; @@ -88,8 +152,8 @@ microtouch_reset_complete(void *priv) fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x30\x0D", 3); /* 0 */ } -void -microtouch_calibrate_timer(void *priv) +static void +mtouch_calibrate_timer(void *priv) { mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; @@ -120,14 +184,16 @@ microtouch_calibrate_timer(void *priv) pclog("CAL: x1=%f, y1=%f, x2=%f, y2=%f\n", x1, y1, x2, y2); pclog("CAL: scale_x=%f, scale_y=%f, off_x=%f, off_y=%f\n", dev->scale_x, dev->scale_y, dev->off_x, dev->off_y); + mtouch_writenvr(dev, dev->scale_x, dev->scale_y, dev->off_x, dev->off_y); + mtouch_savenvr(dev); } dev->abs_x_old = dev->abs_x; dev->abs_y_old = dev->abs_y; } } -void -microtouch_process_commands(mouse_microtouch_t *dev) +static void +mtouch_process_commands(mouse_microtouch_t *dev) { dev->cmd[strcspn(dev->cmd, "\r")] = '\0'; pclog("MT Command: %s\n", dev->cmd); @@ -249,7 +315,7 @@ microtouch_process_commands(mouse_microtouch_t *dev) fifo8_push_all(&dev->resp, (uint8_t *) "\x01\x30\x0D", 3); /* 0 */ } -void +static void mtouch_write(serial_t *serial, void *priv, uint8_t data) { mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; @@ -269,7 +335,7 @@ mtouch_write(serial_t *serial, void *priv, uint8_t data) dev->cmd[dev->cmd_pos++] = data; dev->cmd_pos = 0; - microtouch_process_commands(dev); + mtouch_process_commands(dev); } } } @@ -290,7 +356,7 @@ mtouch_prepare_transmit(void *priv) if (dev->cal_cntr || (!dev->but && !dev->but_old)) { /* Calibration or no buttonpress */ if (!dev->but && dev->but_old) { - microtouch_calibrate_timer(dev); + mtouch_calibrate_timer(dev); } dev->but_old = but; /* Save buttonpress */ return 0; @@ -355,7 +421,7 @@ mtouch_prepare_transmit(void *priv) return 0; } -void +static void mtouch_write_to_host(void *priv) { mouse_microtouch_t *dev = (mouse_microtouch_t *) priv; @@ -444,7 +510,7 @@ mtouch_init(const device_t *info) fifo8_create(&dev->resp, 256); timer_add(&dev->host_to_serial_timer, mtouch_write_to_host, dev, 0); - timer_add(&dev->reset_timer, microtouch_reset_complete, dev, 0); + timer_add(&dev->reset_timer, mtouch_reset_complete, dev, 0); timer_on_auto(&dev->host_to_serial_timer, (1000000. / dev->baud_rate) * 10); dev->id = device_get_config_int("identity"); dev->pen_mode = 3; @@ -454,6 +520,10 @@ mtouch_init(const device_t *info) dev->off_x = 0; dev->off_y = 0; + sprintf(dev->nvr_path, "mtouch_%s.nvr", mtouch_identity[dev->id]); + mtouch_initnvr(dev); + mtouch_readnvr(dev); + if (dev->id < 2) { /* legacy controllers */ dev->format = FORMAT_DEC; } else { From bc5b6b71c414f6c43bfc99733281ec4bdea9c044 Mon Sep 17 00:00:00 2001 From: Jos van Mourik Date: Fri, 11 Oct 2024 22:44:32 +0200 Subject: [PATCH 7/7] Cleanup --- src/device/mouse_microtouch_touchscreen.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/device/mouse_microtouch_touchscreen.c b/src/device/mouse_microtouch_touchscreen.c index fa9640eba..1100937ef 100644 --- a/src/device/mouse_microtouch_touchscreen.c +++ b/src/device/mouse_microtouch_touchscreen.c @@ -106,8 +106,6 @@ mtouch_writenvr(void *priv, float scale_x, float scale_y, float off_x, float off memcpy(&dev->nvr[4], &scale_y, 4); memcpy(&dev->nvr[8], &off_x, 4); memcpy(&dev->nvr[12], &off_y, 4); - - pclog("NVR WRITE: %f, %f, %f, %f\n", scale_x, scale_y, off_x, off_y); } static void @@ -119,7 +117,7 @@ mtouch_readnvr(void *priv) memcpy(&dev->off_x, &dev->nvr[8], 4); memcpy(&dev->off_y, &dev->nvr[12], 4); - pclog("NVR READ: %f, %f, %f, %f\n", dev->scale_x, dev->scale_y, dev->off_x, dev->off_y); + pclog("MT NVR CAL: scale_x=%f, scale_y=%f, off_x=%f, off_y=%f\n", dev->scale_x, dev->scale_y, dev->off_x, dev->off_y); } static void @@ -181,9 +179,8 @@ mtouch_calibrate_timer(void *priv) dev->scale_y = (y2_ref - y1_ref) / (y2 - y1); dev->off_y = y1_ref - dev->scale_y * y1; dev->cal_ex = false; - - pclog("CAL: x1=%f, y1=%f, x2=%f, y2=%f\n", x1, y1, x2, y2); - pclog("CAL: scale_x=%f, scale_y=%f, off_x=%f, off_y=%f\n", dev->scale_x, dev->scale_y, dev->off_x, dev->off_y); + + pclog("MT NEW CAL: scale_x=%f, scale_y=%f, off_x=%f, off_y=%f\n", dev->scale_x, dev->scale_y, dev->off_x, dev->off_y); mtouch_writenvr(dev, dev->scale_x, dev->scale_y, dev->off_x, dev->off_y); mtouch_savenvr(dev); } @@ -515,10 +512,6 @@ mtouch_init(const device_t *info) dev->id = device_get_config_int("identity"); dev->pen_mode = 3; dev->mode = MODE_STREAM; - dev->scale_x = 1; - dev->scale_y = 1; - dev->off_x = 0; - dev->off_y = 0; sprintf(dev->nvr_path, "mtouch_%s.nvr", mtouch_identity[dev->id]); mtouch_initnvr(dev);