From 523ddb0892444650df28078bfd9f397f9164ccd9 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Fri, 9 Apr 2021 21:39:28 +0300 Subject: [PATCH] Custom emulation update WIP, HBSTRT/STOP full resolution support. --- custom.cpp | 214 +++++++++++++++++++++++++++++++--------------- debug.cpp | 27 ++++-- drawing.cpp | 21 ++--- include/custom.h | 54 ++++++------ include/debug.h | 1 + include/drawing.h | 44 ++++++++-- 6 files changed, 241 insertions(+), 120 deletions(-) diff --git a/custom.cpp b/custom.cpp index 1dad84ea..055f6d64 100644 --- a/custom.cpp +++ b/custom.cpp @@ -281,7 +281,8 @@ int maxvpos = MAXVPOS_PAL; int maxvpos_nom = MAXVPOS_PAL; // nominal value (same as maxvpos but "faked" maxvpos in fake 60hz modes) int maxvpos_display = MAXVPOS_PAL; // value used for display size int hsyncendpos, hsyncstartpos; -int hsyncstartpos_start, hsynctotal; +static int hsyncstartpos_start; +int hsynctotal; static int maxvpos_total = 511; int minfirstline = VBLANK_ENDLINE_PAL; int firstblankedline; @@ -510,6 +511,7 @@ static int bprun_pipeline_flush_delay; static uae_u16 rga_pipeline[256]; static int rga_pipeline_bpl_read, rga_pipeline_bpl_write; static int rga_pipeline_copper_read; +static int rga_pipeline_sprite_read; #define RGA_PIPELINE_MASK 255 struct custom_store custom_storage[256]; @@ -3522,7 +3524,7 @@ static int tospritexddf(int ddf) } static int fromspritexdiw (int ddf) { - return coord_hw_to_window_x (ddf >> sprite_buffer_res) + (DIW_DDF_OFFSET << lores_shift); + return coord_hw_to_window_x_lores(ddf >> sprite_buffer_res) + (DIW_DDF_OFFSET << lores_shift); } static void calcsprite(void) @@ -3566,7 +3568,7 @@ static void decide_sprites(int hpos, bool usepointx, bool quick) // if sprite is at the very edge of right border point = hpos * 2 - DDF_OFFSET; if (hpos >= maxhpos) { - point += (extrahpos - 2) * 2; + point += (extrahpos >> 2) - 2; } if (nodraw () || hpos < 0x14 || nr_armed == 0 || point == last_sprite_point) @@ -3739,7 +3741,7 @@ static void finish_decisions(int hpos) } } #endif - record_color_change2(hsyncstartpos, 0xffff, 0); + record_color_change2(hsyncstartpos >> CCK_SHRES_SHIFT, 0xffff, 0); if (thisline_decision.plfleft >= 0 && thisline_decision.plflinelen < 0) { thisline_decision.plfright = thisline_decision.plfleft; thisline_decision.plflinelen = 0; @@ -4003,11 +4005,13 @@ static void dumpsync (void) if (cnt < 0) return; cnt--; - write_log (_T("BEAMCON0=%04X VTOTAL=%04X HTOTAL=%04X\n"), new_beamcon0, vtotal, htotal); - write_log (_T(" HSSTOP=%04X HBSTRT=%04X HBSTOP=%04X\n"), hsstop, hbstrt, hbstop); - write_log (_T(" VSSTOP=%04X VBSTRT=%04X VBSTOP=%04X\n"), vsstop, vbstrt, vbstop); - write_log (_T(" HSSTRT=%04X VSSTRT=%04X HCENTER=%04X\n"), hsstrt, vsstrt, hcenter); - write_log (_T(" HSYNCSTART=%04X HSYNCEND=%04X\n"), hsyncstartpos, hsyncendpos); + write_log(_T("BEAMCON0=%04X VTOTAL=%04X HTOTAL=%04X\n"), new_beamcon0, vtotal, htotal); + write_log(_T(" HSSTOP=%04X HBSTRT=%04X HBSTOP=%04X\n"), hsstop, hbstrt, hbstop); + write_log(_T(" VSSTOP=%04X VBSTRT=%04X VBSTOP=%04X\n"), vsstop, vbstrt, vbstop); + write_log(_T(" HSSTRT=%04X VSSTRT=%04X HCENTER=%04X\n"), hsstrt, vsstrt, hcenter); + write_log(_T(" HSYNCSTART=%04X.%d HSYNCEND=%04X.%d\n"), + hsyncstartpos >> CCK_SHRES_SHIFT, hsyncstartpos & ((1 << CCK_SHRES_SHIFT) - 1), + hsyncendpos >> CCK_SHRES_SHIFT, hsyncendpos & ((1 << CCK_SHRES_SHIFT) - 1)); } int current_maxvpos(void) @@ -4051,52 +4055,61 @@ static void updateextblk(void) { if ((beamcon0 & 0x80) && (beamcon0 & 0x0100)) { - hsyncstartpos = hsstrt; - hsyncendpos = hsstop; + uae_u16 hbstrt_v = (hbstrt & 0xff) << 3; + if (aga_mode) { + hbstrt_v |= (hbstrt >> 8) & 7; + } + uae_u16 hbstop_v = (hbstop & 0xff) << 3; + if (aga_mode) { + hbstop_v |= (hbstop >> 8) & 7; + } + + hsyncstartpos = hsstrt << CCK_SHRES_SHIFT; + hsyncendpos = hsstop << CCK_SHRES_SHIFT; if ((bplcon0 & 1) && (bplcon3 & 1)) { - if (hbstrt > maxhpos / 2) { - if (hsyncstartpos < hbstrt) - hsyncstartpos = hbstrt; + if (hbstrt_v > (maxhpos << CCK_SHRES_SHIFT) / 2) { + if (hsyncstartpos < hbstrt_v) + hsyncstartpos = hbstrt_v; } else { - if (hsyncstartpos > hbstrt) - hsyncstartpos = hbstrt; + if (hsyncstartpos > hbstrt_v) + hsyncstartpos = hbstrt_v; } - if (hbstop > maxhpos / 2) { - if (hsyncendpos > hbstop) - hsyncendpos = hbstop; + if (hbstop_v > (maxhpos << CCK_SHRES_SHIFT) / 2) { + if (hsyncendpos > hbstop_v) + hsyncendpos = hbstop_v; } else { - if (hsyncendpos < hbstop) - hsyncendpos = hbstop; + if (hsyncendpos < hbstop_v) + hsyncendpos = hbstop_v; } } hsyncstartpos_start = hsyncstartpos; if (hsyncstartpos < hsyncendpos) { - hsyncstartpos = maxhpos + hsyncstartpos; + hsyncstartpos = (maxhpos << CCK_SHRES_SHIFT) + hsyncstartpos; hsynctotal = hsyncstartpos; } else { - hsynctotal = maxhpos + hsyncstartpos; + hsynctotal = (maxhpos << CCK_SHRES_SHIFT) + hsyncstartpos; } hsyncendpos--; - if (hsyncendpos < 2) { - hsyncendpos = 2; + if (hsyncendpos < (2 << CCK_SHRES_SHIFT)) { + hsyncendpos = 2 << CCK_SHRES_SHIFT; } - if (hsyncstartpos - hsyncendpos < maxhpos / 2) { - hsyncstartpos = maxhpos; + if (hsyncstartpos - hsyncendpos < (maxhpos << CCK_SHRES_SHIFT) / 2) { + hsyncstartpos = maxhpos << CCK_SHRES_SHIFT; } } else { - hsyncstartpos_start = 13; - hsyncstartpos = maxhpos_short + hsyncstartpos_start; - hsyncendpos = 24; - hsynctotal = 234; + hsyncstartpos_start = 13 << CCK_SHRES_SHIFT; + hsyncstartpos = (maxhpos_short << CCK_SHRES_SHIFT) + hsyncstartpos_start; + hsyncendpos = 24 << CCK_SHRES_SHIFT; + hsynctotal = 234 << CCK_SHRES_SHIFT; } calcdiw(); @@ -4244,8 +4257,8 @@ void compute_framesync(void) if (vres2 > VRES_QUAD) vres2 = VRES_QUAD; - int start = hsyncstartpos; //hbstrt; - int stop = hsyncendpos; //hbstop; + int start = hsyncstartpos >> CCK_SHRES_SHIFT; + int stop = hsyncendpos >> CCK_SHRES_SHIFT; vidinfo->drawbuffer.inwidth = ((maxhpos - (maxhpos - start + DISPLAY_LEFT_SHIFT / 2) + 1) * 2) << res2; vidinfo->drawbuffer.inxoffset = stop * 2; @@ -6566,6 +6579,25 @@ static void do_copper_fetch(int hpos, uae_u16 id) { if (id == 0x8f) { // copper allocated cycle without DMA request + switch (cop_state.state) + { + case COP_wait: +#ifdef DEBUGGER + if (debug_dma) + record_dma_event(DMA_EVENT_COPPERWAKE, hpos, vpos); + if (debug_copper) + record_copper(cop_state.ip - 4, 0xffffffff, cop_state.ir[0], cop_state.ir[1], hpos, vpos); +#endif + break; + case COP_skip: +#ifdef DEBUGGER + if (debug_dma && cop_state.ignore_next > 0) + record_dma_event(DMA_EVENT_COPPERSKIP, hpos, vpos); + if (debug_copper) + record_copper(cop_state.ip - 4, 0xffffffff, cop_state.ir[0], cop_state.ir[1], hpos, vpos); +#endif + break; + } return; } @@ -7030,19 +7062,15 @@ static void update_copper(int until_hpos) // Wait finished, request IR1. case COP_wait: { + if (hpos == 2 - COPPER_CYCLE_POLARITY) { + goto next; + } if (copper_cant_read(cp, 0x84)) { goto next; } cop_state.state = COP_read1; -#ifdef DEBUGGER - if (debug_dma) - record_dma_event(DMA_EVENT_COPPERWAKE, hpos, vpos); - if (debug_copper) - record_copper(cop_state.ip - 4, 0xffffffff, cop_state.ir[0], cop_state.ir[1], hpos, vpos); -#endif - } break; @@ -7079,18 +7107,13 @@ static void update_copper(int until_hpos) // SKIP finished. Request IR1. case COP_skip: { - + if (hpos == 2 - COPPER_CYCLE_POLARITY) { + goto next; + } if (copper_cant_read(cp, 0x85)) { goto next; } cop_state.state = COP_read1; - -#ifdef DEBUGGER - if (debug_dma && cop_state.ignore_next > 0) - record_dma_event(DMA_EVENT_COPPERSKIP, hpos, vpos); - if (debug_copper) - record_copper(cop_state.ip - 4, 0xffffffff, cop_state.ir[0], cop_state.ir[1], hpos, vpos); -#endif } break; @@ -7282,13 +7305,65 @@ static void sprite_fetch_full(struct sprite *s, int hpos, int cycle, int mode, u *v2 = data322; } +static void do_sprite_dma(uae_u16 dat, int hpos) +{ + int num = dat & 7; + struct sprite *s = &spr[num]; + uae_u32 data321, data322; + uae_u16 data; + bool cycle = (dat & 8) != 0; + + sprite_fetch_full(s, hpos, cycle, false, &data, &data321, &data322); + if (1) { + if (cycle) { + SPRxDATB_1(data, num, hpos); + } else { + SPRxDATA_1(data, num, hpos); + } +#ifdef AGA + switch (sprite_width) + { + case 64: + if (cycle == 0) { + s->data[1] = data321; + s->data[2] = data322 >> 16; + s->data[3] = data322; + } else { + s->datb[1] = data321; + s->datb[2] = data322 >> 16; + s->datb[3] = data322; + } + break; + case 32: + if (cycle == 0) { + s->data[1] = data321; + s->data[2] = data; + s->data[3] = data321; + } else { + s->datb[1] = data321; + s->datb[2] = data; + s->datb[3] = data321; + } + break; + } +#endif + } else { + if (cycle) { + SPRxPOS_1(data, num, hpos); + } else { + SPRxCTL_1(data, num, hpos); + } + } + +} + static void do_sprites_1(int num, int cycle, int hpos) { struct sprite *s = &spr[num]; int posctl = 0; uae_u16 data; // fetch both sprite pairs even if DMA was switched off between sprites - int isdma = dmaen (DMA_SPRITE) || ((num & 1) && spr[num & ~1].dmacycle); + int isdma = dmaen(DMA_SPRITE) || ((num & 1) && spr[num & ~1].dmacycle); bool unaligned = (spr[num].pt & 2) != 0; if (cant_this_last_line()) @@ -7296,33 +7371,33 @@ static void do_sprites_1(int num, int cycle, int hpos) // see SPRxCTRL below // if (isdma && vpos == sprite_vblank_endline) -// spr_arm (num, 0); +// spr_arm(num, 0); #ifdef AGA if (isdma && s->dblscan && (fmode & 0x8000) && (vpos & 1) != (s->vstart & 1) && s->dmastate) { - spr_arm (num, 1); + spr_arm(num, 1); return; } #endif #if SPRITE_DEBUG >= 3 * 256 if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) - write_log (_T("%d:%d:slot%d:%d\n"), vpos, hpos, num, cycle); + write_log(_T("%d:%d:slot%d:%d\n"), vpos, hpos, num, cycle); #endif if (vpos == s->vstart) { #if SPRITE_DEBUG > 0 if (!s->dmastate && vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) - write_log (_T("%d:%d:SPR%d START\n"), vpos, hpos, num); + write_log(_T("%d:%d:SPR%d START\n"), vpos, hpos, num); #endif s->dmastate = 1; if (s->ptxvpos2 == vpos && hpos < s->ptxhpos2) return; if (num == 0 && cycle == 0) - cursorsprite (); + cursorsprite(); } if (vpos == s->vstop || vpos == sprite_vblank_endline) { #if SPRITE_DEBUG > 0 if (s->dmastate && vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) - write_log (_T("%d:%d:SPR%d STOP\n"), vpos, hpos, num); + write_log(_T("%d:%d:SPR%d STOP\n"), vpos, hpos, num); #endif s->dmastate = 0; } @@ -7344,16 +7419,16 @@ static void do_sprites_1(int num, int cycle, int hpos) if (start_before_dma && s->armed) { maybe_decide_sprites(num, hpos); } - SPRxPOS_1 (data, num, hpos); + SPRxPOS_1(data, num, hpos); s->dmacycle = 1; } else { // This is needed to disarm previous field's sprite. // It can be seen on OCS Agnus + ECS Denise combination where // this cycle is disabled due to weird DDFTSTR=$18 copper list // which causes corrupted sprite to "wrap around" the display. - SPRxCTL_1 (data, num, hpos); + SPRxCTL_1(data, num, hpos); s->dmastate = 0; - sprstartstop (s); + sprstartstop(s); } } if (vpos == sprite_vblank_endline) { @@ -7362,7 +7437,7 @@ static void do_sprites_1(int num, int cycle, int hpos) } #if SPRITE_DEBUG >= 256 if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) { - write_log (_T("%d:%d:dma:P=%06X "), vpos, hpos, s->pt); + write_log(_T("%d:%d:dma:P=%06X "), vpos, hpos, s->pt); } #endif } @@ -7371,7 +7446,7 @@ static void do_sprites_1(int num, int cycle, int hpos) sprite_fetch_full(s, hpos, cycle, true, &data, &data321, &data322); #if SPRITE_DEBUG >= 256 if (vpos >= SPRITE_DEBUG_MINY && vpos <= SPRITE_DEBUG_MAXY && (SPRITE_DEBUG & (1 << num))) { - write_log (_T("%d:%d:dma:P=%06X "), vpos, hpos, s->pt); + write_log(_T("%d:%d:dma:P=%06X "), vpos, hpos, s->pt); } #endif if (cycle == 0) { @@ -7379,7 +7454,7 @@ static void do_sprites_1(int num, int cycle, int hpos) if (start_before_dma) { maybe_decide_sprites(num, hpos); } - SPRxDATA_1 (data, num, hpos); + SPRxDATA_1(data, num, hpos); s->dmacycle = 1; } else { // This is needed if xpos is between DATA and DATB fetches @@ -7388,7 +7463,7 @@ static void do_sprites_1(int num, int cycle, int hpos) if (start_before_dma) { maybe_decide_sprites(num, hpos); } - SPRxDATB_1 (data, num, hpos); + SPRxDATB_1(data, num, hpos); } #ifdef AGA switch (sprite_width) @@ -9528,13 +9603,13 @@ static void hsync_handler_post (bool onvsync) int diwfirstword_lores = diwfirstword; if (diwlastword_lores > diwlastword_total) { diwlastword_total = diwlastword_lores; - if (diwlastword_total > coord_diw_lores_to_window_x(hsyncstartpos * 2)) - diwlastword_total = coord_diw_lores_to_window_x(hsyncstartpos * 2); + if (diwlastword_total > coord_diw_shres_to_window_x(hsyncstartpos)) + diwlastword_total = coord_diw_shres_to_window_x(hsyncstartpos); } if (diwfirstword_lores < diwfirstword_total) { diwfirstword_total = diwfirstword_lores; - if (diwfirstword_total < coord_diw_lores_to_window_x(hsyncendpos * 2)) - diwfirstword_total = coord_diw_lores_to_window_x(hsyncendpos * 2); + if (diwfirstword_total < coord_diw_shres_to_window_x(hsyncendpos)) + diwfirstword_total = coord_diw_shres_to_window_x(hsyncendpos); firstword_bplcon1 = bplcon1; } } @@ -9602,7 +9677,7 @@ static void hsync_handler (void) uae_reset (0, 0); return; } - eventtab[ev_hsynch].evtime = get_cycles() + hsyncstartpos_start * CYCLE_UNIT; + eventtab[ev_hsynch].evtime = get_cycles() + (hsyncstartpos_start >> CCK_SHRES_SHIFT) * CYCLE_UNIT; eventtab[ev_hsynch].active = 1; events_schedule(); @@ -9690,6 +9765,7 @@ void custom_reset (bool hardreset, bool keyboardreset) rga_pipeline_bpl_read = 0; rga_pipeline_bpl_write = 3; rga_pipeline_copper_read = 2; + rga_pipeline_sprite_read = 3; if (!savestate_state) { cia_hsync = 0; @@ -10385,8 +10461,8 @@ static int REGPARAM2 custom_wput_1 (int hpos, uaecptr addr, uae_u32 value, int n case 0x1DC: BEAMCON0(value); break; case 0x1C0: if (htotal != value) { htotal = value & (MAXHPOS_ROWS - 1); varsync(); } break; case 0x1C2: if (hsstop != value) { hsstop = value & (MAXHPOS_ROWS - 1); varsync(); } break; - case 0x1C4: if (hbstrt != value) { hbstrt = value & (MAXHPOS_ROWS - 1); varsync(); } break; - case 0x1C6: if (hbstop != value) { hbstop = value & (MAXHPOS_ROWS - 1); varsync();} break; + case 0x1C4: if (hbstrt != value) { hbstrt = value & 0x7ff; varsync(); } break; + case 0x1C6: if (hbstop != value) { hbstop = value & 0x7ff; varsync();} break; case 0x1C8: if (vtotal != value) { vtotal = value & (MAXVPOS_LINES_ECS - 1); varsync(); } break; case 0x1CA: if (vsstop != value) { vsstop = value & (MAXVPOS_LINES_ECS - 1); varsync(); } break; case 0x1CC: if (vbstrt < value || vbstrt > (value & (MAXVPOS_LINES_ECS - 1)) + 1) { vbstrt = value & (MAXVPOS_LINES_ECS - 1); varsync(); } break; diff --git a/debug.cpp b/debug.cpp index afcfcd81..3b4e3164 100644 --- a/debug.cpp +++ b/debug.cpp @@ -1319,6 +1319,7 @@ void record_dma_reset (void) dr2 = &dr[v * NR_DMA_REC_HPOS + h]; memset (dr2, 0, sizeof (struct dma_rec)); dr2->reg = 0xffff; + dr2->cf_reg = 0xffff; dr2->addr = 0xffffffff; } } @@ -1850,6 +1851,9 @@ void record_dma_write(uae_u16 reg, uae_u32 dat, uae_u32 addr, int hpos, int vpos dr = &dma_record[dma_record_toggle][vpos * NR_DMA_REC_HPOS + hpos]; dma_record_frame[dma_record_toggle] = timeframes; if (dr->reg != 0xffff) { + dr->cf_reg = reg; + dr->cf_dat = dat; + dr->cf_addr = addr; dma_conflict(vpos, hpos, dr, reg, false); return; } @@ -1865,7 +1869,11 @@ struct dma_rec *last_dma_rec; void record_dma_read_value(uae_u32 v) { if (last_dma_rec) { - last_dma_rec->dat = v; + if (last_dma_rec->cf_reg != 0xffff) { + last_dma_rec->cf_dat = v; + } else { + last_dma_rec->dat = v; + } } } void record_dma_read(uae_u16 reg, uae_u32 addr, int hpos, int vpos, int type, int extra) @@ -1888,6 +1896,8 @@ void record_dma_read(uae_u16 reg, uae_u32 addr, int hpos, int vpos, int type, in dma_record_frame[dma_record_toggle] = timeframes; if (dr->reg != 0xffff) { dma_conflict(vpos, hpos, dr, reg, false); + dr->cf_reg = reg; + dr->cf_addr = addr; return; } dr->reg = reg; @@ -1909,6 +1919,7 @@ static bool get_record_dma_info(struct dma_rec *dr, int hpos, int vpos, uae_u32 const TCHAR *sr; int br = dr->extra & 7; int chcnt = -1; + TCHAR srtext[10]; if (l1) l1[0] = 0; @@ -1976,6 +1987,12 @@ static bool get_record_dma_info(struct dma_rec *dr, int hpos, int vpos, uae_u32 sr = _T("BPL"); chcnt = br + 1; } + if (dr->cf_reg != 0xffff) { + _stprintf(srtext, _T("!%03x "), dr->cf_reg); + chcnt = -1; + } else { + _tcscpy(srtext, sr); + } _stprintf (l1, _T("[%02X %3d]"), hpos, hpos); if (l4) { @@ -1998,14 +2015,14 @@ static bool get_record_dma_info(struct dma_rec *dr, int hpos, int vpos, uae_u32 } else { if (chcnt >= 0) { if (regsize == 3) - _stprintf(l2, _T("%3s%d %03X"), sr, chcnt, r); + _stprintf(l2, _T("%3s%d %03X"), srtext, chcnt, r); else - _stprintf(l2, _T("%4s%d %02X"), sr, chcnt, r); + _stprintf(l2, _T("%4s%d %02X"), srtext, chcnt, r); } else { if (regsize == 3) - _stprintf(l2, _T("%4s %03X"), sr, r); + _stprintf(l2, _T("%4s %03X"), srtext, r); else - _stprintf(l2, _T("%5s %02X"), sr, r); + _stprintf(l2, _T("%5s %02X"), srtext, r); } } if (l3) { diff --git a/drawing.cpp b/drawing.cpp index 4dd75874..698dcd7b 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -472,10 +472,11 @@ static void set_blanking_limits(void) hblank_right_stop = visible_right_stop; if (programmedmode) { - if (hblank_left_start < coord_hw_to_window_x(hsyncendpos * 2 + 1)) - hblank_left_start = coord_hw_to_window_x(hsyncendpos * 2 + 1); - if (hblank_right_stop > coord_hw_to_window_x(hsyncstartpos * 2 + 1)) - hblank_right_stop = coord_hw_to_window_x(hsyncstartpos * 2 + 1); + // has hires pixel offset + if (hblank_left_start < coord_hw_to_window_x_shres(hsyncendpos - 2)) + hblank_left_start = coord_hw_to_window_x_shres(hsyncendpos - 2); + if (hblank_right_stop > coord_hw_to_window_x_shres(hsyncstartpos - 1)) + hblank_right_stop = coord_hw_to_window_x_shres(hsyncstartpos - 1); } } @@ -643,8 +644,8 @@ int get_custom_limits (int *pw, int *ph, int *pdx, int *pdy, int *prealh) if (plflastline_total < 4) plflastline_total = last_planes_vpos; - ddffirstword_total = coord_hw_to_window_x (ddffirstword_total * 2 + DIW_DDF_OFFSET); - ddflastword_total = coord_hw_to_window_x (ddflastword_total * 2 + DIW_DDF_OFFSET); + ddffirstword_total = coord_hw_to_window_x_lores(ddffirstword_total * 2 + DIW_DDF_OFFSET); + ddflastword_total = coord_hw_to_window_x_lores(ddflastword_total * 2 + DIW_DDF_OFFSET); if (doublescan <= 0 && !programmedmode) { int min = coord_diw_lores_to_window_x (92); @@ -923,8 +924,8 @@ static void pfield_init_linetoscr (bool border) ddf_left = DISPLAY_LEFT_SHIFT; /* Compute datafetch start/stop in pixels; native display coordinates. */ - native_ddf_left = coord_hw_to_window_x(ddf_left); - native_ddf_right = coord_hw_to_window_x(ddf_right); + native_ddf_left = coord_hw_to_window_x_lores(ddf_left); + native_ddf_right = coord_hw_to_window_x_lores(ddf_right); // Blerkenwiegel/Scoopex workaround native_ddf_left2 = native_ddf_left; @@ -977,7 +978,7 @@ static void pfield_init_linetoscr (bool border) if (playfield_end < linetoscr_diw_end && hblank_right_stop > playfield_end) { playfield_end = linetoscr_diw_end; } - int left = coord_hw_to_window_x(dp_for_drawing->plfleft * 2 - DDF_OFFSET); + int left = coord_hw_to_window_x_lores(dp_for_drawing->plfleft * 2 - DDF_OFFSET); if (left < visible_left_border) left = visible_left_border; if (left < playfield_start && left >= linetoscr_diw_start) { @@ -1020,7 +1021,7 @@ static void pfield_init_linetoscr (bool border) if (playfield_start < visible_left_border) playfield_start = visible_left_border; #endif - max = coord_hw_to_window_x(max >> sprite_buffer_res) + (DIW_DDF_OFFSET << lores_shift); + max = coord_hw_to_window_x_lores(max >> sprite_buffer_res) + (DIW_DDF_OFFSET << lores_shift); if (max > playfield_end) playfield_end = max; if (playfield_end > visible_right_border) diff --git a/include/custom.h b/include/custom.h index 3262c92e..a15623af 100644 --- a/include/custom.h +++ b/include/custom.h @@ -29,21 +29,21 @@ #define BLIT_NASTY_CPU_STEAL_CYCLE_COUNT 4 -uae_u32 get_copper_address (int copno); +uae_u32 get_copper_address(int copno); -extern int custom_init (void); -extern void custom_prepare (void); -extern void custom_reset (bool hardreset, bool keyboardreset); -extern int intlev (void); -extern void dumpcustom (void); +extern int custom_init(void); +extern void custom_prepare(void); +extern void custom_reset(bool hardreset, bool keyboardreset); +extern int intlev(void); +extern void dumpcustom(void); -extern void do_copper (void); +extern void do_copper(void); -extern void notice_new_xcolors (void); +extern void notice_new_xcolors(void); extern void notice_screen_contents_lost(int monid); -extern void init_row_map (void); -extern void init_hz_normal (void); -extern void init_custom (void); +extern void init_row_map(void); +extern void init_hz_normal(void); +extern void init_custom(void); extern void set_picasso_hack_rate(int hz); @@ -59,7 +59,7 @@ extern int vpos, lof_store; extern int n_frames; -STATIC_INLINE int dmaen (unsigned int dmamask) +STATIC_INLINE int dmaen(unsigned int dmamask) { return (dmamask & dmacon) && (dmacon & 0x200); } @@ -161,9 +161,7 @@ extern bool programmedmode; extern unsigned long frametime, timeframes; extern uae_u16 htotal, vtotal, beamcon0; -/* 100 words give you 1600 horizontal pixels. Should be more than enough for -* superhires. Don't forget to update the definition in genp2c.c as well. -* needs to be larger for superhires support */ +// 100 words give you 1600 horizontal pixels. Should be more than enough for superhires. #ifdef CUSTOM_SIMPLE #define MAX_WORDS_PER_LINE 50 #else @@ -197,13 +195,13 @@ extern int xbluecolor_s, xbluecolor_b, xbluecolor_m; #define RES_SHIFT(res) ((res) == RES_LORES ? 8 : (res) == RES_HIRES ? 4 : 2) /* get resolution from bplcon0 */ -STATIC_INLINE int GET_RES_DENISE (uae_u16 con0) +STATIC_INLINE int GET_RES_DENISE(uae_u16 con0) { if (!(currprefs.chipset_mask & CSMASK_ECS_DENISE)) con0 &= ~0x40; // SUPERHIRES return ((con0) & 0x40) ? RES_SUPERHIRES : ((con0) & 0x8000) ? RES_HIRES : RES_LORES; } -STATIC_INLINE int GET_RES_AGNUS (uae_u16 con0) +STATIC_INLINE int GET_RES_AGNUS(uae_u16 con0) { if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) con0 &= ~0x40; // SUPERHIRES @@ -221,7 +219,7 @@ STATIC_INLINE int GET_PLANES(uae_u16 bplcon0) return (bplcon0 >> 12) & 7; // normal planes bits } -extern void fpscounter_reset (void); +extern void fpscounter_reset(void); extern unsigned long idletime; extern int lightpen_x[2], lightpen_y[2]; extern int lightpen_cx[2], lightpen_cy[2], lightpen_active, lightpen_enabled, lightpen_enabled2; @@ -230,17 +228,17 @@ struct customhack { uae_u16 v; int vpos, hpos; }; -void customhack_put (struct customhack *ch, uae_u16 v, int hpos); -uae_u16 customhack_get (struct customhack *ch, int hpos); -extern void alloc_cycle_ext (int, int); -extern void alloc_cycle_blitter (int hpos, uaecptr *ptr, int); -extern bool ispal (void); -extern bool isvga (void); -extern int current_maxvpos (void); -extern struct chipset_refresh *get_chipset_refresh (struct uae_prefs*); -extern void compute_framesync (void); +void customhack_put(struct customhack *ch, uae_u16 v, int hpos); +uae_u16 customhack_get(struct customhack *ch, int hpos); +extern void alloc_cycle_ext(int, int); +extern void alloc_cycle_blitter(int hpos, uaecptr *ptr, int); +extern bool ispal(void); +extern bool isvga(void); +extern int current_maxvpos(void); +extern struct chipset_refresh *get_chipset_refresh(struct uae_prefs*); +extern void compute_framesync(void); extern void getsyncregisters(uae_u16 *phsstrt, uae_u16 *phsstop, uae_u16 *pvsstrt, uae_u16 *pvsstop); -int is_bitplane_dma (int hpos); +int is_bitplane_dma(int hpos); void custom_cpuchange(void); struct custom_store diff --git a/include/debug.h b/include/debug.h index 7519f016..b661a7b9 100644 --- a/include/debug.h +++ b/include/debug.h @@ -220,6 +220,7 @@ struct dma_rec uae_s16 type; uae_u16 extra; uae_s8 intlev; + uae_u16 cf_reg, cf_dat, cf_addr; }; extern struct dma_rec *last_dma_rec; diff --git a/include/drawing.h b/include/drawing.h index ea9b2026..0f02c2b8 100644 --- a/include/drawing.h +++ b/include/drawing.h @@ -37,17 +37,13 @@ before it appears on-screen. (TW: display emulation now does this automatically) #define DISPLAY_LEFT_SHIFT 0x3c #define DISPLAY_LEFT_SHIFT_SHRES (DISPLAY_LEFT_SHIFT << 2) -#define PIXEL_XPOS(HPOS) (((HPOS) - DISPLAY_LEFT_SHIFT + DIW_DDF_OFFSET - 1) << lores_shift) - -extern int hsynctotal; - -#define min_diwlastword (0) -#define max_diwlastword (PIXEL_XPOS(hsynctotal * 2 + 1)) +#define CCK_SHRES_SHIFT 3 extern int lores_shift, shres_shift, interlace_seen; extern bool aga_mode, ecs_agnus, ecs_denise, direct_rgb; extern int visible_left_border, visible_right_border; extern int detected_screen_resolution; +extern int hsynctotal; STATIC_INLINE int shres_coord_hw_to_window_x(int x) { @@ -57,12 +53,44 @@ STATIC_INLINE int shres_coord_hw_to_window_x(int x) return x; } -STATIC_INLINE int coord_hw_to_window_x(int x) +STATIC_INLINE int coord_hw_to_window_x_shres(int xx) +{ + int x = xx >> (CCK_SHRES_SHIFT - 1); + x -= DISPLAY_LEFT_SHIFT; + if (lores_shift == 1) { + x <<= 1; + x |= (xx >> 1) & 1; + } else if (lores_shift == 2) { + x <<= 2; + x |= xx & 3; + } + return x; +} +STATIC_INLINE int coord_hw_to_window_x_lores(int x) { x -= DISPLAY_LEFT_SHIFT; return x << lores_shift; } +STATIC_INLINE int PIXEL_XPOS(int xx) +{ + int x = xx >> (CCK_SHRES_SHIFT - 1); + x -= DISPLAY_LEFT_SHIFT; + x += DIW_DDF_OFFSET; + x -= 1; + if (lores_shift == 1) { + x <<= 1; + x |= (xx >> 1) & 1; + } else if (lores_shift == 2) { + x <<= 2; + x |= xx & 3; + } + return x; +} + +#define min_diwlastword (0) +#define max_diwlastword (PIXEL_XPOS(hsynctotal)) + STATIC_INLINE int coord_window_to_hw_x(int x) { x >>= lores_shift; @@ -213,7 +241,7 @@ struct color_change { #ifdef UAE_MINI #define MAX_PIXELS_PER_LINE 880 #else -#define MAX_PIXELS_PER_LINE 1760 +#define MAX_PIXELS_PER_LINE 2048 #endif /* No divisors for MAX_PIXELS_PER_LINE; we support AGA and SHRES sprites */ -- 2.47.3