From: Toni Wilen Date: Sun, 18 Oct 2020 13:00:23 +0000 (+0300) Subject: Hardware graphics board emulation updates and fixes. X-Git-Tag: 4900~280 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=7e8b417f5c598d460ad41afd48cac2f1ebf03beb;p=francis%2Fwinuae.git Hardware graphics board emulation updates and fixes. --- diff --git a/gfxboard.cpp b/gfxboard.cpp index 0ef76557..35e57863 100644 --- a/gfxboard.cpp +++ b/gfxboard.cpp @@ -297,7 +297,6 @@ struct rtggfxboard uae_u8 p4_pci[0x44]; int vga_width, vga_height; bool vga_refresh_active; - bool vga_changed; int device_settings; uae_u32 vgaioregionptr, vgavramregionptr, vgabank0regionptr, vgabank1regionptr; @@ -603,6 +602,8 @@ void gfxboard_free_vram(int index) } extern uae_u8 *getpcembuffer32(int, int, int); +extern int svga_get_vtotal(void); +extern int svga_poll(void *p); // PCEM void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) @@ -630,10 +631,11 @@ void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) static int gfxboard_pcem_poll(struct rtggfxboard *gb) { - extern int svga_poll(void *p); return svga_poll(gb->pcemobject2); } +extern int p96syncrate; + static void gfxboard_hsync_handler(void) { for (int i = 0; i < MAX_RTG_BOARDS; i++) { @@ -644,11 +646,9 @@ static void gfxboard_hsync_handler(void) gb->func->hsync(gb->userdata); } if (gb->pcemdev && gb->pcemobject && !gb->pcem_vblank) { - extern int svga_get_vtotal(void); static int pollcnt; - int pollsize = svga_get_vtotal() * 256 / 300; - if (pollsize < 256) - pollsize = 256; + int total = svga_get_vtotal(); + int pollsize = (p96syncrate << 8) / (total ? total : 1); pollcnt += pollsize; while (pollcnt >= 256) { if (gfxboard_pcem_poll(gb)) { @@ -998,7 +998,6 @@ static bool gfxboard_setmode_ext(struct rtggfxboard *gb) gfxboard_setmode(gb, &mode); gfx_set_picasso_modeinfo(gb->monitor_id, mode.mode); gfxboard_set_fullrefresh(gb, 2); - gb->vga_changed = false; return true; } @@ -1128,7 +1127,6 @@ void gfxboard_resize(int width, int height, void *p) { struct rtggfxboard *gb = (struct rtggfxboard *)p; if (width != gb->vga_width || gb->vga_height != height) { - gb->vga_changed = true; gb->resolutionchange = 5; } gb->vga_width = width; @@ -1139,7 +1137,7 @@ void qemu_console_resize(QemuConsole *con, int width, int height) { struct rtggfxboard *gb = (struct rtggfxboard *)con; if (width != gb->vga_width || gb->vga_height != height) { - gb->vga_changed = true; + gb->resolutionchange = 5; } gb->vga_width = width; gb->vga_height = height; @@ -1215,7 +1213,7 @@ uint8_t *surface_data(DisplaySurface *s) return NULL; if (rtg_visible[gb->monitor_id] < 0) return NULL; - if (gb->vga_changed) + if (gb->resolutionchange) return NULL; if (s == &gb->fakesurface || !gb->vga_refresh_active) return gb->fakesurface_surface; @@ -1248,16 +1246,24 @@ void gfxboard_refresh(int monid) } } -void gfxboard_intreq(void *p, int act) +void gfxboard_intreq(void *p, int act, bool safe) { struct rtggfxboard *gb = (struct rtggfxboard*)p; if (act) { if (gb->board->irq && gb->gfxboard_intena) { + int irq = 0; gb->gfxboard_vblank = 1; if (gb->board->irq == 2 && gb->gfxboard_intena != 6) - INTREQ(0x8000 | 0x0008); + irq = 2; else - INTREQ(0x8000 | 0x2000); + irq = 6; + if (irq) { + if (!safe) { + INTREQ(0x8000 | (irq == 6 ? 0x2000 : 0x0008)); + } else { + safe_interrupt_set(IRQ_SOURCE_GFX, gb->monitor_id, irq == 6); + } + } } } else { gb->gfxboard_vblank = 0; @@ -1295,7 +1301,8 @@ void gfxboard_vsync_handler(bool full_redraw_required, bool redraw_required) if (gb->pcemdev) { static int fcount; if (!gb->pcem_vblank && gb->pcemobject) { - for (;;) { + int max = svga_get_vtotal(); + while (max-- > 0) { if (gfxboard_pcem_poll(gb)) break; } @@ -1407,7 +1414,7 @@ void gfxboard_vsync_handler(bool full_redraw_required, bool redraw_required) if (!redraw_required) continue; - if (!gb->monswitch_delay && gb->monswitch_current && ad->picasso_on && ad->picasso_requested_on && !gb->vga_changed) { + if (!gb->monswitch_delay && gb->monswitch_current && ad->picasso_on && ad->picasso_requested_on && !gb->resolutionchange) { picasso_getwritewatch(i, gb->vram_start_offset); if (!gb->pcemdev) { if (gb->fullrefresh) @@ -1418,7 +1425,7 @@ void gfxboard_vsync_handler(bool full_redraw_required, bool redraw_required) } } - if (ad->picasso_on && !gb->vga_changed) { + if (ad->picasso_on && !gb->resolutionchange) { if (!gb->monitor_id) { if (currprefs.leds_on_screen & STATUSLINE_RTG) { if (gb->gfxboard_surface == NULL) { @@ -4451,6 +4458,9 @@ static void REGPARAM2 gfxboard_bput_mmio_pcem(uaecptr addr, uae_u32 b) addr &= gb->pcem_mmio_mask; addr += gb->pcem_mmio_offset; addr ^= 3; +#if 0 + write_log(_T("gfxboard_bput_mmio_wbs_pcem(%08x, %08x)\n"), addr, b); +#endif put_mem_pcem(addr, b, 0); } static void REGPARAM2 gfxboard_wput_mmio_pcem(uaecptr addr, uae_u32 w) @@ -4459,6 +4469,9 @@ static void REGPARAM2 gfxboard_wput_mmio_pcem(uaecptr addr, uae_u32 w) addr &= gb->pcem_mmio_mask; addr += gb->pcem_mmio_offset; addr ^= 2; +#if 0 + write_log(_T("gfxboard_wput_mmio_wbs_pcem(%08x, %08x)\n"), addr, w); +#endif put_mem_pcem(addr, w, 1); } static void REGPARAM2 gfxboard_lput_mmio_pcem(uaecptr addr, uae_u32 l) @@ -4466,6 +4479,9 @@ static void REGPARAM2 gfxboard_lput_mmio_pcem(uaecptr addr, uae_u32 l) struct rtggfxboard *gb = getgfxboard(addr); addr &= gb->pcem_mmio_mask; addr += gb->pcem_mmio_offset; +#if 0 + write_log(_T("gfxboard_lput_mmio_wbs_pcem(%08x, %08x)\n"), addr, l); +#endif put_mem_pcem(addr, l, 2); } @@ -4503,6 +4519,9 @@ static void REGPARAM2 gfxboard_bput_mmio_wbs_pcem(uaecptr addr, uae_u32 b) struct rtggfxboard *gb = getgfxboard(addr); addr &= gb->pcem_mmio_mask; addr += gb->pcem_mmio_offset; +#if 0 + write_log(_T("gfxboard_bput_mmio_wbs_pcem(%08x, %08x)\n"), addr, b); +#endif put_mem_pcem(addr, b, 0); } static void REGPARAM2 gfxboard_wput_mmio_wbs_pcem(uaecptr addr, uae_u32 w) @@ -4510,6 +4529,9 @@ static void REGPARAM2 gfxboard_wput_mmio_wbs_pcem(uaecptr addr, uae_u32 w) struct rtggfxboard *gb = getgfxboard(addr); addr &= gb->pcem_mmio_mask; addr += gb->pcem_mmio_offset; +#if 0 + write_log(_T("gfxboard_wput_mmio_wbs_pcem(%08x, %08x)\n"), addr, w); +#endif w = do_byteswap_16(w); put_mem_pcem(addr, w, 1); } @@ -4518,6 +4540,9 @@ static void REGPARAM2 gfxboard_lput_mmio_wbs_pcem(uaecptr addr, uae_u32 l) struct rtggfxboard *gb = getgfxboard(addr); addr &= gb->pcem_mmio_mask; addr += gb->pcem_mmio_offset; +#if 0 + write_log(_T("gfxboard_lput_mmio_wbs_pcem(%08x, %08x)\n"), addr, l); +#endif l = do_byteswap_32(l); put_mem_pcem(addr, l, 2); } @@ -4554,6 +4579,9 @@ static void REGPARAM2 gfxboard_bput_mmio_lbs_pcem(uaecptr addr, uae_u32 b) struct rtggfxboard *gb = getgfxboard(addr); addr &= gb->pcem_mmio_mask; addr += gb->pcem_mmio_offset; +#if 0 + write_log(_T("gfxboard_bput_mmio_wbs_pcem(%08x, %08x)\n"), addr, b); +#endif put_mem_pcem(addr, b, 0); } static void REGPARAM2 gfxboard_wput_mmio_lbs_pcem(uaecptr addr, uae_u32 w) @@ -4561,6 +4589,9 @@ static void REGPARAM2 gfxboard_wput_mmio_lbs_pcem(uaecptr addr, uae_u32 w) struct rtggfxboard *gb = getgfxboard(addr); addr &= gb->pcem_mmio_mask; addr += gb->pcem_mmio_offset; +#if 0 + write_log(_T("gfxboard_wput_mmio_wbs_pcem(%08x, %08x)\n"), addr, w); +#endif put_mem_pcem(addr, w, 1); } static void REGPARAM2 gfxboard_lput_mmio_lbs_pcem(uaecptr addr, uae_u32 l) @@ -4568,6 +4599,9 @@ static void REGPARAM2 gfxboard_lput_mmio_lbs_pcem(uaecptr addr, uae_u32 l) struct rtggfxboard *gb = getgfxboard(addr); addr &= gb->pcem_mmio_mask; addr += gb->pcem_mmio_offset; +#if 0 + write_log(_T("gfxboard_lput_mmio_wbs_pcem(%08x, %08x)\n"), addr, l); +#endif put_mem_pcem(addr, l, 2); } diff --git a/include/devices.h b/include/devices.h index 0ff88661..a1edf7ea 100644 --- a/include/devices.h +++ b/include/devices.h @@ -46,7 +46,8 @@ void device_add_exit(DEVICE_VOID p); #define IRQ_SOURCE_CIA 12 #define IRQ_SOURCE_CD32CDTV 13 #define IRQ_SOURCE_IDE 14 -#define IRQ_SOURCE_MAX 15 +#define IRQ_SOURCE_GFX 15 +#define IRQ_SOURCE_MAX 16 #endif /* UAE_DEVICES_H */ diff --git a/od-win32/picasso96_win.cpp b/od-win32/picasso96_win.cpp index 498a200c..5756984e 100644 --- a/od-win32/picasso96_win.cpp +++ b/od-win32/picasso96_win.cpp @@ -94,7 +94,7 @@ void picasso_flushpixels(int index, uae_u8 *src, int offset, bool render); int p96refresh_active; bool have_done_picasso = 1; /* For the JIT compiler */ -static int p96syncrate; +int p96syncrate; static int p96hsync_counter; static smp_comm_pipe *render_pipe; diff --git a/pcem/pcemglue.cpp b/pcem/pcemglue.cpp index 185cc8df..8282396e 100644 --- a/pcem/pcemglue.cpp +++ b/pcem/pcemglue.cpp @@ -621,20 +621,20 @@ int pci_add(uint8_t(*read)(int func, int addr, void *priv), void (*write)(int fu pci_card_priv = priv; return 0; } -extern void gfxboard_intreq(void *, int); +extern void gfxboard_intreq(void *, int, bool); void pci_set_irq_routing(int card, int irq) { - write_log(_T("pci_set_irq_routing %d %d\n"), card, irq); + //write_log(_T("pci_set_irq_routing %d %d\n"), card, irq); } void pci_set_irq(int card, int pci_int) { //write_log(_T("pci_set_irq %d %d\n"), card, pci_int); - gfxboard_intreq(gfxboard_priv, 1); + gfxboard_intreq(gfxboard_priv, 1, true); } void pci_clear_irq(int card, int pci_int) { //write_log(_T("pci_clear_irq %d %d\n"), card, pci_int); - gfxboard_intreq(gfxboard_priv, 0); + gfxboard_intreq(gfxboard_priv, 0, true); } int rom_init(rom_t *rom, char *fn, uint32_t address, int size, int mask, int file_offset, uint32_t flags) { @@ -672,7 +672,7 @@ void thread_reset_event(event_t *_event) } int thread_wait_event(event_t *event, int timeout) { - uae_sem_trywait_delay((uae_sem_t*)&event, timeout); + uae_sem_trywait_delay((uae_sem_t*)&event, timeout < 0 ? INFINITE : timeout); return 0; } void thread_destroy_event(event_t *_event) @@ -852,6 +852,10 @@ static void *port_priv[MAX_IO_PORT]; void put_io_pcem(uaecptr addr, uae_u32 v, int size) { +#if 0 + write_log(_T("put_io_pcem(%08x,%08x,%d)\n"), addr, v, size); +#endif + addr &= MAX_IO_PORT - 1; if (size == 0) { if (port_outb[addr]) @@ -874,6 +878,10 @@ void put_io_pcem(uaecptr addr, uae_u32 v, int size) } uae_u32 get_io_pcem(uaecptr addr, int size) { +#if 0 + write_log(_T("get_io_pcem(%08x,%d)\n"), addr, size); +#endif + uae_u32 v = 0; addr &= MAX_IO_PORT - 1; if (size == 0) { diff --git a/pcem/vid_cl5429.cpp b/pcem/vid_cl5429.cpp index ee0b61e8..b86953f7 100644 --- a/pcem/vid_cl5429.cpp +++ b/pcem/vid_cl5429.cpp @@ -1245,8 +1245,8 @@ void gd5429_hwcursor_draw(svga_t *svga, int displine) { for (x = 0; x < 64; x += 8) { - dat[0] = svga->vram[svga->hwcursor_latch.addr]; - dat[1] = svga->vram[svga->hwcursor_latch.addr + 8]; + dat[0] = svga->vram[svga->hwcursor_latch.addr & svga->vram_display_mask]; + dat[1] = svga->vram[(svga->hwcursor_latch.addr + 8) & svga->vram_display_mask]; for (xx = 0; xx < 8; xx++) { if (offset >= svga->hwcursor_latch.x) @@ -1269,8 +1269,8 @@ void gd5429_hwcursor_draw(svga_t *svga, int displine) { for (x = 0; x < 32; x += 8) { - dat[0] = svga->vram[svga->hwcursor_latch.addr]; - dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x80]; + dat[0] = svga->vram[svga->hwcursor_latch.addr & svga->vram_display_mask]; + dat[1] = svga->vram[(svga->hwcursor_latch.addr + 0x80) & svga->vram_display_mask]; for (xx = 0; xx < 8; xx++) { if (offset >= svga->hwcursor_latch.x) diff --git a/pcem/vid_s3.cpp b/pcem/vid_s3.cpp index ab43dcde..ae648ada 100644 --- a/pcem/vid_s3.cpp +++ b/pcem/vid_s3.cpp @@ -2558,8 +2558,8 @@ void s3_hwcursor_draw(svga_t *svga, int displine) // pclog("HWcursor %i %i\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y); for (x = 0; x < 64; x += 16) { - dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 8) | svga->vram[svga->hwcursor_latch.addr + 1]; - dat[1] = (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3]; + dat[0] = (svga->vram[svga->hwcursor_latch.addr & svga->vram_display_mask] << 8) | svga->vram[(svga->hwcursor_latch.addr + 1) & svga->vram_display_mask]; + dat[1] = (svga->vram[(svga->hwcursor_latch.addr + 2) & svga->vram_display_mask] << 8) | svga->vram[(svga->hwcursor_latch.addr + 3) & svga->vram_display_mask]; for (xx = 0; xx < 16; xx++) { if (offset >= svga->hwcursor_latch.x) diff --git a/pcem/vid_s3_virge.cpp b/pcem/vid_s3_virge.cpp index 6c723882..0e9fa320 100644 --- a/pcem/vid_s3_virge.cpp +++ b/pcem/vid_s3_virge.cpp @@ -46,7 +46,7 @@ static int dither[4][4] = #define FIFO_ENTRY_SIZE (1 << 31) #define FIFO_ENTRIES (virge->fifo_write_idx - virge->fifo_read_idx) -#define FIFO_FULL ((virge->fifo_write_idx - virge->fifo_read_idx) >= FIFO_SIZE) +#define FIFO_FULL (virge->fifo_write_idx + 1 == virge->fifo_read_idx) #define FIFO_EMPTY (virge->fifo_read_idx == virge->fifo_write_idx) #define FIFO_TYPE 0xff000000 @@ -227,7 +227,7 @@ typedef struct virge_t } streams; fifo_entry_t fifo[FIFO_SIZE]; - volatile int fifo_read_idx, fifo_write_idx; + volatile uint16_t fifo_read_idx, fifo_write_idx; thread_t *fifo_thread; volatile int fifo_thread_state; @@ -309,7 +309,7 @@ enum #define INT_3DF_EMP (1 << 6) #define INT_MASK 0xff -static int vsync_enabled(virge_t *virge) +static int is_interrupt_active(virge_t *virge) { if ((virge->svga.crtc[0x32] & 0x10) && ((!(virge->svga.crtc[0x11] & 0x20) && virge->vblank_irq > 0) || (virge->subsys_stat & virge->subsys_cntl & INT_MASK))) return 1; @@ -318,7 +318,7 @@ static int vsync_enabled(virge_t *virge) static void s3_virge_update_irqs(virge_t *virge) { - if (vsync_enabled(virge)) + if (is_interrupt_active(virge)) pci_set_irq(virge->card, PCI_INTA); else pci_clear_irq(virge->card, PCI_INTA); @@ -1022,7 +1022,7 @@ static void fifo_thread(void *param) { uint64_t start_time = timer_read(); uint64_t end_time; - fifo_entry_t *fifo = &virge->fifo[virge->fifo_read_idx & FIFO_MASK]; + fifo_entry_t *fifo = &virge->fifo[virge->fifo_read_idx]; uint32_t val = fifo->val; switch (fifo->addr_type & FIFO_TYPE) @@ -1363,7 +1363,7 @@ static void fifo_thread(void *param) static void s3_virge_queue(virge_t *virge, uint32_t addr, uint32_t val, uint32_t type) { - fifo_entry_t *fifo = &virge->fifo[virge->fifo_write_idx & FIFO_MASK]; + fifo_entry_t *fifo = &virge->fifo[virge->fifo_write_idx]; if (FIFO_FULL) { @@ -1379,10 +1379,12 @@ static void s3_virge_queue(virge_t *virge, uint32_t addr, uint32_t val, uint32_t virge->fifo_write_idx++; - if (FIFO_ENTRIES > 0xe000) - wake_fifo_thread(virge); - if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) - wake_fifo_thread(virge); + if (FIFO_ENTRIES > 0xe000) { + wake_fifo_thread(virge); + } + if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) { + wake_fifo_thread(virge); + } } static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p) @@ -3468,8 +3470,8 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) for (x = 0; x < 64; x += 16) { - dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 8) | svga->vram[svga->hwcursor_latch.addr + 1]; - dat[1] = (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3]; + dat[0] = (svga->vram[svga->hwcursor_latch.addr & svga->vram_display_mask] << 8) | svga->vram[(svga->hwcursor_latch.addr + 1) & svga->vram_display_mask]; + dat[1] = (svga->vram[(svga->hwcursor_latch.addr + 2) & svga->vram_display_mask] << 8) | svga->vram[(svga->hwcursor_latch.addr + 3) & svga->vram_display_mask]; if (svga->crtc[0x55] & 0x10) { /*X11*/ diff --git a/pcem/vid_svga.cpp b/pcem/vid_svga.cpp index 7db56ac6..efd3d607 100644 --- a/pcem/vid_svga.cpp +++ b/pcem/vid_svga.cpp @@ -1619,18 +1619,19 @@ void svga_add_status_info(char *s, int max_len, void *p) svga_t *svga = (svga_t *)p; char temps[128]; - if (svga->chain4) strcpy(temps, "SVGA chained (possibly mode 13h)\n"); - else strcpy(temps, "SVGA unchained (possibly mode-X)\n"); + if (svga->chain4) strcpy(temps, "SVGA chained "); + else strcpy(temps, "SVGA unchained "); strncat(s, temps, max_len); - if (!svga->video_bpp) strcpy(temps, "SVGA in text mode\n"); - else sprintf(temps, "SVGA colour depth : %i bpp\n", svga->video_bpp); + if (!svga->video_bpp) strcpy(temps, "SVGA in text mode "); + else sprintf(temps, "SVGA colour depth : %i bpp ", svga->video_bpp); strncat(s, temps, max_len); sprintf(temps, "SVGA resolution : %i x %i\n", svga->video_res_x, svga->video_res_y); strncat(s, temps, max_len); - +#if 0 sprintf(temps, "SVGA refresh rate : %i Hz\n\n", svga->frames); svga->frames = 0; strncat(s, temps, max_len); +#endif }