From e7fdb4a0384174f4b5959ac8ec230db592161774 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 9 Jul 2023 20:31:11 +0300 Subject: [PATCH] Many A2410 emulation improvements --- framebufferboards.cpp | 5 + gfxboard.cpp | 20 ++- include/gfxboard.h | 3 + mame/a2410.cpp | 281 +++++++++++++++++++++++++------------- mame/tm34010/34010fld.c | 8 +- mame/tm34010/34010gfx.c | 11 ++ mame/tm34010/34010ops.c | 4 +- mame/tm34010/34010ops.h | 23 +++- mame/tm34010/tms34010.cpp | 73 +++++----- mame/tm34010/tms34010.h | 5 + 10 files changed, 284 insertions(+), 149 deletions(-) diff --git a/framebufferboards.cpp b/framebufferboards.cpp index 391884b2..103d2cbe 100644 --- a/framebufferboards.cpp +++ b/framebufferboards.cpp @@ -488,6 +488,10 @@ static addrbank generic_fb_bank ABFLAG_IO, S_READ, S_WRITE }; +static void harlequin_refresh(void *userdata) +{ +} + struct gfxboard_func harlequin_func { harlequin_init, @@ -495,6 +499,7 @@ struct gfxboard_func harlequin_func harlequin_reset, harlequin_hsync, harlequin_vsync, + harlequin_refresh, harlequin_toggle, harlequin_configured }; diff --git a/gfxboard.cpp b/gfxboard.cpp index a3e28411..5f7d507a 100644 --- a/gfxboard.cpp +++ b/gfxboard.cpp @@ -1161,6 +1161,9 @@ static void vga_update_size_ext(struct rtggfxboard *gb) static void gfxboard_set_fullrefresh(struct rtggfxboard *gb, int cnt) { gb->fullrefresh = cnt; + if (gb->func) { + gb->func->refresh(gb->userdata); + } } static bool gfxboard_setmode_ext(struct rtggfxboard *gb) @@ -1237,6 +1240,18 @@ bool gfxboard_rtg_enable_initial(int monid, int index) return true; } +bool gfxboard_switch_away(int monid) +{ + if (!monid) { + struct amigadisplay *ad = &adisplays[monid]; + if (ad->picasso_requested_on) { + ad->picasso_requested_on = false; + set_config_changed(); + } + return true; + } + return false; +} int gfxboard_toggle(int monid, int index, int log) { @@ -1564,10 +1579,7 @@ void gfxboard_vsync_handler(bool full_redraw_required, bool redraw_required) } } } else { - if (ad->picasso_requested_on) { - ad->picasso_requested_on = false; - set_config_changed(); - } + gfxboard_switch_away(gb->monitor_id); } } } diff --git a/include/gfxboard.h b/include/gfxboard.h index 799ba0e8..81a93103 100644 --- a/include/gfxboard.h +++ b/include/gfxboard.h @@ -27,6 +27,7 @@ extern const TCHAR *gfxboard_get_configname(int); extern struct gfxboard_func *gfxboard_get_func(struct rtgboardconfig *rbc); extern int gfxboard_get_index_from_id(int); extern int gfxboard_get_id_from_index(int); +extern bool gfxboard_switch_away(int monid); extern bool gfxboard_allocate_slot(int, int); extern void gfxboard_free_slot(int); @@ -98,6 +99,7 @@ typedef void(*GFXBOARD_HSYNC)(void*); typedef bool(*GFXBOARD_VSYNC)(void*, struct gfxboard_mode*); typedef bool(*GFXBOARD_TOGGLE)(void*, int); typedef void(*GFXBOARD_CONFIGURED)(void*, uae_u32); +typedef void(*GFXBOARD_REFRESH)(void*); struct gfxboard_func { @@ -106,6 +108,7 @@ struct gfxboard_func GFXBOARD_RESET reset; GFXBOARD_HSYNC hsync; GFXBOARD_VSYNC vsync; + GFXBOARD_REFRESH refresh; GFXBOARD_TOGGLE toggle; GFXBOARD_CONFIGURED configured; }; diff --git a/mame/a2410.cpp b/mame/a2410.cpp index a8dfe01e..56332686 100644 --- a/mame/a2410.cpp +++ b/mame/a2410.cpp @@ -25,7 +25,7 @@ static tms340x0_device tms_device; static address_space tms_space; mscreen *m_screen; -#define OVERLAY_WIDTH 1024 +#define MAX_HEIGHT 2048 struct a2410_struct { @@ -39,21 +39,24 @@ struct a2410_struct uae_u8 a2410_palette_temp[4]; uae_u8 a2410_palette_control[4]; uae_u16 a2410_control; - bool a2410_modified[1024]; + bool a2410_modified[MAX_HEIGHT]; int a2410_displaywidth; int a2410_displayend; int a2410_vertical_start; - bool a2410_enabled; + bool a2410_enabled, a2410_active; uae_u8 a2410_overlay_mask[2]; int a2410_overlay_blink_rate_on; int a2410_overlay_blink_rate_off; int a2410_overlay_blink_cnt; uae_u32 tms_configured; int a2410_gfxboard; + int coladdr; bool a2410_modechanged; - int a2410_gotmode; int a2410_width, a2410_height; + uae_u32 overlaylinetable[MAX_HEIGHT + 1]; + uae_u32 vramlinetab[MAX_HEIGHT + 1]; + int overlaylinetableindex; int a2410_vram_start_offset; uae_u8 *a2410_surface; int a2410_interlace; @@ -61,6 +64,9 @@ struct a2410_struct int a2410_hsync_max; bool a2410_visible; + int a2410_activecnt; + bool a2410_newactive, a2410_preactive; + addrbank *gfxbank; }; @@ -159,7 +165,7 @@ void m_to_shiftreg_cb(address_space space, offs_t offset, UINT16 *shiftreg) { memcpy(shiftreg, &gfxmem_banks[a2410_data.a2410_gfxboard]->baseaddr[TOWORD(offset)], 256 * sizeof(UINT16)); } -void m_from_shiftreg_cb(address_space space, offs_t offset, UINT16* shiftreg) +void m_from_shiftreg_cb(address_space space, offs_t offset, UINT16 *shiftreg) { memcpy(&gfxmem_banks[a2410_data.a2410_gfxboard]->baseaddr[TOWORD(offset)], shiftreg, 256 * sizeof(UINT16)); } @@ -190,8 +196,17 @@ static void mark_overlay(struct a2410_struct *data, int addr) if (!data->a2410_enabled) return; addr &= 0x1ffff; - addr /= OVERLAY_WIDTH / 8; - data->a2410_modified[addr] = true; + if (addr >= data->overlaylinetable[data->overlaylinetableindex] && addr < data->overlaylinetable[data->overlaylinetableindex + 1]) { + data->a2410_modified[data->overlaylinetableindex] = true; + } else { + for(int i = 0; i < MAX_HEIGHT; i++) { + if (addr >= data->overlaylinetable[i] && addr < data->overlaylinetable[i + 1]) { + data->a2410_modified[i] = true; + data->overlaylinetableindex = i; + break; + } + } + } } static void a2410_create_palette32(struct a2410_struct *data, int offset) @@ -219,6 +234,7 @@ static void a2410_create_palette32(struct a2410_struct *data, int offset) #endif } + static void write_ramdac(struct a2410_struct *data, int addr, uae_u8 v) { int coloridx = data->a2410_palette_index & 3; @@ -238,6 +254,7 @@ static void write_ramdac(struct a2410_struct *data, int addr, uae_u8 v) data->a2410_palette_index = 0; break; case 2: + data->a2410_palette_index &= ~3; if (data->a2410_palette_index >= 4 * 4 && data->a2410_palette_index < 8 * 4) { data->a2410_palette_control[data->a2410_palette_index / 4 - 4] = v; } @@ -279,11 +296,9 @@ static void write_ramdac(struct a2410_struct *data, int addr, uae_u8 v) data->a2410_palette_index = 0; } break; - default: - write_log(_T("Unknown write RAMDAC address %08x PC=%08x\n"), addr, M68K_GETPC); - break; } } + static uae_u8 read_ramdac(struct a2410_struct *data, int addr) { uae_u8 v = 0; @@ -315,13 +330,11 @@ static uae_u8 read_ramdac(struct a2410_struct *data, int addr) data->a2410_palette_index = 0; } break; - default: - write_log(_T("Unknown read RAMDAC address %08x PC=%08x\n"), addr, M68K_GETPC); - break; } return v; } + static bool valid_dma(struct a2410_struct *data, uaecptr addr) { // prevent recursive DMA @@ -348,7 +361,11 @@ UINT8 address_space::read_byte(UINT32 a) //write_log(_T("TMS byte read framebuffer %08x (%08x) = %02x PC=%08x\n"), aa, addr, v, M68K_GETPC); break; case A2410_BANK_RAMDAC: - v = read_ramdac(data, addr); + if (addr & 4) { + v = read_ramdac(data, addr & 3); + } else { + write_ramdac(data, addr & 3, 0xff); + } //write_log(_T("RAMDAC READ %08x = %02x PC=%08x\n"), aa, v, M68K_GETPC); break; case A2410_BANK_CONTROL: @@ -357,7 +374,7 @@ UINT8 address_space::read_byte(UINT32 a) break; case A2410_BANK_DMA: if (valid_dma(data, addr)) { - if (data->a2410_control & 4) + if (!(data->a2410_control & 4)) addr ^= 1; v = get_byte(addr); } @@ -394,7 +411,11 @@ UINT16 address_space::read_word(UINT32 a) //write_log(_T("TMS gfx word read %08x (%08x) = %04x PC=%08x\n"), aa, addr, v, M68K_GETPC); break; case A2410_BANK_RAMDAC: - v = read_ramdac(data, addr); + if (addr & 4) { + v = read_ramdac(data, addr & 3); + } else { + write_ramdac(data, addr & 3, 0xff); + } //write_log(_T("RAMDAC READ %08x = %02x PC=%08x\n"), aa, v, M68K_GETPC); break; case A2410_BANK_CONTROL: @@ -404,7 +425,7 @@ UINT16 address_space::read_word(UINT32 a) case A2410_BANK_DMA: if (valid_dma(data, addr)) { v = get_word(addr); - if (data->a2410_control & 4) + if (!(data->a2410_control & 4)) v = (v >> 8) | (v << 8); } break; @@ -435,8 +456,10 @@ void address_space::write_byte(UINT32 a, UINT8 b) //write_log(_T("TMS gfx byte write %08x (%08x) = %02x PC=%08x\n"), aa, addr, b, M68K_GETPC); break; case A2410_BANK_RAMDAC: - //write_log(_T("RAMDAC WRITE %08x = %02x PC=%08x\n"), aa, b, M68K_GETPC); - write_ramdac(data, addr, b); + //write_log(_T("RAMDAC WRITE %08x = %08x = %02x PC=%08x\n"), addr, aa, b, M68K_GETPC); + if (!(addr & 4)) { + write_ramdac(data, addr & 3, b); + } break; case A2410_BANK_CONTROL: write_log(_T("CONTROL WRITE %08x = %02x PC=%08x\n"), aa, b, M68K_GETPC); @@ -444,7 +467,7 @@ void address_space::write_byte(UINT32 a, UINT8 b) break; case A2410_BANK_DMA: if (valid_dma(data, addr)) { - if (data->a2410_control & 4) + if (!(data->a2410_control & 4)) addr ^= 1; put_byte(addr, b); } @@ -470,8 +493,9 @@ void address_space::write_word(UINT32 a, UINT16 b) case A2410_BANK_PROGRAM: data->program_ram[addr] = b >> 8; data->program_ram[addr + 1] = b & 0xff; - if (addr < 0x40000) + if (addr < 0x40000) { mark_overlay(data, addr); + } //write_log(_T("TMS program word write RAM %08x (%08x) = %04x PC=%08x\n"), aa, addr, b, M68K_GETPC); break; case A2410_BANK_FRAMEBUFFER: @@ -480,8 +504,10 @@ void address_space::write_word(UINT32 a, UINT16 b) //write_log(_T("TMS gfx word write %08x (%08x) = %04x PC=%08x\n"), aa, addr, b, M68K_GETPC); break; case A2410_BANK_RAMDAC: - //write_log(_T("RAMDAC WRITE %08x = %04x IDX=%d/%d PC=%08x\n"), aa, b, a2410_palette_index / 4, a2410_palette_index & 3, M68K_GETPC); - write_ramdac(data, addr, (uae_u8)b); + //write_log(_T("RAMDAC WRITE %08x = %08x = %04x (%d,%d) PC=%08x\n"), addr, aa, b, data->a2410_palette_index / 4, data->a2410_palette_index & 3, M68K_GETPC); + if (!(addr & 4)) { + write_ramdac(data, addr & 3, (uae_u8)b); + } break; case A2410_BANK_CONTROL: write_log(_T("CONTROL WRITE %08x = %04x PC=%08x\n"), aa, b, M68K_GETPC); @@ -489,7 +515,7 @@ void address_space::write_word(UINT32 a, UINT16 b) break; case A2410_BANK_DMA: if (valid_dma(data, addr)) { - if (data->a2410_control & 4) + if (!(data->a2410_control & 4)) b = (b >> 8) | (b << 8); put_word(addr, b); } @@ -509,46 +535,30 @@ static uae_u32 REGPARAM2 tms_bget(uaecptr addr) if (!(addr & 1)) vv >>= 8; v = (uae_u8)vv; - //write_log(_T("TMS read %08x = %02x PC=%08x\n"), addr, v & 0xff, M68K_GETPC); + //write_log(_T("tms_bget %08x = %02x PC=%08x\n"), addr, v & 0xff, M68K_GETPC); tms_execute_single(); return v; } + static uae_u32 REGPARAM2 tms_wget(uaecptr addr) { struct a2410_struct *data = &a2410_data; uae_u16 v; addr &= 65535; v = tms_device.host_r(tms_space, addr >> 1); - //write_log(_T("TMS read %08x = %04x PC=%08x\n"), addr, v & 0xffff, M68K_GETPC); + //write_log(_T("tms_wget %08x = %04x PC=%08x\n"), addr, v & 0xffff, M68K_GETPC); tms_execute_single(); return v; } -static uae_u32 REGPARAM2 tms_lget(uaecptr addr) -{ - uae_u32 v; - addr &= 65535; - v = tms_wget(addr) << 16; - v |= tms_wget(addr + 2); - return v; -} - static void REGPARAM2 tms_wput(uaecptr addr, uae_u32 w) { struct a2410_struct *data = &a2410_data; addr &= 65535; - //write_log(_T("TMS write %08x = %04x PC=%08x\n"), addr, w & 0xffff, M68K_GETPC); - tms_device.host_w(tms_space, addr >> 1, w); + tms_device.host_w(tms_space, addr >> 1, w); tms_execute_single(); } -static void REGPARAM2 tms_lput(uaecptr addr, uae_u32 l) -{ - addr &= 65535; - tms_wput(addr, l >> 16); - tms_wput(addr + 2, l); -} - static void REGPARAM2 tms_bput(uaecptr addr, uae_u32 b) { struct a2410_struct *data = &a2410_data; @@ -559,6 +569,21 @@ static void REGPARAM2 tms_bput(uaecptr addr, uae_u32 b) tms_execute_single(); } +static uae_u32 REGPARAM2 tms_lget(uaecptr addr) +{ + uae_u32 v; + addr &= 65535; + v = tms_wget(addr) << 16; + v |= tms_wget(addr + 2); + return v; +} +static void REGPARAM2 tms_lput(uaecptr addr, uae_u32 l) +{ + addr &= 65535; + tms_wput(addr, l >> 16); + tms_wput(addr + 2, l); +} + static addrbank tms_bank = { tms_lget, tms_wget, tms_bget, tms_lput, tms_wput, tms_bput, @@ -577,7 +602,6 @@ static void tms_reset(void *userdata) data->a2410_surface = NULL; data->a2410_modechanged = false; - data->a2410_gotmode = 0; data->a2410_interlace = 0; data->a2410_interrupt = 0; data->a2410_hsync_max = 2; @@ -665,11 +689,12 @@ void mscreen::configure(int width, int height, rectangle vis) if (data->a2410_interlace) data->a2410_height *= 2; data->a2410_modechanged = true; - data->a2410_gotmode = true; m_screen->height_v = height; m_screen->width_v = width; tms_rectangle = vis; write_log(_T("A2410 %d*%d -> %d*%d\n"), ow, oh, data->a2410_width, data->a2410_height); + memset(data->overlaylinetable, 0, sizeof(data->overlaylinetable)); + data->overlaylinetableindex = 0; data->a2410_hsync_max = data->a2410_height / 300; } @@ -693,21 +718,12 @@ static bool tms_toggle(void *userdata, int mode) return false; if (!mode) { - if (!data->a2410_enabled) - return false; data->a2410_enabled = false; - data->a2410_modechanged = false; - data->a2410_gotmode = -1; - data->a2410_visible = false; + data->a2410_modechanged = true; return true; } else { - if (!data->a2410_gotmode) - return false; - if (data->a2410_enabled) - return false; - data->a2410_gotmode = 1; + data->a2410_enabled = true; data->a2410_modechanged = true; - data->a2410_visible = true; return true; } return false; @@ -723,23 +739,68 @@ static void tms_vsync_handler2(struct a2410_struct *data, bool internalsync) tms34010_display_params parms; tms_device.get_display_params(&parms); - bool enabled = parms.enabled != 0 && data->a2410_gotmode > 0; + bool active = parms.enabled != 0; + + // don't disable display if parms.enabled is inactive less than 1 field + if (active != data->a2410_newactive) { + if (data->a2410_activecnt > 0) { + data->a2410_activecnt = 0; + data->a2410_newactive = active; + data->a2410_preactive = active; + } else if (active) { + data->a2410_preactive = active; + data->a2410_newactive = active; + data->request_fullrefresh = 1; + } else { + data->a2410_activecnt = 2; + data->a2410_preactive = data->a2410_newactive; + data->a2410_newactive = active; + active = data->a2410_preactive; + } + } else { + if (data->a2410_activecnt > 0) { + active = data->a2410_preactive; + data->a2410_activecnt--; + if (!data->a2410_activecnt) { + data->a2410_preactive = data->a2410_newactive; + active = data->a2410_newactive; + if (active) { + data->request_fullrefresh = 1; + } + } + } + } - if (!data->a2410_visible && data->a2410_modechanged) { + if (active && !data->a2410_visible && !data->a2410_active && !data->a2410_enabled) { gfxboard_rtg_enable_initial(monid, data->a2410_gfxboard); + data->a2410_visible = true; + tms_toggle(data, 1); + } else if ((!active || !data->a2410_enabled) && data->a2410_visible) { + if (gfxboard_switch_away(monid)) { + tms_toggle(data, 0); + data->a2410_visible = false; + } + if (data->a2410_surface) + gfx_unlock_picasso(monid, false); + data->a2410_surface = NULL; + return; + } else if (active && data->a2410_enabled && !data->a2410_visible) { + if (!gfxboard_rtg_enable_initial(monid, data->a2410_gfxboard)) { + data->a2410_visible = true; + tms_toggle(data, 1); + } } if (data->a2410_visible) { - if (enabled != data->a2410_enabled || data->a2410_modechanged) { + if (active != data->a2410_active || data->a2410_modechanged) { if (data->a2410_surface) gfx_unlock_picasso(monid, false); data->a2410_surface = NULL; - if (enabled) { - data->a2410_modechanged = false; + if (active) { data->fullrefresh = 2; } - data->a2410_enabled = enabled; + data->a2410_modechanged = false; write_log(_T("A2410 MONITOR=%d ACTIVE=%d\n"), monid, data->a2410_enabled); } @@ -759,6 +820,7 @@ static void tms_vsync_handler2(struct a2410_struct *data, bool internalsync) gfx_unlock_picasso(monid, false); } } + data->a2410_active = active; data->a2410_interlace = -data->a2410_interlace; @@ -815,16 +877,22 @@ static void tms_hsync_handler2(struct a2410_struct *data) tms_device.m_icount = 1000; tms_device.execute_run(); int a2410_vpos = data->tms_vp; + + tms34010_display_params parms; + tms_device.get_display_params(&parms); + data->tms_vp = tms_device.scanline_callback(NULL, data->tms_vp, data->a2410_interlace < 0); a2410_rethink(data); - if (!data->a2410_enabled) + if (!data->a2410_preactive) return; if (a2410_vpos == 0) { tms_vsync_handler2(data, true); - picasso_getwritewatch(data->a2410_gfxboard, data->a2410_vram_start_offset, NULL, NULL); + if (data->a2410_interlace <= 0) { + picasso_getwritewatch(data->a2410_gfxboard, data->a2410_vram_start_offset, NULL, NULL); + } } if (data->a2410_modechanged || !ad->picasso_on) @@ -834,52 +902,67 @@ static void tms_hsync_handler2(struct a2410_struct *data) data->fullrefresh--; } - tms34010_display_params parms; - tms_device.get_display_params(&parms); - data->a2410_displaywidth = parms.hsblnk - parms.heblnk; data->a2410_displayend = parms.heblnk; data->a2410_vertical_start = parms.veblnk; - int overlay_yoffset = a2410_vpos - data->a2410_vertical_start; + int yoffset = a2410_vpos - data->a2410_vertical_start; - int coladdr = parms.coladdr; + int coladdr = parms.coladdr & 0x1ff; int vramoffset = ((parms.rowaddr << 8) & 0x7ffff); - uae_u16 *vram = (uae_u16*)data->gfxbank->baseaddr + vramoffset; - - int overlayoffset = a2410_vpos - parms.veblnk; + int overlayoffset = (parms.rowaddr << 6) & 0x1ffff; + int overlayline = parms.yoffset; - if (overlay_yoffset < 0) + if (yoffset < 0 || yoffset >= MAX_HEIGHT || a2410_vpos < 0 || a2410_vpos >= MAX_HEIGHT) return; if (data->a2410_interlace) { - overlay_yoffset *= 2; - if (data->a2410_interlace < 0) - overlay_yoffset++; - } - - if (overlay_yoffset >= data->a2410_height || overlay_yoffset >= vidinfo->height) - return; - - if (!data->fullrefresh && !data->a2410_modified[overlay_yoffset]) { - if (!picasso_is_vram_dirty(data->a2410_gfxboard, data->gfxbank->start + (vramoffset << 1), data->a2410_displaywidth)) { - if (!picasso_is_vram_dirty(data->a2410_gfxboard, data->gfxbank->start + ((vramoffset + 0x200) << 1), data->a2410_displaywidth)) { - return; - } + yoffset *= 2; + if (data->a2410_interlace < 0) { + yoffset++; } } + uae_u16 *vram = (uae_u16 *)data->gfxbank->baseaddr + vramoffset; + data->overlaylinetable[a2410_vpos] = overlayoffset; + get_a2410_surface(data); uae_u8 *dst = data->a2410_surface; if (!dst) return; - data->a2410_modified[overlay_yoffset] = false; + if (yoffset >= data->a2410_height || yoffset >= vidinfo->maxheight) + return; + if (overlayline < 0 || overlayline >= MAX_HEIGHT) + return; + + bool linerefresh = false; + + if (data->vramlinetab[a2410_vpos] != vramoffset) { + data->vramlinetab[a2410_vpos] = vramoffset; + linerefresh = true; + } + + if (coladdr != data->coladdr) { + data->fullrefresh = 1; + data->coladdr = coladdr; + } + + if (!data->fullrefresh && !data->a2410_modified[a2410_vpos] && !linerefresh) { + if (!picasso_is_vram_dirty(data->a2410_gfxboard, data->gfxbank->start + (vramoffset << 1), data->a2410_displaywidth)) { + return; + } + } + + if (data->a2410_interlace <= 0) { + data->a2410_modified[a2410_vpos] = false; + } - dst += overlay_yoffset * vidinfo->rowbytes; + dst += yoffset * vidinfo->rowbytes; uae_u32 *dst32 = (uae_u32*)dst; - uae_u8 *overlay0 = data->program_ram + overlayoffset * OVERLAY_WIDTH / 8; + overlayoffset += (coladdr >> 3) << 1; + uae_u8 *overlay0 = data->program_ram + overlayoffset; uae_u8 *overlay1 = overlay0 + 0x20000; bool overlay0color = !(data->a2410_palette_control[6 - 4] & 0x40); @@ -899,7 +982,7 @@ static void tms_hsync_handler2(struct a2410_struct *data) int overlay_bitcount = 0; uae_u8 opix0 = 0, opix1 = 0; - for (int x = parms.heblnk; x < parms.hsblnk && xx < vidinfo->width; x += 2, xx += 2) { + for (int x = parms.heblnk; x < parms.hsblnk && xx < vidinfo->maxwidth; x += 2, xx += 2) { if (a2410_vpos >= parms.veblnk && a2410_vpos < parms.vsblnk) { @@ -909,8 +992,11 @@ static void tms_hsync_handler2(struct a2410_struct *data) overlay_offset++; } - uae_u16 pix = vram[coladdr & 0x1ff]; - coladdr++; + uae_u16 pix = 0; + if (coladdr < 0x400) { + pix = vram[coladdr]; + coladdr++; + } if (overlay0color || opix0 || opix1) { @@ -951,7 +1037,7 @@ static void tms_hsync_handler2(struct a2410_struct *data) } } - while (xx < vidinfo->width) { + while (xx < vidinfo->maxwidth) { *dst32++ = 0; xx++; } @@ -974,6 +1060,12 @@ void standard_irq_callback(int level) a2410_rethink(data); } +static void tms_refresh(void *userdata) +{ + struct a2410_struct *data = (struct a2410_struct *)userdata; + data->request_fullrefresh = 1; +} + struct gfxboard_func a2410_func { tms_init, @@ -981,6 +1073,7 @@ struct gfxboard_func a2410_func tms_reset, tms_hsync, tms_vsync, + tms_refresh, tms_toggle, tms_configured }; diff --git a/mame/tm34010/34010fld.c b/mame/tm34010/34010fld.c index ca05039d..e6f87153 100644 --- a/mame/tm34010/34010fld.c +++ b/mame/tm34010/34010fld.c @@ -484,13 +484,7 @@ UINT32 tms340x0_device::rfield_s_07(offs_t offset) UINT32 tms340x0_device::rfield_s_08(offs_t offset) { UINT32 ret; - if (offset & 0x07) - { - RFIELDMAC(0xff,9); - } - - else - ret = TMS34010_RDMEM(TOBYTE(offset)); + RFIELDMAC_8(); return (INT32)(INT8)ret; } diff --git a/mame/tm34010/34010gfx.c b/mame/tm34010/34010gfx.c index 6bfea235..d650cfaf 100644 --- a/mame/tm34010/34010gfx.c +++ b/mame/tm34010/34010gfx.c @@ -1096,6 +1096,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear dstbit += BITS_PER_PIXEL; if (dstbit > 16) { + if (m_plane_masking) dstword = do_plane_masking((this->*word_read)(*m_program, dstwordaddr << 1), dstword); (this->*word_write)(*m_program, dstwordaddr++ << 1, dstword); readwrites++; dstbit -= 16; @@ -1115,6 +1116,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear readwrites++; } + if (m_plane_masking) dstword = do_plane_masking((this->*word_read)(*m_program, dstwordaddr << 1), dstword); (this->*word_write)(*m_program, dstwordaddr++ << 1, dstword); readwrites++; } @@ -1459,6 +1461,7 @@ if ((daddr & (BITS_PER_PIXEL - 1)) != 0) osd_printf_debug("PIXBLT_R%d with odd d } /* write the result */ + if (m_plane_masking) dstword = do_plane_masking((this->*word_read)(*m_program, dwordaddr << 1), dstword); (this->*word_write)(*m_program, dwordaddr << 1, dstword); } @@ -1506,6 +1509,7 @@ if ((daddr & (BITS_PER_PIXEL - 1)) != 0) osd_printf_debug("PIXBLT_R%d with odd d } /* write the result */ + if (m_plane_masking) dstword = do_plane_masking((this->*word_read)(*m_program, dwordaddr << 1), dstword); (this->*word_write)(*m_program, dwordaddr << 1, dstword); } @@ -1549,6 +1553,7 @@ if ((daddr & (BITS_PER_PIXEL - 1)) != 0) osd_printf_debug("PIXBLT_R%d with odd d } /* write the result */ + if (m_plane_masking) dstword = do_plane_masking((this->*word_read)(*m_program, dwordaddr << 1), dstword); (this->*word_write)(*m_program, dwordaddr << 1, dstword); } @@ -1707,6 +1712,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt_b)(int dst_is_linear) } /* write the result */ + if (m_plane_masking) dstword = do_plane_masking((this->*word_read)(*m_program, dwordaddr << 1), dstword); (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); } @@ -1743,6 +1749,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt_b)(int dst_is_linear) } /* write the result */ + if (m_plane_masking) dstword = do_plane_masking((this->*word_read)(*m_program, dwordaddr << 1), dstword); (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); } @@ -1776,6 +1783,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt_b)(int dst_is_linear) } /* write the result */ + if (m_plane_masking) dstword = do_plane_masking((this->*word_read)(*m_program, dwordaddr << 1), dstword); (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); } @@ -1907,6 +1915,7 @@ void FUNCTION_NAME(tms340x0_device::fill)(int dst_is_linear) } /* write the result */ + if (m_plane_masking) dstword = do_plane_masking((this->*word_read)(*m_program, dwordaddr << 1), dstword); (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); } @@ -1934,6 +1943,7 @@ void FUNCTION_NAME(tms340x0_device::fill)(int dst_is_linear) } /* write the result */ + if (m_plane_masking) dstword = do_plane_masking((this->*word_read)(*m_program, dwordaddr << 1), dstword); (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); } @@ -1958,6 +1968,7 @@ void FUNCTION_NAME(tms340x0_device::fill)(int dst_is_linear) } /* write the result */ + if (m_plane_masking) dstword = do_plane_masking((this->*word_read)(*m_program, dwordaddr << 1), dstword); (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); } diff --git a/mame/tm34010/34010ops.c b/mame/tm34010/34010ops.c index 160d53e3..66e370ad 100644 --- a/mame/tm34010/34010ops.c +++ b/mame/tm34010/34010ops.c @@ -533,7 +533,7 @@ void tms340x0_device::dint(UINT16 op) } \ else \ { \ - *rd1 = quotient; \ + *rd1 = (INT32)quotient; \ *rd2 = remainder; \ SET_NZ_VAL(*rd1); \ } \ @@ -580,7 +580,7 @@ void tms340x0_device::divs_b(UINT16 op) { DIVS(B); } } \ else \ { \ - *rd1 = quotient; \ + *rd1 = (INT32)quotient; \ *rd2 = remainder; \ SET_Z_VAL(*rd1); \ } \ diff --git a/mame/tm34010/34010ops.h b/mame/tm34010/34010ops.h index 6dad233c..c8df512c 100644 --- a/mame/tm34010/34010ops.h +++ b/mame/tm34010/34010ops.h @@ -37,6 +37,21 @@ inline void tms340x0_device::TMS34010_WRMEM_DWORD(offs_t A, UINT32 V) m_program->write_word(A+2,V>>16); } +inline void tms340x0_device::TMS34010_WRMEM_WORD_MASK(offs_t A, UINT32 V) +{ + if (m_plane_masking) V = do_plane_masking(TMS34010_RDMEM_WORD(A), V); + + m_program->write_word(A, V); +} + +inline void tms340x0_device::TMS34010_WRMEM_DWORD_MASK(offs_t A, UINT32 V) +{ + if (m_plane_masking) V = do_plane_masking(TMS34010_RDMEM_DWORD(A), V); + + m_program->write_word(A, V); + m_program->write_word(A + 2, V >> 16); +} + /* IO registers accessor */ @@ -86,20 +101,16 @@ inline void tms340x0_device::TMS34010_WRMEM_DWORD(offs_t A, UINT32 V) } #define WFIELDMAC_8() \ - if (offset & 0x07) \ + if (true) \ { \ WFIELDMAC(0xff,9); \ } \ - else \ - TMS34010_WRMEM(TOBYTE(offset), data); #define RFIELDMAC_8() \ - if (offset & 0x07) \ + if (true) \ { \ RFIELDMAC(0xff,9); \ } \ - else \ - return TMS34010_RDMEM(TOBYTE(offset)); #define WFIELDMAC_32() \ if (offset & 0x0f) \ diff --git a/mame/tm34010/tms34010.cpp b/mame/tm34010/tms34010.cpp index 8f24c70c..e0e7462c 100644 --- a/mame/tm34010/tms34010.cpp +++ b/mame/tm34010/tms34010.cpp @@ -246,13 +246,20 @@ inline INT32 tms340x0_device::POP() } +UINT32 tms340x0_device::do_plane_masking(UINT32 r, UINT32 w) +{ + UINT32 pmask = IOREG(REG_PMASK); + pmask |= pmask << 16; + UINT32 o = (r & pmask) | (w & ~pmask); + return o; +} + /*************************************************************************** PIXEL READS ***************************************************************************/ #define RP(m1,m2) \ - /* TODO: Plane masking */ \ return (TMS34010_RDMEM_WORD(TOBYTE(offset & 0xfffffff0)) >> (offset & m1)) & m2; UINT32 tms340x0_device::read_pixel_1(offs_t offset) { RP(0x0f,0x01) } @@ -261,12 +268,10 @@ UINT32 tms340x0_device::read_pixel_4(offs_t offset) { RP(0x0c,0x0f) } UINT32 tms340x0_device::read_pixel_8(offs_t offset) { RP(0x08,0xff) } UINT32 tms340x0_device::read_pixel_16(offs_t offset) { - /* TODO: Plane masking */ return TMS34010_RDMEM_WORD(TOBYTE(offset & 0xfffffff0)); } UINT32 tms340x0_device::read_pixel_32(offs_t offset) { - /* TODO: Plane masking */ return TMS34010_RDMEM_DWORD(TOBYTE(offset & 0xffffffe0)); } @@ -295,14 +300,12 @@ UINT32 tms340x0_device::read_pixel_shiftreg(offs_t offset) UINT32 pix = TMS34010_RDMEM_WORD(a); \ UINT32 shiftcount = offset & m1; \ \ - /* TODO: plane masking */ \ data &= m2; \ pix = (pix & ~(m2 << shiftcount)) | (data << shiftcount); \ - TMS34010_WRMEM_WORD(a, pix); + TMS34010_WRMEM_WORD_MASK(a, pix); /* No Raster Op + Transparency */ #define WP_T(m1,m2) \ - /* TODO: plane masking */ \ data &= m2; \ if (data) \ { \ @@ -310,9 +313,8 @@ UINT32 tms340x0_device::read_pixel_shiftreg(offs_t offset) UINT32 pix = TMS34010_RDMEM_WORD(a); \ UINT32 shiftcount = offset & m1; \ \ - /* TODO: plane masking */ \ pix = (pix & ~(m2 << shiftcount)) | (data << shiftcount); \ - TMS34010_WRMEM_WORD(a, pix); \ + TMS34010_WRMEM_WORD_MASK(a, pix); \ } /* Raster Op + No Transparency */ #define WP_R(m1,m2) \ @@ -320,10 +322,9 @@ UINT32 tms340x0_device::read_pixel_shiftreg(offs_t offset) UINT32 pix = TMS34010_RDMEM_WORD(a); \ UINT32 shiftcount = offset & m1; \ \ - /* TODO: plane masking */ \ data = (this->*m_raster_op)(data & m2, (pix >> shiftcount) & m2) & m2; \ pix = (pix & ~(m2 << shiftcount)) | (data << shiftcount); \ - TMS34010_WRMEM_WORD(a, pix); + TMS34010_WRMEM_WORD_MASK(a, pix); /* Raster Op + Transparency */ #define WP_R_T(m1,m2) \ @@ -331,12 +332,11 @@ UINT32 tms340x0_device::read_pixel_shiftreg(offs_t offset) UINT32 pix = TMS34010_RDMEM_WORD(a); \ UINT32 shiftcount = offset & m1; \ \ - /* TODO: plane masking */ \ data = (this->*m_raster_op)(data & m2, (pix >> shiftcount) & m2) & m2; \ if (data) \ { \ pix = (pix & ~(m2 << shiftcount)) | (data << shiftcount); \ - TMS34010_WRMEM_WORD(a, pix); \ + TMS34010_WRMEM_WORD_MASK(a, pix); \ } /* No Raster Op + No Transparency */ @@ -346,13 +346,11 @@ void tms340x0_device::write_pixel_4(offs_t offset, UINT32 data) { WP(0x0c, 0x0f) void tms340x0_device::write_pixel_8(offs_t offset, UINT32 data) { WP(0x08, 0xff); } void tms340x0_device::write_pixel_16(offs_t offset, UINT32 data) { - /* TODO: plane masking */ - TMS34010_WRMEM_WORD(TOBYTE(offset & 0xfffffff0), data); + TMS34010_WRMEM_WORD_MASK(TOBYTE(offset & 0xfffffff0), data); } void tms340x0_device::write_pixel_32(offs_t offset, UINT32 data) { - /* TODO: plane masking */ - TMS34010_WRMEM_WORD(TOBYTE(offset & 0xffffffe0), data); + TMS34010_WRMEM_WORD_MASK(TOBYTE(offset & 0xffffffe0), data); } /* No Raster Op + Transparency */ @@ -362,15 +360,13 @@ void tms340x0_device::write_pixel_t_4(offs_t offset, UINT32 data) { WP_T(0x0c, 0 void tms340x0_device::write_pixel_t_8(offs_t offset, UINT32 data) { WP_T(0x08, 0xff); } void tms340x0_device::write_pixel_t_16(offs_t offset, UINT32 data) { - /* TODO: plane masking */ if (data) - TMS34010_WRMEM_WORD(TOBYTE(offset & 0xfffffff0), data); + TMS34010_WRMEM_WORD_MASK(TOBYTE(offset & 0xfffffff0), data); } void tms340x0_device::write_pixel_t_32(offs_t offset, UINT32 data) { - /* TODO: plane masking */ if (data) - TMS34010_WRMEM_DWORD(TOBYTE(offset & 0xffffffe0), data); + TMS34010_WRMEM_DWORD_MASK(TOBYTE(offset & 0xffffffe0), data); } /* Raster Op + No Transparency */ @@ -380,15 +376,13 @@ void tms340x0_device::write_pixel_r_4(offs_t offset, UINT32 data) { WP_R(0x0c, 0 void tms340x0_device::write_pixel_r_8(offs_t offset, UINT32 data) { WP_R(0x08, 0xff); } void tms340x0_device::write_pixel_r_16(offs_t offset, UINT32 data) { - /* TODO: plane masking */ UINT32 a = TOBYTE(offset & 0xfffffff0); - TMS34010_WRMEM_WORD(a, (this->*m_raster_op)(data, TMS34010_RDMEM_WORD(a))); + TMS34010_WRMEM_WORD_MASK(a, (this->*m_raster_op)(data, TMS34010_RDMEM_WORD(a))); } void tms340x0_device::write_pixel_r_32(offs_t offset, UINT32 data) { - /* TODO: plane masking */ UINT32 a = TOBYTE(offset & 0xffffffe0); - TMS34010_WRMEM_DWORD(a, (this->*m_raster_op)(data, TMS34010_RDMEM_DWORD(a))); + TMS34010_WRMEM_DWORD_MASK(a, (this->*m_raster_op)(data, TMS34010_RDMEM_DWORD(a))); } /* Raster Op + Transparency */ @@ -398,21 +392,19 @@ void tms340x0_device::write_pixel_r_t_4(offs_t offset, UINT32 data) { WP_R_T(0x0 void tms340x0_device::write_pixel_r_t_8(offs_t offset, UINT32 data) { WP_R_T(0x08,0xff); } void tms340x0_device::write_pixel_r_t_16(offs_t offset, UINT32 data) { - /* TODO: plane masking */ UINT32 a = TOBYTE(offset & 0xfffffff0); data = (this->*m_raster_op)(data, TMS34010_RDMEM_WORD(a)); if (data) - TMS34010_WRMEM_WORD(a, data); + TMS34010_WRMEM_WORD_MASK(a, data); } void tms340x0_device::write_pixel_r_t_32(offs_t offset, UINT32 data) { - /* TODO: plane masking */ UINT32 a = TOBYTE(offset & 0xffffffe0); data = (this->*m_raster_op)(data, TMS34010_RDMEM_DWORD(a)); if (data) - TMS34010_WRMEM_DWORD(a, data); + TMS34010_WRMEM_DWORD_MASK(a, data); } /* Shift register write */ @@ -1161,10 +1153,7 @@ WRITE16_MEMBER( tms340x0_device::io_register_w ) break; case REG_PMASK: -#if 0 - if (data) logerror("Plane masking not supported. PC=%08X\n", space.device().safe_pc()); -#endif - if (data) logerror("Plane masking not supported. PMASK=%04x PC=%08X\n", data, m_pc); + m_plane_masking = data != 0; break; case REG_DPYCTL: @@ -1571,17 +1560,28 @@ WRITE16_MEMBER( tms340x0_device::host_w ) { int reg = offset; unsigned int addr; + unsigned int hstctlh = IOREG(REG_HSTCTLH); switch (reg) { /* upper 16 bits of the address */ case TMS34010_HOST_ADDRESS_H: IOREG(REG_HSTADRH) = data; + // !LBL && !INCW + if (!(hstctlh & 0x2000) && !(hstctlh & 0x0800)) { + addr = (IOREG(REG_HSTADRH) << 16) | IOREG(REG_HSTADRL); + m_prefetch_data = TMS34010_RDMEM_WORD(TOBYTE(addr & 0xfffffff0)); + } break; /* lower 16 bits of the address */ case TMS34010_HOST_ADDRESS_L: IOREG(REG_HSTADRL) = data; + // LBL && !INCW + if ((hstctlh & 0x2000) && !(hstctlh & 0x0800)) { + addr = (IOREG(REG_HSTADRH) << 16) | IOREG(REG_HSTADRL); + m_prefetch_data = TMS34010_RDMEM_WORD(TOBYTE(addr & 0xfffffff0)); + } break; /* actual data */ @@ -1590,6 +1590,7 @@ WRITE16_MEMBER( tms340x0_device::host_w ) /* write to the address */ addr = (IOREG(REG_HSTADRH) << 16) | IOREG(REG_HSTADRL); TMS34010_WRMEM_WORD(TOBYTE(addr & 0xfffffff0), data); + m_prefetch_data = data; /* optional postincrement */ if (IOREG(REG_HSTCTLH) & 0x0800) @@ -1646,18 +1647,18 @@ READ16_MEMBER( tms340x0_device::host_r ) /* actual data */ case TMS34010_HOST_DATA: + result = m_prefetch_data; /* read from the address */ addr = (IOREG(REG_HSTADRH) << 16) | IOREG(REG_HSTADRL); - result = TMS34010_RDMEM_WORD(TOBYTE(addr & 0xfffffff0)); - - /* optional postincrement (it says preincrement, but data is preloaded, so it - is effectively a postincrement */ + /* optional preincrement */ if (IOREG(REG_HSTCTLH) & 0x1000) { addr += 0x10; IOREG(REG_HSTADRH) = addr >> 16; IOREG(REG_HSTADRL) = (UINT16)addr; } + m_prefetch_data = TMS34010_RDMEM_WORD(TOBYTE(addr & 0xfffffff0)); + break; /* control register */ diff --git a/mame/tm34010/tms34010.h b/mame/tm34010/tms34010.h index bc61ab11..91c2afd7 100644 --- a/mame/tm34010/tms34010.h +++ b/mame/tm34010/tms34010.h @@ -347,6 +347,8 @@ protected: direct_read_data *m_direct; UINT32 m_pixclock; /* the pixel clock (0 means don't adjust screen size) */ int m_pixperclock; /* pixels per clock */ + bool m_plane_masking; + UINT16 m_prefetch_data; // emu_timer *m_scantimer; #if 0 @@ -381,6 +383,8 @@ protected: UINT32 TMS34010_RDMEM_DWORD(offs_t A); void TMS34010_WRMEM_DWORD(offs_t A, UINT32 V); + void TMS34010_WRMEM_DWORD_MASK(offs_t A, UINT32 V); + void TMS34010_WRMEM_WORD_MASK(offs_t A, UINT32 V); void SET_ST(UINT32 st); void RESET_ST(); UINT32 ROPCODE(); @@ -1027,6 +1031,7 @@ protected: void check_interrupt(); void set_pixel_function(); void set_raster_op(); + UINT32 do_plane_masking(UINT32 r, UINT32 w); }; -- 2.47.3