]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
imported winuaesrc1620b4.zip
authorToni Wilen <twilen@winuae.net>
Mon, 3 Aug 2009 14:47:51 +0000 (17:47 +0300)
committerToni Wilen <twilen@winuae.net>
Mon, 22 Feb 2010 19:47:33 +0000 (21:47 +0200)
blitter.c
custom.c
od-win32/hardfile_win32.c
od-win32/win32.c
od-win32/win32.h
od-win32/winuaechangelog.txt

index 691b9848a08a608e17051e430b1df45ea8a0185a..19961caba36231d553c232f614116a2ec4df89b3 100644 (file)
--- 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
     }
 
index 6efaa5c8e75f8a170bd42245d89757db5fa00813..9b9a26301bdff3daa7f3520dfb763140ae817867 100644 (file)
--- 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 (&regs, 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++) {
index 3ab3e4f304418802a899fc907801a2aff103674a..f8371aa0eafd018937a77693b9b9e9240945b5da 100644 (file)
@@ -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;
index 8aff34b805a151839e67204f9be209d5db34c807..e3b65987934cd072d859e5178e864c5fed643cb0 100644 (file)
@@ -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"<NULL>");
-       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)
 {
index ad08b766736593797f1ad87d6d94f69c163d0a77..8613ed3afe6084f9e536604eed06c35ab18944a3 100644 (file)
@@ -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""
 
index b8333832a0ef42b275db9527775dc8e6415f8066..2b7d89bb66f0b2db122b23470f7db160d4a2ed74 100644 (file)
@@ -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 <batch file>")
+- 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: