From: Toni Wilen Date: Mon, 3 Aug 2009 14:47:51 +0000 (+0300) Subject: imported winuaesrc1620b4.zip X-Git-Tag: 2100~69 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=230a93e7eeedd0a7ce4571fa0e3f6bc8d1ec34ed;p=francis%2Fwinuae.git imported winuaesrc1620b4.zip --- diff --git a/blitter.c b/blitter.c index 691b9848..19961cab 100644 --- a/blitter.c +++ b/blitter.c @@ -34,6 +34,8 @@ uae_u16 bltcon0, bltcon1; uae_u32 bltapt, bltbpt, bltcpt, bltdpt; int blitter_nasty; +static int original_ch, original_fill, original_line; + static int blinea_shift; static uae_u16 blinea, blineb; static int blitline, blitfc, blitfill, blitife, blitsing, blitdesc; @@ -70,6 +72,8 @@ static int blit_last_cycle, blit_dmacount, blit_dmacount2; static int blit_linecycles, blit_extracycles, blit_nod; static const int *blit_diag; static int blit_line_pixel; +static int blit_frozen, blit_faulty; +static int blit_final; static uae_u16 ddat1, ddat2; static int ddat1use, ddat2use; @@ -230,24 +234,35 @@ static void blitter_dump (void) blt_info.bltamod & 0xffff, blt_info.bltbmod & 0xffff, blt_info.bltcmod & 0xffff, blt_info.bltdmod & 0xffff); } +STATIC_INLINE const int *get_ch (void) +{ + if (blit_faulty) + return &blit_diag[0]; + if (blit_final) + return blit_cycle_diagram_finald; + return blit_diag; +} + STATIC_INLINE int channel_state (int cycles) { + const int *diag = get_ch (); if (cycles < 0) return 0; - if (cycles < blit_diag[0]) - return blit_diag[1 + cycles]; - cycles -= blit_diag[0]; - cycles %= blit_diag[0]; - return blit_diag[1 + blit_diag[0] + cycles]; + if (cycles < diag[0]) + return diag[1 + cycles]; + cycles -= diag[0]; + cycles %= diag[0]; + return diag[1 + diag[0] + cycles]; } STATIC_INLINE int channel_pos (int cycles) { + const int *diag = get_ch (); if (cycles < 0) return 0; - if (cycles < blit_diag[0]) + if (cycles < diag[0]) return cycles; - cycles -= blit_diag[0]; - cycles %= blit_diag[0]; + cycles -= diag[0]; + cycles %= diag[0]; return cycles; } @@ -264,10 +279,12 @@ STATIC_INLINE int canblit (int hpos) // blitter interrupt is set when last "main" cycle // has been finished, any non-linedraw D-channel blit // still needs 2 more cycles before final D is written -static void blitter_interrupt (int hpos) +static void blitter_interrupt (int hpos, int done) { if (blit_interrupt) return; + if (!done && !currprefs.blitter_cycle_exact) + return; blit_interrupt = 1; INTREQ (0x8040); if (debug_dma) @@ -278,7 +295,7 @@ static void blitter_done (int hpos) { ddat1use = ddat2use = 0; bltstate = blit_startcycles == 0 ? BLT_done : BLT_init; - blitter_interrupt (hpos); + blitter_interrupt (hpos, 1); blitter_done_notify (hpos); if (debug_dma) record_dma_event (DMA_EVENT_BLITFINISHED, hpos, vpos); @@ -809,17 +826,10 @@ STATIC_INLINE int blitter_doddma (int hpos) if (blitter_vcounter2 > blitter_vcounter1) blitter_vcounter1 = blitter_vcounter2; } -#if 0 - if (blitter_hcounter1 == 0 && blitter_vcounter1 == vblitsize) { - if (blit_diag != blit_cycle_diagram_finald) { - blit_cyclecounter = -1; - blit_diag = blit_cycle_diagram_finald; - } - } -#endif if (blit_ch == 1) blitter_hcounter1 = blitter_hcounter2; } + blit_final = 0; return wd; } @@ -903,10 +913,14 @@ static void do_startcycles (int hpos) if (v) { blit_startcycles--; if (blit_startcycles == 0) { + if (blit_faulty) + blit_faulty = -1; bltstate = BLT_done; do_blitter (vhpos, 0); blit_startcycles = 0; blit_cyclecounter = 0; + if (blit_faulty) + blit_faulty = 1; return; } } @@ -920,7 +934,7 @@ void decide_blitter (int hpos) if (blit_startcycles > 0) do_startcycles (hpos); - if (bltstate == BLT_done) + if (bltstate == BLT_done || blit_frozen) return; #ifdef BLITTER_DEBUG if (blitter_delayed_debug) { @@ -1001,10 +1015,10 @@ void decide_blitter (int hpos) } if (blitter_vcounter1 == vblitsize && channel_pos (blit_cyclecounter - 1) == blit_diag[0] - 1) { - if (blit_diag != blit_cycle_diagram_finald) { - blitter_interrupt (last_blitter_hpos); + if (!blit_final) { + blitter_interrupt (last_blitter_hpos, 0); blit_cyclecounter = 0; - blit_diag = blit_cycle_diagram_finald; + blit_final = 1; } } last_blitter_hpos++; @@ -1048,21 +1062,22 @@ static void blitter_force_finish (void) static void blit_bltset (int con) { int i; + const int *olddiag = blit_diag; - blitdesc = bltcon1 & 2; - - if (bltstate != BLT_done) - return; + if (con & 2) { + blitdesc = bltcon1 & 2; + blt_info.blitbshift = bltcon1 >> 12; + blt_info.blitdownbshift = 16 - blt_info.blitbshift; + } - blinea_shift = bltcon0 >> 12; - blt_info.blitashift = bltcon0 >> 12; - blt_info.blitdownashift = 16 - blt_info.blitashift; - blt_info.blitbshift = bltcon1 >> 12; - blt_info.blitdownbshift = 16 - blt_info.blitbshift; + if (con & 1) { + blt_info.blitashift = bltcon0 >> 12; + blt_info.blitdownashift = 16 - blt_info.blitashift; + } + blit_ch = (bltcon0 & 0x0f00) >> 8; blitline = bltcon1 & 1; blitfill = bltcon1 & 0x18; - blit_ch = (bltcon0 & 0x0f00) >> 8; if (blitline) { if (hblitsize != 2) @@ -1085,6 +1100,51 @@ static void blit_bltset (int con) if ((bltcon1 & 0x80) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) debugtest (DEBUGTEST_BLITTER, L"ECS BLTCON1 DOFF-bit set\n"); + // on the fly switching fillmode from extra cycle to non-extra: blitter freezes + // non-extra cycle to extra cycle: does not freeze but cycle diagram goes weird, + // extra free cycle changes to another D write.. + // (Absolute Inebriation vector cube inside semi-filled vector object requires freezing blitter.) + if (bltstate != BLT_done) { + static int freezes = 10; + int isen = blit_diag >= &blit_cycle_diagram_fill[0][0] && blit_diag <= &blit_cycle_diagram_fill[15][0]; + int iseo = olddiag >= &blit_cycle_diagram_fill[0][0] && olddiag <= &blit_cycle_diagram_fill[15][0]; + if (iseo != isen) { + if (freezes > 0) { + write_log (L"BLITTER: on the fly %d (%d) -> %d (%d) switch!\n", original_ch, iseo, blit_ch, isen); + freezes--; + } + } + if (iseo && !isen) { + blit_frozen = 1; + } else if (!iseo && isen) { +#ifdef BLITTER_DEBUG_NOWAIT + write_log (L"BLITTER: on the fly %d (%d) -> %d (%d) switch\n", oldch, iseo, blit_ch, isen); +#endif + } + } + + // on the fly switching from CH=1 to CH=D -> blitter stops writing (Rampage/TEK) + // currently just switch to no-channels mode, better than crashing the demo.. + if (bltstate != BLT_done) { + static uae_u8 changetable[32 * 32]; + int o = original_ch + (original_fill ? 16 : 0); + int n = blit_ch + (blitfill ? 16 : 0); + if (o != n) { + if (changetable[o * 32 + n] < 10) { + changetable[o * 32 + n]++; + write_log (L"BLITTER: channel mode changed while active (%02X->%02X)\n", o, n); + } + } + if (blit_ch == 13 && original_ch == 1) { + blit_faulty = 1; + } + } + + if (blit_faulty) { + blit_ch = 0; + blit_diag = blit_cycle_diagram[blit_ch]; + } + blit_dmacount = blit_dmacount2 = 0; blit_nod = 1; for (i = 0; i < blit_diag[0]; i++) { @@ -1113,6 +1173,8 @@ static void blit_modset (void) void reset_blit (int bltcon) { + if (bltcon & 1) + blinea_shift = bltcon0 >> 12; if (bltstate == BLT_done) return; if (bltcon) @@ -1123,6 +1185,7 @@ void reset_blit (int bltcon) static void do_blitter2 (int hpos, int copper) { int cycles; + int cleanstart; #ifdef BLITTER_DEBUG_NOWAIT if (bltstate != BLT_done) { @@ -1130,6 +1193,13 @@ static void do_blitter2 (int hpos, int copper) write_log (L"blitter was already active! PC=%08x\n", M68K_GETPC); } #endif + cleanstart = 0; + if (bltstate == BLT_done) { + if (blit_faulty > 0) + blit_faulty = 0; + cleanstart = 1; + } + bltstate = BLT_done; hblitsize = blt_info.hblitsize; @@ -1139,6 +1209,7 @@ static void do_blitter2 (int hpos, int copper) preva = 0; prevb = 0; blt_info.got_cycle = 0; + blit_frozen = 0; blit_firstline_cycles = blit_first_cycle = get_cycles (); blit_misscyclecounter = 0; @@ -1148,7 +1219,7 @@ static void do_blitter2 (int hpos, int copper) blit_cyclecounter = 0; blit_totalcyclecounter = 0; - blit_bltset (1|2); + blit_bltset (1 | 2); blit_modset (); ddat1use = ddat2use = 0; blit_interrupt = 0; @@ -1165,6 +1236,12 @@ static void do_blitter2 (int hpos, int copper) cycles = vblitsize * hblitsize; } + if (cleanstart) { + original_ch = blit_ch; + original_fill = blitfill; + original_line = blitline; + } + #ifdef BLITTER_DEBUG blitter_dontdo = 0; if (1) { @@ -1243,24 +1320,25 @@ void do_blitter (int hpos, int copper) void maybe_blit (int hpos, int hack) { - static int warned; + static int warned = 10; if (bltstate == BLT_done) return; if (savestate_state) return; - if (!warned && dmaen (DMA_BLITTER) && blt_info.got_cycle) { - warned = 1; + if (warned && dmaen (DMA_BLITTER) && blt_info.got_cycle) { + warned--; debugtest (DEBUGTEST_BLITTER, L"program does not wait for blitter tc=%d\n", blit_cyclecounter); #ifdef BLITTER_DEBUG warned = 0; #endif #ifdef BLITTER_DEBUG_NOWAIT - warned = 0; + warned = 10; write_log (L"program does not wait for blitter PC=%08x\n", M68K_GETPC); - activate_debugger (); + //activate_debugger (); + //blitter_done (hpos); #endif } diff --git a/custom.c b/custom.c index 6efaa5c8..9b9a2630 100644 --- a/custom.c +++ b/custom.c @@ -63,7 +63,7 @@ #define SPRBORDER 0 -STATIC_INLINE int nocustom(void) +STATIC_INLINE int nocustom (void) { if (picasso_on && currprefs.picasso96_nocustom) return 1; @@ -238,6 +238,7 @@ static int diwhigh_written; static unsigned int ddfstrt, ddfstop, ddfstrt_old_hpos, ddfstrt_old_vpos; static int ddf_change, badmode; static int fmode; +static int bplcon1_hpos; /* The display and data fetch windows */ @@ -295,6 +296,7 @@ struct copper { int strobe; /* COPJMP1 / COPJMP2 accessed */ int last_write, last_write_hpos; int moveaddr, movedata, movedelay; + int movedata100, movedelay100; }; static struct copper cop_state; @@ -782,7 +784,7 @@ static uae_u32 fetched_aga1[MAX_PLANES]; /* Expansions from bplcon0/bplcon1. */ static int toscr_res, toscr_nr_planes, toscr_nr_planes2, fetchwidth; -static int toscr_delay1, toscr_delay2, toscr_delay1x, toscr_delay2x; +static int toscr_delay1, toscr_delay2; /* The number of bits left from the last fetched words. This is an optimization - conceptually, we have to make sure the result is @@ -888,10 +890,10 @@ static void compute_toscr_delay_1 (void) delay1 += delayoffset; delay2 += delayoffset; delaymask = (fetchwidth - 1) >> toscr_res; - toscr_delay1x = (delay1 & delaymask) << toscr_res; - toscr_delay1x |= shdelay1 >> (RES_MAX - toscr_res); - toscr_delay2x = (delay2 & delaymask) << toscr_res; - toscr_delay2x |= shdelay2 >> (RES_MAX - toscr_res); + toscr_delay1 = (delay1 & delaymask) << toscr_res; + toscr_delay1 |= shdelay1 >> (RES_MAX - toscr_res); + toscr_delay2 = (delay2 & delaymask) << toscr_res; + toscr_delay2 |= shdelay2 >> (RES_MAX - toscr_res); } static void compute_toscr_delay (int hpos) @@ -905,9 +907,6 @@ STATIC_INLINE void maybe_first_bpl1dat (int hpos) if (thisline_decision.plfleft == -1) { thisline_decision.plfleft = hpos; compute_delay_offset (); - compute_toscr_delay_1 (); - toscr_delay1 = toscr_delay1x; - toscr_delay2 = toscr_delay2x; } } @@ -1179,14 +1178,17 @@ STATIC_INLINE void fetch_start (int hpos) fetch_state = fetch_started; } + /* Called when all planes have been fetched, i.e. when a new block of data is available to be displayed. The data in fetched[] is moved into todisplay[]. */ STATIC_INLINE void beginning_of_plane_block (int hpos, int fm) { int i; + int oleft = thisline_decision.plfleft; flush_display (fm); + if (fm == 0) for (i = 0; i < MAX_PLANES; i++) { todisplay[i][0] |= fetched[i]; @@ -1199,11 +1201,15 @@ STATIC_INLINE void beginning_of_plane_block (int hpos, int fm) todisplay[i][0] = fetched_aga0[i]; } #endif - toscr_delay1 = toscr_delay1x; - toscr_delay2 = toscr_delay2x; + update_denise (hpos); maybe_first_bpl1dat (hpos); - compute_toscr_delay (hpos); + + // writing to BPLCON1 1 cycle after BPL1DAT access will + // not (except first BPL1DAT write) affect the display + // until next display block + if (bplcon1_hpos != hpos || oleft < 0) + compute_toscr_delay (hpos); } #ifdef SPEEDUP @@ -1728,8 +1734,9 @@ STATIC_INLINE void decide_line (int hpos) ok = 1; /* hack warning.. Writing to DDFSTRT when DMA should start must be ignored * (correct fix would be emulate this delay for every custom register, but why bother..) */ - if (hpos - 2 == ddfstrt_old_hpos && ddfstrt_old_vpos == vpos) - ok = 0; + if (ddfstrt_old_vpos == vpos) + if (hpos - 2 == ddfstrt_old_hpos) + ok = 0; } if (ok && dmaen (DMA_BITPLANE)) { start_bpl_dma (hpos, plfstrt); @@ -2433,6 +2440,7 @@ static void reset_decisions (void) last_sprite_point = 0; fetch_state = fetch_not_started; + bplcon1_hpos = -1; if (plf_state > plf_active) plf_state = plf_idle; @@ -2905,6 +2913,11 @@ static void COPJMP (int num, int vblank) { int oldstrobe = cop_state.strobe; +#if CUSTOM_DEBUG > 0 + if (dmaen (DMA_COPPER) && (cop_state.saved_i1 != 0xffff || cop_state.saved_i2 != 0xfffe)) + write_log (L"vblank without copper ending %08x (%08x %08x)\n", cop_state.ip, cop1lc, cop2lc); +#endif + unset_special (®s, SPCFLAG_COPPER); cop_state.ignore_next = 0; if (!oldstrobe) @@ -3215,7 +3228,7 @@ static void BPLCON0 (int hpos, uae_u16 v) #endif if (bplcon0 == v) return; - + if ((bplcon0 & 2) && !(v & 2)) { vpos_previous = vpos; hpos_previous = hpos; @@ -3238,13 +3251,18 @@ static void BPLCON0 (int hpos, uae_u16 v) expand_fmodes (); - record_register_change (hpos, 0x100, v | 0x80); + record_register_change (hpos, 0x100, v); calcdiw (); estimate_last_fetch_cycle (hpos); } +static void BPLCON0_f (uae_u32 d) +{ + BPLCON0 (d >> 16, d & 0xffff); +} + STATIC_INLINE void BPLCON1 (int hpos, uae_u16 v) { if (!(currprefs.chipset_mask & CSMASK_AGA)) @@ -3254,6 +3272,7 @@ STATIC_INLINE void BPLCON1 (int hpos, uae_u16 v) ddf_change = vpos; decide_line (hpos); decide_fetch (hpos); + bplcon1_hpos = hpos; bplcon1 = v; } @@ -3373,7 +3392,7 @@ static void DDFSTRT (int hpos, uae_u16 v) v &= 0xfe; if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) v &= 0xfc; - if (ddfstrt == v) + if (ddfstrt == v && hpos + 2 != ddfstrt) return; ddf_change = vpos; decide_line (hpos); @@ -3394,7 +3413,7 @@ static void DDFSTOP (int hpos, uae_u16 v) v &= 0xfe; if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS)) v &= 0xfc; - if (ddfstop == v) + if (ddfstop == v && hpos + 2 != ddfstop) return; ddf_change = vpos; decide_line (hpos); @@ -3826,7 +3845,7 @@ static void COLOR_WRITE (int hpos, uae_u16 v, int num) STATIC_INLINE int copper_cant_read (int hpos) { - if (hpos + 1 >= maxhpos) + if (hpos + 1 >= maxhpos) // first refresh slot return 1; return is_bitplane_dma_inline (hpos); } @@ -3835,7 +3854,7 @@ static int custom_wput_copper (int hpos, uaecptr addr, uae_u32 value, int noget) { int v; - debug_wputpeek (0xdff000 + (cop_state.saved_i1 & 0x1fe), cop_state.saved_i2); + debug_wputpeek (0xdff000 + addr, value); copper_access = 1; v = custom_wput_1 (hpos, addr, value, noget); copper_access = 0; @@ -3854,6 +3873,7 @@ static void dump_copper (TCHAR *error, int until_hpos) // "emulate" chip internal delays, not the right place but fast and 99.9% programs // use only copper to write BPLCON1 etc.. (exception is HulkaMania/TSP..) +// this table should be filled with zeros and done somewhere else.. static int customdelay[]= { 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* 32 0x00 - 0x3e */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x40 - 0x5e */ @@ -3910,15 +3930,24 @@ static void update_copper (int until_hpos) if (cop_state.movedelay > 0) { cop_state.movedelay--; - if (cop_state.movedelay == 1 && cop_state.moveaddr == 0x100) { + if (cop_state.movedelay == 0) { + custom_wput_copper (c_hpos, cop_state.moveaddr, cop_state.movedata, 0); + } + } +#if 1 + if (cop_state.movedelay100 > 0) { + cop_state.movedelay100--; + if (cop_state.movedelay100 == 1) { // Denise reacts to BPLCON0 change a bit earlier than Agnus - BPLCON0_Denise (old_hpos, cop_state.movedata); + BPLCON0_Denise (c_hpos, cop_state.movedata100); } - if (cop_state.movedelay == 0) { - custom_wput_copper (old_hpos, cop_state.moveaddr, cop_state.movedata, 0); + if (cop_state.movedelay100 == 0) { + decide_line (c_hpos); + decide_fetch (c_hpos); + custom_wput_copper (c_hpos, 0x100, cop_state.movedata100, 0); } } - +#endif c_hpos += 2; if (cop_state.strobe) { @@ -3952,8 +3981,8 @@ static void update_copper (int until_hpos) break; case COP_strobe_delay2: // second cycle after COPJMP is like second read cycle except - // there is 0x1FE in logic analyzer as a target register - // (next word is still read normally and tossed away) + // there is 0x1FE as a target register + // (following word is still read normally and tossed away) if (copper_cant_read (old_hpos)) continue; cop_state.state = COP_read1; @@ -4005,11 +4034,11 @@ static void update_copper (int until_hpos) #endif } else { // MOVE unsigned int reg = cop_state.i1 & 0x1FE; + uae_u16 data = cop_state.i2; cop_state.state = COP_read1; - cop_state.movedata = cop_state.i2; #ifdef DEBUGGER if (debug_dma) - record_dma (reg, cop_state.i2, cop_state.ip - 2, old_hpos, vpos); + record_dma (reg, data, cop_state.ip - 2, old_hpos, vpos); #endif test_copper_dangerous (reg); if (! copper_enabled_thisline) @@ -4019,8 +4048,6 @@ static void update_copper (int until_hpos) cop_state.ignore_next = 0; } - cop_state.moveaddr = reg; - cop_state.movedelay = 0; cop_state.last_write = reg; cop_state.last_write_hpos = old_hpos; if (reg == 0x88) { @@ -4030,14 +4057,21 @@ static void update_copper (int until_hpos) cop_state.ip = cop2lc; cop_state.state = COP_strobe_delay1; } else { - if (cop_state.moveaddr == 0x100) { + // FIX: all copper writes happen 1 cycle later than CPU writes + if (reg == 0x100) { // special case BPLCON0 BPL DMA sequence delay - cop_state.movedelay = 2; - } else if (customdelay[cop_state.moveaddr / 2]) { + // dma sequence does not change until 1+4 cycles after the write + cop_state.movedelay100 = 2; + cop_state.movedata100 = data; + if (thisline_decision.plfleft == -1) + BPLCON0_Denise (old_hpos, data); + } else if (customdelay[reg / 2]) { + cop_state.moveaddr = reg; + cop_state.movedata = data; cop_state.movedelay = customdelay[cop_state.moveaddr / 2]; } else { int hpos2 = old_hpos; - custom_wput_copper (hpos2, reg, cop_state.movedata, 0); + custom_wput_copper (hpos2, reg, data, 0); hpos2++; if (!nocustom () && reg >= 0x140 && reg < 0x180 && hpos2 >= SPR0_HPOS && hpos2 < SPR0_HPOS + 4 * MAX_SPRITES) { do_sprites (hpos2); @@ -4179,8 +4213,9 @@ static void compute_spcflag_copper (int hpos) } /* - Copper writes to BLTSIZE: 2 blitter idle cycles, blitter normal cycle starts + Copper writes to BLTSIZE: 3 blitter idle cycles, blitter normal cycle starts BFD=0 wait: blitter interrupt, 4 cycles, copper fetches next word + (CPU write to BLTSIZE only have 2 idle cycles at start) */ void blitter_done_notify (int hpos) { @@ -4280,12 +4315,13 @@ STATIC_INLINE void do_sprites_1 (int num, int cycle, int hpos) struct sprite *s = &spr[num]; int dma, posctl = 0; uae_u16 data; + int isdma = dmaen (DMA_SPRITE); - if (vpos == sprite_vblank_endline) + if (isdma && vpos == sprite_vblank_endline) spr_arm (num, 0); #ifdef AGA - if (s->dblscan && (fmode & 0x8000) && (vpos & 1) != (s->vstart & 1) && s->dmastate) { + if (isdma && s->dblscan && (fmode & 0x8000) && (vpos & 1) != (s->vstart & 1) && s->dmastate) { spr_arm (num, 1); return; } @@ -4316,6 +4352,9 @@ STATIC_INLINE void do_sprites_1 (int num, int cycle, int hpos) } #endif } + + if (!isdma) + return; if (cycle && !s->dmacycle) return; /* Superfrog intro flashing bee fix */ @@ -4427,24 +4466,21 @@ static void do_sprites (int hpos) if (minspr < SPR0_HPOS) minspr = SPR0_HPOS; - if (dmaen (DMA_SPRITE)) { - - for (i = minspr; i <= maxspr; i++) { - int cycle = -1; - int num = (i - SPR0_HPOS) / 4; - switch ((i - SPR0_HPOS) & 3) - { - case 0: - cycle = 0; - spr[num].dmacycle = 0; - break; - case 2: - cycle = 1; - break; - } - if (cycle >= 0 && num >= 0 && num < MAX_SPRITES) - do_sprites_1 (num, cycle, i); + for (i = minspr; i <= maxspr; i++) { + int cycle = -1; + int num = (i - SPR0_HPOS) / 4; + switch ((i - SPR0_HPOS) & 3) + { + case 0: + cycle = 0; + spr[num].dmacycle = 0; + break; + case 2: + cycle = 1; + break; } + if (cycle >= 0 && num >= 0 && num < MAX_SPRITES) + do_sprites_1 (num, cycle, i); } last_sprite_hpos = hpos; @@ -5205,7 +5241,14 @@ static void MISC_handler (void) STATIC_INLINE void event2_newevent_x (int no, evt t, uae_u32 data, evfunc2 func) { - evt et = t * CYCLE_UNIT + get_cycles (); + evt et; + + if (((int)t) <= 0) { + func (data); + return; + } + + et = t * CYCLE_UNIT + get_cycles (); if (no < 0) { for (no = ev2_misc; no < ev2_max; no++) { diff --git a/od-win32/hardfile_win32.c b/od-win32/hardfile_win32.c index 3ab3e4f3..f8371aa0 100644 --- a/od-win32/hardfile_win32.c +++ b/od-win32/hardfile_win32.c @@ -203,6 +203,8 @@ static int safetycheck (HANDLE *h, const TCHAR *name, uae_u64 offset, uae_u8 *bu write_log (L"hd ignored, read error %d!\n", GetLastError ()); return 2; } + if (offset > 0) + return -5; if (j == 0 && buf[0] == 0x39 && buf[1] == 0x10 && buf[2] == 0xd3 && buf[3] == 0x12) { // ADIDE "CPRM" hidden block.. if (do_rdbdump) @@ -1130,6 +1132,7 @@ static BOOL GetDevicePropertyFromName(const TCHAR *DevicePath, DWORD Index, DWOR udi->size = pi->PartitionLength.QuadPart; write_log (L"used\n"); _stprintf (udi->device_name, L"HD_P#%d_%s", pi->PartitionNumber, orgname); + udi->dangerous = -5; udi++; (*index2)++; safepart = 1; @@ -1380,6 +1383,9 @@ TCHAR *hdf_getnameharddrive (int index, int flags, int *sectorsize, int *dangero *dangerousdrive = 0; switch (uae_drives[index].dangerous) { + case -5: + dang = L"[PART]"; + break; case -6: dang = L"[MBR]"; break; diff --git a/od-win32/win32.c b/od-win32/win32.c index 8aff34b8..e3b65987 100644 --- a/od-win32/win32.c +++ b/od-win32/win32.c @@ -2335,73 +2335,65 @@ static void shellexecute (TCHAR *command) { STARTUPINFO si = { 0 }; PROCESS_INFORMATION pi = { 0 }; + TCHAR **arg; + int i, j, k, stop; - si.cb = sizeof si; - si.wShowWindow = SW_HIDE; - si.dwFlags = STARTF_USESHOWWINDOW; - if (CreateProcess (NULL, - command, - NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { - WaitForSingleObject (pi.hProcess, INFINITE); - CloseHandle (pi.hProcess); - CloseHandle (pi.hThread); - } else { - write_log (L"CreateProcess('%s') failed, %d\n", - command, GetLastError ()); - } -} - -#if 0 -static void shellexecute (TCHAR *command) -{ - SHELLEXECUTEINFO sei = { 0 }; - TCHAR **args; - int i; - - i = 0; - args = parseargstring (command); - while (args && args[i]) { - int j; - int len; - TCHAR *cmd = args[i++]; - TCHAR *s = NULL; - - sei.cbSize = sizeof sei; - sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT | SEE_MASK_DOENVSUBST | SEE_MASK_FLAG_NO_UI; - sei.lpFile = cmd; - sei.nShow = SW_HIDE; + if (_tcslen (command) == 0) + return; + i = j = 0; + stop = 0; + arg = parseargstring (command); + while (!stop) { + TCHAR *cmd, *exec; + int len = 1; j = i; - len = 0; - while (args[i] && _tcscmp (args[i], L";")) { - len += _tcslen (args[i]) + 1; + while (arg[i] && _tcscmp (arg[i], L";")) { + len += _tcslen (arg[i]) + 3; i++; } - if (i > j) { - s = xcalloc (len + 1, sizeof (TCHAR)); - while (j < i) { - if (s[0]) - _tcscat (s, L" "); - _tcscat (s, args[j]); - j++; + exec = NULL; + cmd = xcalloc (len, sizeof (TCHAR)); + for (k = j; k < i; k++) { + int quote = 0; + if (_tcslen (cmd) > 0) + _tcscat (cmd, L" "); + if (_tcschr (arg[k], ' ')) + quote = 1; + if (quote) + _tcscat (cmd, L"\""); + _tcscat (cmd, arg[k]); + if (quote) + _tcscat (cmd, L"\""); + if (!exec && !_tcsicmp (cmd, L"cmd.exe")) { + int size; + size = GetEnvironmentVariable (L"ComSpec", NULL, 0); + if (size > 0) { + exec = xcalloc (size + 1, sizeof (TCHAR)); + GetEnvironmentVariable (L"ComSpec", exec, size); + } + cmd[0] = 0; } - sei.lpParameters = s; } - write_log (L"ShellExecuteEx('%s','%s')\n", cmd, s ? s : L""); - if (ShellExecuteEx (&sei)) { - HANDLE h = sei.hProcess; - if (h) { - WaitForSingleObject (h, INFINITE); - CloseHandle (h); - } - write_log (L"Succeeded\n"); + if (arg[i++] == 0) + stop = 1; + si.cb = sizeof si; + //si.wShowWindow = SW_HIDE; + //si.dwFlags = STARTF_USESHOWWINDOW; + if (CreateProcess (exec, + cmd, + NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { + WaitForSingleObject (pi.hProcess, INFINITE); + CloseHandle (pi.hProcess); + CloseHandle (pi.hThread); } else { - write_log (L"Failed. ERR=%d\n", GetLastError ()); + write_log (L"CreateProcess('%s' '%s') failed, %d\n", + exec, cmd, GetLastError ()); } - xfree (s); + xfree (exec); + xfree (cmd); } - xfree (args); + xfree (arg); } -#endif void target_run (void) { diff --git a/od-win32/win32.h b/od-win32/win32.h index ad08b766..8613ed3a 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -17,8 +17,8 @@ #define WINUAEPUBLICBETA 1 -#define WINUAEBETA L"Beta 3" -#define WINUAEDATE MAKEBD(2009, 7, 30) +#define WINUAEBETA L"Beta 4" +#define WINUAEDATE MAKEBD(2009, 8, 3) #define WINUAEEXTRA L"" #define WINUAEREV L"" diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index b8333832..2b7d89bb 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,40 @@ +Beta 4: + +- 0x76/0x30 partition types are marked as "PART" in GUI and read/write + should really really work.. +- exec* command line didn't support command separation (;) characters, + batch files supported ("cmd.exe /c ") +- fixed very old left border graphics error in Absolute Inebriation +- b3 sprite fix broke other programs, fixed again +- Brian the Lion "dialog screen" problem is not anything AGA-specific, + BPLCON0 write needs 5 cycle delay, not 4 when written by copper. + Not fixed yet, waiting odd number of cycles in copper emulation isn't + currently possible + +and few buggy demos fixed, doing weird things with the blitter and work +only accidentally.. For the first time ever Rampage/TEK works! + +- Absolute Inebriation/VD "red linevector cube inside white object" part + now works. Bug in blitter wait, rewrites blitter registers when old blit + is still active, normally this would mess up the blit but it worked + because write to BLTCON1 freezes the blitter if it causes switch from + "extra" cycle fillmode to normal mode. +- Rampage/TEK blitter feature workaround added, another buggy demo, it + changes blitter channel mode from 0x01 to 0x0D while blit is already + active, result is blitter getting confused and changing to weird cycle + diagram without D-channel. No writes, no memory corruption, no crash... +- above cases (blitter channel mode changing while active) also writes + message to log. I am not going to test all combinations :) + +Random freezing not yet fixed. + +I guess version will be renamed to 1.7 or 2.0 because of huge A500 +compatibility increase.. + +btw, I only have single non fully working A500 test statefile remaining, +I need more non-working A500 game/demo reports :) + Beta 3: Two main compatibility testing demos work perfectly now: