]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
imported winuaesrc1620b3.zip
authorToni Wilen <twilen@winuae.net>
Thu, 30 Jul 2009 14:03:07 +0000 (17:03 +0300)
committerToni Wilen <twilen@winuae.net>
Mon, 22 Feb 2010 19:47:27 +0000 (21:47 +0200)
17 files changed:
blitter.c
custom.c
disk.c
gencpu.c
include/blitter.h
inputdevice.c
newcpu.c
od-win32/bsdsock.c
od-win32/hardfile_win32.c
od-win32/resources/resource
od-win32/resources/winuae.rc
od-win32/sounddep/sound.c
od-win32/sounddep/sound.h
od-win32/win32.c
od-win32/win32.h
od-win32/win32gui.c
od-win32/winuaechangelog.txt

index d31791652aa9bffa9992ada9770f6c20102c7d90..691b9848a08a608e17051e430b1df45ea8a0185a 100644 (file)
--- a/blitter.c
+++ b/blitter.c
@@ -41,6 +41,7 @@ static int blitonedot, blitsign;
 static int blit_add;
 static int blit_modadda, blit_modaddb, blit_modaddc, blit_modaddd;
 static int blit_ch;
+static int vblitsize, hblitsize;
 
 #ifdef BLITTER_DEBUG
 static int blitter_dontdo;
@@ -57,7 +58,7 @@ uae_u32 blit_masktable[BLITTER_MAX_WORDS];
 enum blitter_states bltstate;
 
 static int blit_cyclecounter, blit_maxcyclecounter, blit_slowdown, blit_totalcyclecounter;
-static int blit_linecyclecounter, blit_misscyclecounter;
+static int blit_startcycles, blit_misscyclecounter;
 
 #ifdef CPUEMU_12
 extern uae_u8 cycle_line[];
@@ -77,14 +78,15 @@ int blit_interrupt;
 
 static int last_blitter_hpos;
 
-/*
+#define BLITTER_STARTUP_CYCLES 2
 
-    idle cycles are free cycles (available for CPU)
-    but for some reason they still require free bus cycle
+/*
+    Blitter Idle Cycle:
 
-    basically every blitter cycle requires free bus cycle,
-    "real" cycles are used for blitter DMA, idle cycles
-    are free for CPU (if CPU needs bus)
+    Cycles that are free cycles (available for CPU) and
+    are not used by any other Agnus DMA channel. Blitter
+    idle cycle is not "used" by blitter, CPU can still use
+    it normally if it needs the bus.
 
     same in both block and line modes
 
@@ -139,7 +141,7 @@ static const int blit_cycle_diagram_fill[][10] =
 };
 
 /*
-    -C-D -C-D ... -C-D -- (? difficult to confirm in logic analyzer)
+    -C-D C-D- ... C-D- --
     
     line draw takes 4 cycles (-C-D)
     idle cycles do the same as above, 2 dma fetches
@@ -156,6 +158,13 @@ static const int blit_cycle_diagram_fill[][10] =
     - disabling A-channel freezes the content of BPLAPT
     - C-channel disabled: nothing is written
 
+    There is one tricky situation, writing to DFF058 just before
+    last D write cycle (which is normally free) does not distrupt
+    blitter operation, final D is still written correctly before
+    blitter starts normally (after 2 idle cycles)
+
+    There is at least one demo that does this..
+    
 */
 
 // 5 = internal "processing cycle"
@@ -166,9 +175,15 @@ static const int blit_cycle_diagram_line[] =
 
 static const int blit_cycle_diagram_finald[] =
 {
-    2, 0,4,        0, 4
+    2, 0,4,        0,4
+};
+
+static const int blit_cycle_diagram_finalld[] =
+{
+    2, 0,0,        0,0
 };
 
+
 void build_blitfilltable (void)
 {
     unsigned int d, fillmask;
@@ -227,6 +242,8 @@ STATIC_INLINE int channel_state (int cycles)
 }
 STATIC_INLINE int channel_pos (int cycles)
 {
+    if (cycles < 0)
+       return 0;
     if (cycles < blit_diag[0])
        return cycles;
     cycles -= blit_diag[0];
@@ -260,7 +277,7 @@ static void blitter_interrupt (int hpos)
 static void blitter_done (int hpos)
 {
     ddat1use = ddat2use = 0;
-    bltstate = BLT_done;
+    bltstate = blit_startcycles == 0 ? BLT_done : BLT_init;
     blitter_interrupt (hpos);
     blitter_done_notify (hpos);
     if (debug_dma)
@@ -287,23 +304,23 @@ static void blitter_dofast (void)
     uae_u8 mt = bltcon0 & 0xFF;
 
     blit_masktable[0] = blt_info.bltafwm;
-    blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm;
+    blit_masktable[hblitsize - 1] &= blt_info.bltalwm;
 
     if (bltcon0 & 0x800) {
        bltadatptr = bltapt;
-       bltapt += (blt_info.hblitsize * 2 + blt_info.bltamod) * blt_info.vblitsize;
+       bltapt += (hblitsize * 2 + blt_info.bltamod) * vblitsize;
     }
     if (bltcon0 & 0x400) {
        bltbdatptr = bltbpt;
-       bltbpt += (blt_info.hblitsize * 2 + blt_info.bltbmod) * blt_info.vblitsize;
+       bltbpt += (hblitsize * 2 + blt_info.bltbmod) * vblitsize;
     }
     if (bltcon0 & 0x200) {
        bltcdatptr = bltcpt;
-       bltcpt += (blt_info.hblitsize * 2 + blt_info.bltcmod) * blt_info.vblitsize;
+       bltcpt += (hblitsize * 2 + blt_info.bltcmod) * vblitsize;
     }
     if (bltcon0 & 0x100) {
        bltddatptr = bltdpt;
-       bltdpt += (blt_info.hblitsize * 2 + blt_info.bltdmod) * blt_info.vblitsize;
+       bltdpt += (hblitsize * 2 + blt_info.bltdmod) * vblitsize;
     }
 
 #ifdef SPEEDUP
@@ -318,9 +335,9 @@ static void blitter_dofast (void)
        int dodst = 0;
 
        /*if (!blitfill) write_log (L"minterm %x not present\n",mt); */
-       for (j = 0; j < blt_info.vblitsize; j++) {
+       for (j = 0; j < vblitsize; j++) {
            blitfc = !!(bltcon1 & 0x4);
-           for (i = 0; i < blt_info.hblitsize; i++) {
+           for (i = 0; i < hblitsize; i++) {
                uae_u32 bltadat, blitahold;
                uae_u16 bltbdat;
                if (bltadatptr) {
@@ -376,7 +393,7 @@ static void blitter_dofast (void)
        blt_info.bltbhold = blitbhold;
     }
     blit_masktable[0] = 0xFFFF;
-    blit_masktable[blt_info.hblitsize - 1] = 0xFFFF;
+    blit_masktable[hblitsize - 1] = 0xFFFF;
 
     bltstate = BLT_done;
 }
@@ -388,23 +405,23 @@ static void blitter_dofast_desc (void)
     uae_u8 mt = bltcon0 & 0xFF;
 
     blit_masktable[0] = blt_info.bltafwm;
-    blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm;
+    blit_masktable[hblitsize - 1] &= blt_info.bltalwm;
 
     if (bltcon0 & 0x800) {
        bltadatptr = bltapt;
-       bltapt -= (blt_info.hblitsize*2 + blt_info.bltamod)*blt_info.vblitsize;
+       bltapt -= (hblitsize*2 + blt_info.bltamod)*vblitsize;
     }
     if (bltcon0 & 0x400) {
        bltbdatptr = bltbpt;
-       bltbpt -= (blt_info.hblitsize*2 + blt_info.bltbmod)*blt_info.vblitsize;
+       bltbpt -= (hblitsize*2 + blt_info.bltbmod)*vblitsize;
     }
     if (bltcon0 & 0x200) {
        bltcdatptr = bltcpt;
-       bltcpt -= (blt_info.hblitsize*2 + blt_info.bltcmod)*blt_info.vblitsize;
+       bltcpt -= (hblitsize*2 + blt_info.bltcmod)*vblitsize;
     }
     if (bltcon0 & 0x100) {
        bltddatptr = bltdpt;
-       bltdpt -= (blt_info.hblitsize*2 + blt_info.bltdmod)*blt_info.vblitsize;
+       bltdpt -= (hblitsize*2 + blt_info.bltdmod)*vblitsize;
     }
 #ifdef SPEEDUP
     if (blitfunc_dofast_desc[mt] && !blitfill) {
@@ -417,9 +434,9 @@ static void blitter_dofast_desc (void)
        uaecptr dstp = 0;
        int dodst = 0;
 
-       for (j = 0; j < blt_info.vblitsize; j++) {
+       for (j = 0; j < vblitsize; j++) {
            blitfc = !!(bltcon1 & 0x4);
-           for (i = 0; i < blt_info.hblitsize; i++) {
+           for (i = 0; i < hblitsize; i++) {
                uae_u32 bltadat, blitahold;
                uae_u16 bltbdat;
                if (bltadatptr) {
@@ -475,7 +492,7 @@ static void blitter_dofast_desc (void)
        blt_info.bltbhold = blitbhold;
     }
     blit_masktable[0] = 0xFFFF;
-    blit_masktable[blt_info.hblitsize - 1] = 0xFFFF;
+    blit_masktable[hblitsize - 1] = 0xFFFF;
 
     bltstate = BLT_done;
 }
@@ -581,7 +598,7 @@ static void blitter_line_proc (void)
 STATIC_INLINE void blitter_nxline (void)
 {
     blineb = (blineb << 1) | (blineb >> 15);
-    blt_info.vblitsize--;
+    vblitsize--;
     bltstate = BLT_read;
     blit_line_pixel = 0;
 }
@@ -595,72 +612,73 @@ static int blitter_vcounter1, blitter_vcounter2;
 static void decide_blitter_line (int hsync, int hpos)
 {
 
-    if (dmaen (DMA_BLITTER)) {
+    while (last_blitter_hpos < hpos) {
+        int c = channel_state (blit_cyclecounter);
 
-       while (last_blitter_hpos < hpos) {
-           int c = channel_state (blit_cyclecounter);
+       for (;;) {
 
-           if (blit_linecyclecounter > 0) {
-               blit_linecyclecounter--;
+           if (!canblit (last_blitter_hpos)) {
+               blit_misscyclecounter++;
                break;
            }
 
+           if (!dmaen (DMA_BLITTER) && (c == 3 || c == 4))
+               break;
 
-           for (;;) {
+           blit_cyclecounter++;
+           blit_totalcyclecounter++;
 
-               if (!canblit (last_blitter_hpos)) {
-                   blit_misscyclecounter++;
-                   break;
+           // final 2 idle cycles?
+           if (blit_diag == blit_cycle_diagram_finalld) {
+               if (blit_cyclecounter > blit_diag[0]) {
+                   bltdpt = bltcpt;
+                   blitter_done (last_blitter_hpos);
+                   return;
                }
+               break;
+           }
 
-               blit_cyclecounter++;
-               blit_totalcyclecounter++;
-
-               /* onedot mode and no pixel = bus write access is skipped */
-               if (c == 4 && blitsing && blitonedot > 1) {
-                   if (blt_info.vblitsize == 0) {
-                       bltdpt = bltcpt;
-                       blitter_done (last_blitter_hpos);
-                       return;
-                   }
-                   break;
+           /* onedot mode and no pixel = bus write access is skipped */
+           if (c == 4 && blitsing && blitonedot > 1) {
+               if (vblitsize == 0) {
+                   blit_diag = blit_cycle_diagram_finalld;
+                   blit_cyclecounter = 0;
                }
+               break;
+           }
 
-               if (c == 3) {
-
-                   blitter_read ();
-                   alloc_cycle_ext (last_blitter_hpos, CYCLE_BLITTER);
-                   record_dma_blit (0x70, blt_info.bltcdat, bltcpt, last_blitter_hpos);
-
-               } else if (c == 5) {
-
-                   if (ddat1use) {
-                       bltdpt = bltcpt;
-                   }
-                   ddat1use = 1;
-                   blitter_line ();
-                   blitter_line_proc ();
-                   blitter_nxline ();
+           if (c == 3) {
 
-               } else if (c == 4) {
+               blitter_read ();
+               alloc_cycle_ext (last_blitter_hpos, CYCLE_BLITTER);
+               record_dma_blit (0x70, blt_info.bltcdat, bltcpt, last_blitter_hpos);
 
-                   blitter_write ();
-                   alloc_cycle_ext (last_blitter_hpos, CYCLE_BLITTER);
-                   record_dma_blit (0x00, blt_info.bltddat, bltdpt, last_blitter_hpos);
-                   if (blt_info.vblitsize == 0) {
-                       bltdpt = bltcpt;
-                       blitter_done (last_blitter_hpos);
-                       return;
-                   }
+           } else if (c == 5) {
 
+               if (ddat1use) {
+                   bltdpt = bltcpt;
+               }
+               ddat1use = 1;
+               blitter_line ();
+               blitter_line_proc ();
+               blitter_nxline ();
+
+           } else if (c == 4) {
+
+               blitter_write ();
+               alloc_cycle_ext (last_blitter_hpos, CYCLE_BLITTER);
+               record_dma_blit (0x00, blt_info.bltddat, bltdpt, last_blitter_hpos);
+               if (vblitsize == 0) {
+                   blit_diag = blit_cycle_diagram_finalld;
+                   blit_cyclecounter = 0;
+                   break;
                }
 
-               break;
            }
-           last_blitter_hpos++;
+       
+           break;
        }
-    } else {
-       last_blitter_hpos = hpos;
+       last_blitter_hpos++;
     }
     if (hsync)
        last_blitter_hpos = 0;
@@ -678,7 +696,7 @@ static void actually_do_blit (void)
            blitter_write ();
            bltdpt = bltcpt;
            blitter_nxline ();
-           if (blt_info.vblitsize == 0)
+           if (vblitsize == 0)
                bltstate = BLT_done;
        } while (bltstate != BLT_done);
     } else {
@@ -734,7 +752,7 @@ STATIC_INLINE uae_u16 blitter_doblit (void)
     bltadat = blt_info.bltadat;
     if (blitter_hcounter1 == 0)
        bltadat &= blt_info.bltafwm;
-    if (blitter_hcounter1 == blt_info.hblitsize - 1)
+    if (blitter_hcounter1 == hblitsize - 1)
        bltadat &= blt_info.bltalwm;
     if (blitdesc)
        blitahold = (((uae_u32)bltadat << 16) | preva) >> blt_info.blitdownashift;
@@ -784,7 +802,7 @@ STATIC_INLINE int blitter_doddma (int hpos)
        chipmem_agnus_wput2 (bltdpt, d);
        bltdpt += blit_add;
        blitter_hcounter2++;
-       if (blitter_hcounter2 == blt_info.hblitsize) {
+       if (blitter_hcounter2 == hblitsize) {
            blitter_hcounter2 = 0;
            bltdpt += blit_modaddd;
            blitter_vcounter2++;
@@ -792,7 +810,7 @@ STATIC_INLINE int blitter_doddma (int hpos)
                blitter_vcounter1 = blitter_vcounter2;
        }
 #if 0
-       if (blitter_hcounter1 == 0 && blitter_vcounter1 == blt_info.vblitsize) {
+       if (blitter_hcounter1 == 0 && blitter_vcounter1 == vblitsize) {
            if (blit_diag != blit_cycle_diagram_finald) {
                blit_cyclecounter = -1;
                blit_diag = blit_cycle_diagram_finald;
@@ -849,7 +867,7 @@ STATIC_INLINE void blitter_dodma (int ch, int hpos)
        if (bltcon0 & 0x100)
            ddat1use = 1;
        blitter_hcounter1++;
-       if (blitter_hcounter1 == blt_info.hblitsize) {
+       if (blitter_hcounter1 == hblitsize) {
            blitter_hcounter1 = 0;
            if (bltcon0 & 0x800)
                bltapt += blit_modadda;
@@ -876,10 +894,32 @@ int blitter_need (int hpos)
     return c;
 }
 
+static void do_startcycles (int hpos)
+{
+    int vhpos = last_blitter_hpos;
+    while (vhpos < hpos) {
+       int v = canblit (vhpos);
+       vhpos++;
+       if (v) {
+           blit_startcycles--;
+           if (blit_startcycles == 0) {
+               bltstate = BLT_done;
+               do_blitter (vhpos, 0);
+               blit_startcycles = 0;
+               blit_cyclecounter = 0;
+               return;
+           }
+       }
+    }
+}
+
 void decide_blitter (int hpos)
 {
     int hsync = hpos < 0;
 
+    if (blit_startcycles > 0)
+       do_startcycles (hpos);
+
     if (bltstate == BLT_done)
        return;
 #ifdef BLITTER_DEBUG
@@ -900,86 +940,75 @@ void decide_blitter (int hpos)
        return;
     }
 
-    if (dmaen (DMA_BLITTER)) {
-       while (last_blitter_hpos < hpos) {
-           int c;
+    while (last_blitter_hpos < hpos) {
+       int c;
 
-           c = channel_state (blit_cyclecounter);
+       c = channel_state (blit_cyclecounter);
 
-           for (;;) {
-               int v;
+       for (;;) {
+           int v;
 
-               if (blit_linecyclecounter > 0) {
-                   blit_linecyclecounter--;
-                   break;
-               }
+           v = canblit (last_blitter_hpos);
 
-               v = canblit (last_blitter_hpos);
-
-               // idle cycles require free bus..
-               // (CPU can still use this cycle)
-               if (c == 0 && v == 0) {
-                   blitter_nasty++;
-                   blit_misscyclecounter++;
-                   break;
-               }
+           // idle cycles require free bus..
+           // (CPU can still use this cycle)
+           if (c == 0 && v == 0) {
+               blitter_nasty++;
+               blit_misscyclecounter++;
+               break;
+           }
 
-               if (c == 0) {
-                   blt_info.got_cycle = 1;
-                   blit_cyclecounter++;
-                   blit_totalcyclecounter++;
-                   /* check if blit with zero channels has ended  */
-                   if (blit_ch == 0 && blit_cyclecounter >= blit_maxcyclecounter) {
-                       blitter_done (last_blitter_hpos);
-                       return;
-                   }
-                   break;
+           if (c == 0) {
+               blt_info.got_cycle = 1;
+               blit_cyclecounter++;
+               blit_totalcyclecounter++;
+               /* check if blit with zero channels has ended  */
+               if (blit_ch == 0 && blit_cyclecounter >= blit_maxcyclecounter) {
+                   blitter_done (last_blitter_hpos);
+                   return;
                }
+               break;
+           }
 
-               blitter_nasty++;
+           blitter_nasty++;
 
-               if (v == 0) {
-                   blit_misscyclecounter++;
-                   break;
-               }
+           if (!dmaen (DMA_BLITTER) || v == 0) {
+               blit_misscyclecounter++;
+               break;
+           }
 
-               blt_info.got_cycle = 1;
-               if (c == 4) {
-                   if (blitter_doddma (last_blitter_hpos)) {
-                       blit_cyclecounter++;
-                       blit_totalcyclecounter++;
-                   }
-               } else {
-                   if (blitter_vcounter1 < blt_info.vblitsize) {
-                       blitter_dodma (c, last_blitter_hpos);
-                   }
+           blt_info.got_cycle = 1;
+           if (c == 4) {
+               if (blitter_doddma (last_blitter_hpos)) {
                    blit_cyclecounter++;
                    blit_totalcyclecounter++;
                }
-
-               if (blitter_vcounter1 >= blt_info.vblitsize && blitter_vcounter2 >= blt_info.vblitsize) {
-                   if (!ddat1use && !ddat2use) {
-                       blitter_done (last_blitter_hpos);
-                       return;
-                   }
+           } else {
+               if (blitter_vcounter1 < vblitsize) {
+                   blitter_dodma (c, last_blitter_hpos);
                }
-               break;
+               blit_cyclecounter++;
+               blit_totalcyclecounter++;
            }
 
-           if (blitter_vcounter1 == blt_info.vblitsize && channel_pos (blit_cyclecounter - 1) == blit_diag[0] - 1) {
-               if (blit_diag != blit_cycle_diagram_finald) {
-                   blitter_interrupt (last_blitter_hpos);
-                   blit_cyclecounter = 0;
-                   blit_diag = blit_cycle_diagram_finald;
+           if (blitter_vcounter1 >= vblitsize && blitter_vcounter2 >= vblitsize) {
+               if (!ddat1use && !ddat2use) {
+                   blitter_done (last_blitter_hpos);
+                   return;
                }
            }
-           last_blitter_hpos++;
+           break;
+       }
 
+       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);
+               blit_cyclecounter = 0;
+               blit_diag = blit_cycle_diagram_finald;
+           }
        }
-    } else {
-       last_blitter_hpos = hpos;
+       last_blitter_hpos++;
     }
-
     if (hsync)
        last_blitter_hpos = 0;
 }
@@ -1022,22 +1051,23 @@ static void blit_bltset (int con)
 
     blitdesc = bltcon1 & 2;
 
+    if (bltstate != BLT_done)
+       return;
+
+    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 (bltstate != BLT_done && con == 2)
-       return;
-
     blitline = bltcon1 & 1;
     blitfill = bltcon1 & 0x18;
     blit_ch = (bltcon0 & 0x0f00) >> 8;
 
     if (blitline) {
-       if (blt_info.hblitsize != 2)
+       if (hblitsize != 2)
            debugtest (DEBUGTEST_BLITTER, L"weird hblitsize in linemode: %d vsize=%d\n",
-               blt_info.hblitsize, blt_info.vblitsize);
+               hblitsize, vblitsize);
        blit_diag = blit_cycle_diagram_line;
     } else {
        if (con & 2) {
@@ -1083,8 +1113,6 @@ static void blit_modset (void)
 
 void reset_blit (int bltcon)
 {
-    if (bltcon == 1)
-       blinea_shift = bltcon0 >> 12;
     if (bltstate == BLT_done)
        return;
     if (bltcon)
@@ -1092,19 +1120,22 @@ void reset_blit (int bltcon)
     blit_modset ();
 }
 
-void do_blitter (int hpos)
+static void do_blitter2 (int hpos, int copper)
 {
     int cycles;
 
 #ifdef BLITTER_DEBUG_NOWAIT
     if (bltstate != BLT_done) {
+       if (blit_diag == blit_cycle_diagram_finald)
         write_log (L"blitter was already active! PC=%08x\n", M68K_GETPC);
     }
 #endif
+    bltstate = BLT_done;
 
+    hblitsize = blt_info.hblitsize;
+    vblitsize = blt_info.vblitsize;
     blitter_cycle_exact = currprefs.blitter_cycle_exact;
     blt_info.blitzero = 1;
-    bltstate = BLT_init;
     preva = 0;
     prevb = 0;
     blt_info.got_cycle = 0;
@@ -1113,7 +1144,7 @@ void do_blitter (int hpos)
     blit_misscyclecounter = 0;
     blit_last_cycle = 0;
     blit_maxcyclecounter = 0;
-    last_blitter_hpos = hpos;
+    last_blitter_hpos = hpos + 1;
     blit_cyclecounter = 0;
     blit_totalcyclecounter = 0;
 
@@ -1128,10 +1159,10 @@ void do_blitter (int hpos)
        blineb = (blt_info.bltbdat >> blt_info.blitbshift) | (blt_info.bltbdat << (16 - blt_info.blitbshift));
        blitsign = bltcon1 & 0x40;
        blitonedot = 0;
-       cycles = blt_info.vblitsize;
+       cycles = vblitsize;
     } else {
-       blit_firstline_cycles = blit_first_cycle + (blit_diag[0] * blt_info.hblitsize + cpu_cycles) * CYCLE_UNIT;
-       cycles = blt_info.vblitsize * blt_info.hblitsize;
+       blit_firstline_cycles = blit_first_cycle + (blit_diag[0] * hblitsize + cpu_cycles) * CYCLE_UNIT;
+       cycles = vblitsize * hblitsize;
     }
 
 #ifdef BLITTER_DEBUG
@@ -1147,18 +1178,20 @@ void do_blitter (int hpos)
        if (blit_ch & 8)
            ch++;
        write_log (L"blitstart: %dx%d ch=%d %d*%d=%d d=%d f=%02X n=%d pc=%p l=%d dma=%04X\n",
-           blt_info.hblitsize, blt_info.vblitsize, ch, blit_diag[0], cycles, blit_diag[0] * cycles,
+           hblitsize, vblitsize, ch, blit_diag[0], cycles, blit_diag[0] * cycles,
            blitdesc ? 1 : 0, blitfill, dmaen (DMA_BLITPRI) ? 1 : 0, M68K_GETPC, blitline, dmacon);
        blitter_dump ();
     }
 #endif
+
+    bltstate = BLT_init;
     blit_slowdown = 0;
 
     unset_special (&regs, SPCFLAG_BLTNASTY);
     if (dmaen (DMA_BLITPRI))
        set_special (&regs, SPCFLAG_BLTNASTY);
 
-    if (blt_info.vblitsize == 0 || (blitline && blt_info.hblitsize != 2)) {
+    if (vblitsize == 0 || (blitline && hblitsize != 2)) {
        blitter_done (hpos);
        return;
     }
@@ -1182,10 +1215,10 @@ void do_blitter (int hpos)
        blitter_hcounter1 = blitter_hcounter2 = 0;
        blitter_vcounter1 = blitter_vcounter2 = 0;
        if (blit_nod)
-           blitter_vcounter2 = blt_info.vblitsize;
-       blit_linecyclecounter = 3; // delay before blitter starts
-       blitter_cyclecounter = 0;
-       blit_maxcyclecounter = blt_info.hblitsize * blt_info.vblitsize + 2;
+           blitter_vcounter2 = vblitsize;
+       blit_cyclecounter = -(BLITTER_STARTUP_CYCLES + (copper ? 1 : 0));
+       blit_startcycles = 0;
+       blit_maxcyclecounter = hblitsize * vblitsize + 2;
        return;
     }
 
@@ -1197,6 +1230,17 @@ void do_blitter (int hpos)
     event2_newevent (ev2_blitter, blit_cyclecounter);
 }
 
+void do_blitter (int hpos, int copper)
+{
+    if (bltstate == BLT_done || !currprefs.blitter_cycle_exact) {
+       do_blitter2 (hpos, copper);
+       return;
+    }
+    // previous blit may be have last write cycle left
+    // we must let it finish
+    blit_startcycles = BLITTER_STARTUP_CYCLES + (copper ? 1 : 0);
+}
+
 void maybe_blit (int hpos, int hack)
 {
     static int warned;
@@ -1216,7 +1260,7 @@ void maybe_blit (int hpos, int hack)
 #ifdef BLITTER_DEBUG_NOWAIT
        warned = 0;
        write_log (L"program does not wait for blitter PC=%08x\n", M68K_GETPC);
-       //activate_debugger ();
+       activate_debugger ();
 #endif
     }
 
index 88ea26b6ee36a6e12c03af2ab1a0c719cf98df9c..6efaa5c8e75f8a170bd42245d89757db5fa00813 100644 (file)
--- a/custom.c
+++ b/custom.c
@@ -51,7 +51,7 @@
 #include "a2091.h"
 #include "ncr_scsi.h"
 
-//#define CUSTOM_DEBUG
+#define CUSTOM_DEBUG 0
 #define SPRITE_DEBUG 0
 #define SPRITE_DEBUG_MINY 0xb0
 #define SPRITE_DEBUG_MAXY 0xf8
@@ -261,6 +261,7 @@ int diwfirstword_total, diwlastword_total;
 int firstword_bplcon1;
 
 static int last_copper_hpos;
+static int copper_access;
 
 /* Sprite collisions */
 static unsigned int clxdat, clxcon, clxcon2, clxcon_bpl_enable, clxcon_bpl_match;
@@ -277,6 +278,7 @@ enum copper_states {
     COP_skip1,
     COP_strobe_delay1,
     COP_strobe_delay2,
+    COP_start_delay
 };
 
 struct copper {
@@ -780,7 +782,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;
+static int toscr_delay1, toscr_delay2, toscr_delay1x, toscr_delay2x;
 
 /* The number of bits left from the last fetched words.
    This is an optimization - conceptually, we have to make sure the result is
@@ -886,10 +888,10 @@ static void compute_toscr_delay_1 (void)
     delay1 += delayoffset;
     delay2 += delayoffset;
     delaymask = (fetchwidth - 1) >> 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);
+    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);
 }
 
 static void compute_toscr_delay (int hpos)
@@ -904,6 +906,8 @@ STATIC_INLINE void maybe_first_bpl1dat (int hpos)
        thisline_decision.plfleft = hpos;
        compute_delay_offset ();
        compute_toscr_delay_1 ();
+       toscr_delay1 = toscr_delay1x;
+       toscr_delay2 = toscr_delay2x;
     }
 }
 
@@ -1195,6 +1199,8 @@ 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);
@@ -1695,10 +1701,14 @@ static void maybe_start_bpl_dma (int hpos)
 STATIC_INLINE void decide_line (int hpos)
 {
     /* Take care of the vertical DIW.  */
-    if (vpos == plffirstline)
+    if (vpos == plffirstline) {
        diwstate = DIW_waiting_stop;
-    if (vpos == plflastline)
+       ddf_change = vpos;
+    }
+    if (vpos == plflastline) {
        diwstate = DIW_waiting_start;
+       ddf_change = vpos;
+    }
 
     if (hpos <= last_decide_line_hpos)
        return;
@@ -2311,12 +2321,13 @@ STATIC_INLINE int color_changes_differ (struct draw_info *dip, struct draw_info
 
 /* End of a horizontal scan line. Finish off all decisions that were not
  * made yet. */
-static void finish_decisions (int hpos)
+static void finish_decisions (void)
 {
     struct draw_info *dip;
     struct draw_info *dip_old;
     struct decision *dp;
     int changed;
+    int hpos = maxhpos;
 
     if (nodraw ())
        return;
@@ -2898,7 +2909,7 @@ static void COPJMP (int num, int vblank)
     cop_state.ignore_next = 0;
     if (!oldstrobe)
        cop_state.state_prev = cop_state.state;
-    cop_state.state = vblank ? COP_strobe_delay2 : COP_strobe_delay1;
+    cop_state.state = vblank ? COP_start_delay : COP_strobe_delay1;
     cop_state.vpos = vpos;
     cop_state.hpos = current_hpos () & ~1;
     copper_enabled_thisline = 0;
@@ -3481,8 +3492,6 @@ static void BLTCPTL (int hpos, uae_u16 v) { maybe_blit (hpos, 0); bltcpt = (bltc
 static void BLTDPTH (int hpos, uae_u16 v) { maybe_blit (hpos, 0); bltdpt = (bltdpt & 0xffff) | ((uae_u32)v << 16); }
 static void BLTDPTL (int hpos, uae_u16 v) { maybe_blit (hpos, 0); bltdpt = (bltdpt & ~0xffff) | (v & 0xFFFE); }
 
-// copper writing to BLTSIZE = 5 cycle delay before copper starts (6th cycle is first copper cycle)
-// CPU writing to BLTSIZE = 3 cycle delay
 static void BLTSIZE (int hpos, uae_u16 v)
 {
     maybe_blit (hpos, 0);
@@ -3493,7 +3502,7 @@ static void BLTSIZE (int hpos, uae_u16 v)
        blt_info.vblitsize = 1024;
     if (!blt_info.hblitsize)
        blt_info.hblitsize = 64;
-    do_blitter (hpos);
+    do_blitter (hpos, copper_access);
 }
 
 static void BLTSIZV (int hpos, uae_u16 v)
@@ -3514,7 +3523,7 @@ static void BLTSIZH (int hpos, uae_u16 v)
        blt_info.vblitsize = 32768;
     if (!blt_info.hblitsize)
        blt_info.hblitsize = 0x800;
-    do_blitter (hpos);
+    do_blitter (hpos, copper_access);
 }
 
 STATIC_INLINE void spr_arm (int num, int state)
@@ -3824,8 +3833,13 @@ STATIC_INLINE int copper_cant_read (int hpos)
 
 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);
-    return custom_wput_1 (hpos, addr, value, noget);
+    copper_access = 1;
+    v = custom_wput_1 (hpos, addr, value, noget);
+    copper_access = 0;
+    return v;
 }
 
 static void dump_copper (TCHAR *error, int until_hpos)
@@ -3842,14 +3856,14 @@ static void dump_copper (TCHAR *error, int until_hpos)
 // use only copper to write BPLCON1 etc.. (exception is HulkaMania/TSP..)
 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,2,0,0,0, /* 0x40 - 0x5e */
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x40 - 0x5e */
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x60 - 0x7e */
     0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0, /* 0x80 - 0x9e */
     1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0, /* 32 0xa0 - 0xde */
     /* BPLxPTH/BPLxPTL */
     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 16 */
     /* BPLCON0-3,BPLMOD1-2 */
-    0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 16 */
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 16 */
     /* SPRxPTH/SPRxPTL */
     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 16 */
     /* SPRxPOS/SPRxCTL/SPRxDATA/SPRxDATB */
@@ -3947,6 +3961,14 @@ static void update_copper (int until_hpos)
            if (debug_dma)
                record_dma (0x1fe, chipmem_agnus_wget (cop_state.ip + 2), cop_state.ip + 2, old_hpos, vpos);
            break;
+       case COP_start_delay:
+           if (copper_cant_read (old_hpos))
+               continue;
+           cop_state.state = COP_read1;
+           alloc_cycle (old_hpos, CYCLE_COPPER);
+           if (debug_dma)
+               record_dma (0x1fe, 0, 0xffffffff, old_hpos, vpos);
+           break;
 
        case COP_read1:
            if (copper_cant_read (old_hpos))
@@ -4156,14 +4178,28 @@ static void compute_spcflag_copper (int hpos)
     set_special (&regs, SPCFLAG_COPPER);
 }
 
+/*
+ Copper writes to BLTSIZE: 2 blitter idle cycles, blitter normal cycle starts
+ BFD=0 wait: blitter interrupt, 4 cycles, copper fetches next word
+*/
 void blitter_done_notify (int hpos)
 {
+    int vp = vpos;
+
     if (cop_state.state != COP_bltwait)
        return;
-    cop_state.hpos = (hpos + 2) & ~1;
-    cop_state.vpos = vpos;
+
+    hpos += 4;
+    hpos &= ~1;
+    if (hpos >= maxhpos) {
+       hpos -= maxhpos;
+       vp++;
+    }
+    cop_state.hpos = hpos;
+    cop_state.vpos = vp;
     cop_state.state = COP_read1;
-    if (dmaen (DMA_COPPER)) {
+
+    if (dmaen (DMA_COPPER) && vp == vpos) {
        copper_enabled_thisline = 1;
        set_special (&regs, SPCFLAG_COPPER);
     }
@@ -4280,8 +4316,6 @@ STATIC_INLINE void do_sprites_1 (int num, int cycle, int hpos)
        }
 #endif
     }
-    if (!dmaen (DMA_SPRITE))
-       return;
     if (cycle && !s->dmacycle)
        return; /* Superfrog intro flashing bee fix */
 
@@ -4393,22 +4427,26 @@ static void do_sprites (int hpos)
     if (minspr < SPR0_HPOS)
        minspr = SPR0_HPOS;
 
-    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 (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);
        }
-       if (cycle >= 0 && num >= 0 && num < MAX_SPRITES)
-           do_sprites_1 (num, cycle, i);
     }
+
     last_sprite_hpos = hpos;
 #else
     for (i = 0; i < MAX_SPRITES * 2; i++) {
@@ -4846,7 +4884,7 @@ static void hsync_scandoubler (void)
     }
     curr_color_changes[next_color_change].regno = -1;
 
-    finish_decisions (maxhpos);
+    finish_decisions ();
     hsync_record_line_state (next_lineno, nln_normal, thisline_changed);
     hardware_line_completed (next_lineno);
     scandoubled_line = 0;
@@ -4864,7 +4902,7 @@ static void hsync_handler (void)
     if (!nocustom ()) {
        sync_copper_with_cpu (maxhpos, 0);
        last_copper_hpos = 0;
-       finish_decisions (hpos);
+       finish_decisions ();
        if (thisline_decision.plfleft != -1) {
            if (currprefs.collision_level > 1)
                do_sprite_collisions ();
@@ -4976,7 +5014,7 @@ static void hsync_handler (void)
            alloc_cycle (hp, i == 0 ? CYCLE_STROBE : CYCLE_REFRESH); /* strobe */
 #ifdef DEBUGGER
            if (debug_dma)
-               record_dma (i == 0 ? (vpos + 1 == maxvpos + lof ? 0x3a : 0x3c) : 0x1fe, 0xffff, 0xffffffff, hp, vpos);
+               record_dma (i == 0 ? (vpos + 1 == maxvpos + lof ? 0x38 : 0x3c) : 0x1fe, 0xffff, 0xffffffff, hp, vpos);
 #endif
            hp += 2;
            if (hp >= maxhpos)
@@ -5562,7 +5600,7 @@ STATIC_INLINE uae_u32 REGPARAM2 custom_wget_1 (int hpos, uaecptr addr, int noput
     special_mem |= S_READ;
 #endif
     addr &= 0xfff;
-#ifdef CUSTOM_DEBUG
+#if CUSTOM_DEBUG > 2
     write_log (L"%d:%d:wget: %04X=%04X pc=%p\n", current_hpos(), vpos, addr, addr & 0x1fe, m68k_getpc ());
 #endif
     switch (addr & 0x1fe) {
@@ -5611,6 +5649,9 @@ STATIC_INLINE uae_u32 REGPARAM2 custom_wget_1 (int hpos, uaecptr addr, int noput
            decide_line (hpos);
            decide_fetch (hpos);
            decide_blitter (hpos);
+#if CUSTOM_DEBUG > 0
+           write_log (L"%04X read!\n", addr);
+#endif
            r = custom_wput_copper (hpos, addr, last_custom_value, 1);
            if (currprefs.chipset_mask & CSMASK_AGA) {
                v = last_custom_value;
@@ -5876,8 +5917,12 @@ static int REGPARAM2 custom_wput_1 (int hpos, uaecptr addr, uae_u32 value, int n
 
      /* writing to read-only register causes read access */
      default:
-       if (!noget)
+        if (!noget) {
+#if CUSTOM_DEBUG > 0
+           write_log (L"%04X written!\n", addr);
+#endif
            custom_wget_1 (hpos, addr, 1);
+        }
        return 1;
     }
     return 0;
@@ -5889,7 +5934,7 @@ static void REGPARAM2 custom_wput (uaecptr addr, uae_u32 value)
 #ifdef JIT
     special_mem |= S_WRITE;
 #endif
-#ifdef CUSTOM_DEBUG
+#if CUSTOM_DEBUG > 2
     write_log (L"%d:%d:wput: %04X %04X pc=%p\n", hpos, vpos, addr & 0x01fe, value & 0xffff, m68k_getpc ());
 #endif
     sync_copper_with_cpu (hpos, 1);
diff --git a/disk.c b/disk.c
index e9b18e48de51691c871d624e101fccf841d67a27..4ba5b7ca2c0e7dd0dbfdfe957ff4bf3a29a4b4ec 100644 (file)
--- a/disk.c
+++ b/disk.c
@@ -2563,6 +2563,30 @@ void DISK_handler (uae_u32 data)
 #endif
 }
 
+#ifdef CPUEMU_12
+extern uae_u8 cycle_line[256];
+
+static void diskdma (uae_u32 pt, uae_u16 w, int write)
+{
+    int i, got;
+
+    got = 0;
+    for (i = 7; i <= 11; i += 2) {
+       if (!cycle_line[i]) {
+           cycle_line[i] = CYCLE_MISC;
+           if (debug_dma)
+               record_dma (write ? 0x26 : 0x08, w, pt, i, vpos);
+           got = 1;
+           break;
+       }
+//     if (cycle_line[i] != CYCLE_MISC)
+//         write_log (L"%d!?\n", cycle_line[i]);
+    }
+//    if (!got)
+//     write_log (L"disk dma cycle overflow!?\n");
+}
+#endif
+
 static void disk_doupdate_write (drive * drv, int floppybits)
 {
     int dr;
@@ -2592,6 +2616,9 @@ static void disk_doupdate_write (drive * drv, int floppybits)
                for (dr = 0; dr < MAX_FLOPPY_DRIVES ; dr++) {
                    drive *drv2 = &floppy[dr];
                    uae_u16 w = get_word (dskpt);
+#ifdef CPUEMU_12
+                   diskdma (dskpt, w, 1);
+#endif
                    if (drives[dr]) {
                        drv2->bigmfmbuf[drv2->mfmpos >> 4] = w;
                        drv2->bigmfmbuf[(drv2->mfmpos >> 4) + 1] = 0x5555;
@@ -2693,10 +2720,6 @@ static void disk_doupdate_predict (drive * drv, int startcycle)
     }
 }
 
-#ifdef CPUEMU_12
-extern uae_u8 cycle_line[256];
-#endif
-
 static void disk_doupdate_read_nothing (int floppybits)
 {
     int j = 0, k = 1, l = 0;
@@ -2706,6 +2729,9 @@ static void disk_doupdate_read_nothing (int floppybits)
        if (bitoffset == 15 && dma_enable && dskdmaen == 2 && dsklength >= 0) {
            if (dsklength > 0) {
                put_word (dskpt, word);
+#ifdef CPUEMU_12
+               diskdma (dskpt, word, 0);
+#endif
                dskpt += 2;
            }
            dsklength--;
@@ -2769,11 +2795,10 @@ static void disk_doupdate_read (drive * drv, int floppybits)
        if (bitoffset == 15 && dma_enable && dskdmaen == 2 && dsklength >= 0) {
            if (dsklength > 0) {
                put_word (dskpt, word);
-               dskpt += 2;
 #ifdef CPUEMU_12
-               cycle_line[7] |= CYCLE_MISC;
-               cycle_line[9] |= CYCLE_MISC;
+               diskdma (dskpt, word, 0);
 #endif
+               dskpt += 2;
            }
 #if 0
            dma_tab[j++] = word;
index 6e3f867b4bc44327ad348f5cfd179aa896a1ed6d..565cb80e056ae9e8f53c513554db4a4ed100486e 100644 (file)
--- a/gencpu.c
+++ b/gencpu.c
@@ -35,6 +35,8 @@ static int using_prefetch, using_indirect, using_mmu;
 static int using_exception_3;
 static int using_ce;
 static int cpu_level;
+static int count_read, count_write, count_cycles, count_ncycles;
+static int count_read_ea, count_write_ea, count_cycles_ea;
 
 static int optimized_flags;
 
@@ -122,16 +124,19 @@ static void addcycles (int cycles)
 {
     if (!using_ce) return;
     printf ("\tdo_cycles_ce (%d * CYCLE_UNIT / 2);\n", cycles);
+    count_cycles += cycles;
 }
 static void addcycles2 (char *s, int cycles)
 {
     if (!using_ce) return;
     printf ("%sdo_cycles_ce (%d * CYCLE_UNIT / 2);\n", s, cycles);
+    count_cycles += cycles;
 }
 static void addcycles3 (char *s)
 {
     if (!using_ce) return;
     printf ("%sif (cycles > 0) do_cycles_ce (cycles);\n", s);
+    count_ncycles++;
 }
 
 static int isreg(amodes mode)
@@ -198,20 +203,26 @@ static void gen_nextilong (char *type, char *name, int norefill)
        /* we must do this because execution order of (something | something2) is not defined */
        if (norefill) {
            printf ("\t%s = get_word_ce_prefetch (regs, %d) << 16;\n", name, r + 2);
+           count_read++;
            printf ("\t%s |= regs->irc;\n", name);
        } else {
            printf ("\t%s = get_word_ce_prefetch (regs, %d) << 16;\n", name, r + 2);
+           count_read++;
            printf ("\t%s |= get_word_ce_prefetch (regs, %d);\n", name, r + 4);
+           count_read++;
        }
     } else {
        if (using_prefetch) {
            if (norefill) {
                printf ("\t%s %s;\n", type, name);
                printf ("\t%s = get_word_prefetch (regs, %d) << 16;\n", name, r + 2);
+               count_read++;
                printf ("\t%s |= regs->irc;\n", name);
                insn_n_cycles += 4;
            } else {
                printf ("\t%s %s = get_long_prefetch (regs, %d);\n", type, name, r + 2);
+               count_read++;
+               count_read++;
                insn_n_cycles += 8;
            }
        } else if (using_indirect) {
@@ -234,16 +245,19 @@ static const char *gen_nextiword (int norefill)
     m68k_pc_offset += 2;
 
     if (using_ce) {
-       if (norefill)
+       if (norefill) {
            strcpy (buffer, "regs->irc");
-       else
+       } else {
            sprintf (buffer, "get_word_ce_prefetch (regs, %d)", r + 2);
+           count_read++;
+       }
     } else {
        if (using_prefetch) {
            if (norefill) {
                sprintf (buffer, "regs->irc", r);
            } else {
                sprintf (buffer, "get_word_prefetch (regs, %d)", r + 2);
+               count_read++;
                insn_n_cycles += 4;
            }
        } else if (using_indirect) {
@@ -267,10 +281,12 @@ static const char *gen_nextibyte (int norefill)
     m68k_pc_offset += 2;
 
     if (using_ce) {
-       if (norefill)
+       if (norefill) {
            strcpy (buffer, "(uae_u8)regs->irc");
-       else
+       } else {
            sprintf (buffer, "(uae_u8)get_word_ce_prefetch (regs, %d)", r + 2);
+           count_read++;
+       }
     } else {
        insn_n_cycles += 4;
        if (using_prefetch) {
@@ -279,6 +295,7 @@ static const char *gen_nextibyte (int norefill)
            } else {
                sprintf (buffer, "(uae_u8)get_word_prefetch (regs, %d)", r + 2);
                insn_n_cycles += 4;
+               count_read++;
            }
        } else if (using_indirect)  {
            sprintf (buffer, "get_ibytei (%d)", r);
@@ -312,6 +329,7 @@ static void fill_prefetch_2 (void)
     else
        printf ("\tget_word_prefetch (regs, %d);\n", m68k_pc_offset + 2);
     did_prefetch = 1;
+    count_read++;
     insn_n_cycles += 4;
 }
 
@@ -325,6 +343,7 @@ static void fill_prefetch_1 (int o)
        printf ("\tget_word_prefetch (regs, %d);\n", o);
     }
     did_prefetch = 1;
+    count_read++;
     insn_n_cycles += 4;
 }
 
@@ -344,6 +363,7 @@ static void fill_prefetch_0 (void)
     else
        printf ("\tget_word_prefetch (regs, 0);\n");
     did_prefetch = 1;
+    count_read++;
     insn_n_cycles += 4;
 }
 
@@ -475,10 +495,12 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
        if (!(flags & GF_APDI)) {
            addcycles (2);
            insn_n_cycles += 2;
+           count_cycles_ea += 2;
        }
        break;
     case Ad16:
        printf ("\tuaecptr %sa = m68k_areg (regs, %s) + (uae_s32)(uae_s16)%s;\n", name, reg, gen_nextiword (flags & GF_NOREFILL));
+       count_read_ea++; 
        break;
     case Ad8r:
        printf ("\tuaecptr %sa;\n", name);
@@ -495,10 +517,12 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
                printf ("\t%sa = get_disp_ea_020 (regs, m68k_areg (regs, %s), next_iword (regs));\n", name, reg);
        } else {
            printf ("\t%sa = get_disp_ea_000 (regs, m68k_areg (regs, %s), %s);\n", name, reg, gen_nextiword (flags & GF_NOREFILL));
+           count_read_ea++; 
        }
        if (!(flags & GF_AD8R)) {
            addcycles (2);
            insn_n_cycles += 2;
+           count_cycles_ea += 2;
        }
        break;
     case PC16:
@@ -527,6 +551,7 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
        if (!(flags & GF_PC8R)) {
            addcycles (2);
            insn_n_cycles += 2;
+           count_cycles_ea += 2;
        }
 
        break;
@@ -535,6 +560,7 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
        break;
     case absl:
        gen_nextilong ("uaecptr", namea, flags & GF_NOREFILL);
+        count_read_ea += 2;
        break;
     case imm:
        if (getv != 1)
@@ -542,12 +568,15 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
        switch (size) {
        case sz_byte:
            printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte (flags & GF_NOREFILL));
+           count_read_ea++;
            break;
        case sz_word:
            printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword (flags & GF_NOREFILL));
+           count_read_ea++;
            break;
        case sz_long:
            gen_nextilong ("uae_s32", name, flags & GF_NOREFILL);
+           count_read_ea += 2;
            break;
        default:
            abort ();
@@ -557,16 +586,19 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
        if (getv != 1)
            abort ();
        printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte (flags & GF_NOREFILL));
+        count_read_ea++;
        return;
     case imm1:
        if (getv != 1)
            abort ();
        printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword (flags & GF_NOREFILL));
+        count_read_ea++;
        return;
     case imm2:
        if (getv != 1)
            abort ();
        gen_nextilong ("uae_s32", name, flags & GF_NOREFILL);
+        count_read_ea += 2;
        return;
     case immi:
        if (getv != 1)
@@ -597,9 +629,9 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
        start_brace ();
        if (using_ce) {
            switch (size) {
-           case sz_byte: printf ("\tuae_s8 %s = get_byte_ce (%sa);\n", name, name); break;
-           case sz_word: printf ("\tuae_s16 %s = get_word_ce (%sa);\n", name, name); break;
-           case sz_long: printf ("\tuae_s32 %s = get_word_ce (%sa) << 16; %s |= get_word_ce (%sa + 2);\n", name, name, name, name); break;
+           case sz_byte: printf ("\tuae_s8 %s = get_byte_ce (%sa);\n", name, name); count_read++; break;
+           case sz_word: printf ("\tuae_s16 %s = get_word_ce (%sa);\n", name, name); count_read++; break;
+           case sz_long: printf ("\tuae_s32 %s = get_word_ce (%sa) << 16; %s |= get_word_ce (%sa + 2);\n", name, name, name, name); count_read += 2; break;
            default: abort ();
            }
        } else if (using_mmu) {
@@ -611,9 +643,9 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
            }
        } else {
            switch (size) {
-           case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = get_byte (%sa);\n", name, name); break;
-           case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = get_word (%sa);\n", name, name); break;
-           case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = get_long (%sa);\n", name, name); break;
+           case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = get_byte (%sa);\n", name, name); count_read++; break;
+           case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = get_word (%sa);\n", name, name); count_read++; break;
+           case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = get_long (%sa);\n", name, name); count_read += 2; break;
            default: abort ();
            }
        }
@@ -698,11 +730,13 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha
            switch (size) {
             case sz_byte:
                printf ("\tput_byte_ce (%sa,%s);\n", to, from);
+               count_write++;
                break;
             case sz_word:
                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
                    abort ();
                printf ("\tput_word_ce (%sa,%s);\n", to, from);
+               count_write++;
                break;
             case sz_long:
                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
@@ -711,6 +745,7 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha
                    printf ("\tput_word_ce (%sa + 2, %s); put_word_ce (%sa, %s >> 16);\n", to, from, to, from);
                else
                    printf ("\tput_word_ce (%sa, %s >> 16); put_word_ce (%sa + 2, %s);\n", to, from, to, from);
+               count_write += 2;
                break;
             default:
                abort ();
@@ -741,18 +776,21 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha
             case sz_byte:
                insn_n_cycles += 4;
                printf ("\tput_byte (%sa,%s);\n", to, from);
+               count_write++;
                break;
             case sz_word:
                insn_n_cycles += 4;
                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
                    abort ();
                printf ("\tput_word (%sa,%s);\n", to, from);
+               count_write++;
                break;
             case sz_long:
                insn_n_cycles += 8;
                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
                    abort ();
                printf ("\tput_long (%sa,%s);\n", to, from);
+               count_write += 2;
                break;
             default:
                abort ();
@@ -799,18 +837,22 @@ static void genmovemel (uae_u16 opcode)
            strcpy (getcode, "(uae_s32)(uae_s16)get_word (srca)");
        }
     }
+    count_read += table68k[opcode].size == sz_long ? 2 : 1;
     printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0));
     printf ("\tunsigned int dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
     genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, 0);
-    fill_prefetch_next ();
     start_brace ();
     printf ("\twhile (dmask) { m68k_dreg (regs, movem_index1[dmask]) = %s; srca += %d; dmask = movem_next[dmask]; }\n",
            getcode, size);
     printf ("\twhile (amask) { m68k_areg (regs, movem_index1[amask]) = %s; srca += %d; amask = movem_next[amask]; }\n",
            getcode, size);
 
-    if (table68k[opcode].dmode == Aipi)
+    if (table68k[opcode].dmode == Aipi) {
        printf ("\tm68k_areg (regs, dstreg) = srca;\n");
+       count_read++;
+    }
+    fill_prefetch_next ();
+    count_ncycles++;
 }
 
 static void genmovemel_ce (uae_u16 opcode)
@@ -820,7 +862,6 @@ static void genmovemel_ce (uae_u16 opcode)
     printf ("\tunsigned int dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
     printf ("\tuae_u32 v;\n");
     genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, GF_AA);
-    fill_prefetch_next ();
     if (table68k[opcode].dmode == Ad8r || table68k[opcode].dmode == PC8r)
        addcycles (2);
     start_brace ();
@@ -836,8 +877,11 @@ static void genmovemel_ce (uae_u16 opcode)
                size);
     }
     printf ("\tget_word_ce (srca);\n"); // and final extra word fetch that goes nowhere..
+    count_read++;
     if (table68k[opcode].dmode == Aipi)
        printf ("\tm68k_areg (regs, dstreg) = srca;\n");
+    fill_prefetch_next ();
+    count_ncycles++;
 }
 
 static void genmovemle (uae_u16 opcode)
@@ -858,14 +902,10 @@ static void genmovemle (uae_u16 opcode)
            strcpy (putcode, "put_word (srca");
        }
     }
+    count_write += table68k[opcode].size == sz_long ? 2 : 1;
 
     printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0));
     genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, 0);
-    if (using_prefetch) {
-       sync_m68k_pc ();
-       fill_prefetch_next ();
-    }
-
     start_brace ();
     if (table68k[opcode].dmode == Apdi) {
        printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n");
@@ -886,6 +926,11 @@ static void genmovemle (uae_u16 opcode)
        printf ("\twhile (amask) { %s, m68k_areg (regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n",
                putcode, size);
     }
+    if (using_prefetch) {
+       sync_m68k_pc ();
+       fill_prefetch_next ();
+    }
+    count_ncycles++;
 }
 
 static void genmovemle_ce (uae_u16 opcode)
@@ -894,9 +939,9 @@ static void genmovemle_ce (uae_u16 opcode)
     printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0));
     genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, GF_AA);
 
-    if (table68k[opcode].dmode == Ad8r || table68k[opcode].dmode == PC8r)
+    if (table68k[opcode].dmode == Ad8r || table68k[opcode].dmode == PC8r) {
        addcycles (2);
-    fill_prefetch_next ();
+    }
     start_brace ();
     if (table68k[opcode].size == sz_long) {
        if (table68k[opcode].dmode == Apdi) {
@@ -929,6 +974,8 @@ static void genmovemle_ce (uae_u16 opcode)
                    size);
        }
     }
+    fill_prefetch_next ();
+    count_ncycles++;
 }
 
 static void duplicate_carry (int n)
@@ -1205,11 +1252,13 @@ static int source_is_imm1_8 (struct instr *i)
 static void shift_ce (amodes dmode, int size)
 {
     if (using_ce && isreg (dmode)) {
+       int c = size == sz_long ? 4 : 2;
        printf ("\t{\n");
-       printf ("\t\tint cycles = %d * CYCLE_UNIT / 2;\n", size == sz_long ? 4 : 2);
+       printf ("\t\tint cycles = %d * CYCLE_UNIT / 2;\n", c);
        printf ("\t\tcycles += 2 * CYCLE_UNIT / 2 * ccnt;\n");
        addcycles3 ("\t\t");
        printf ("\t}\n");
+       count_cycles += c;
     }
 }
 
@@ -1222,15 +1271,17 @@ static void bsetcycles (struct instr *curi)
         printf ("\tsrc &= 31;\n");
         if (isreg (curi->dmode)) {
            addcycles (2);
-           if (curi->mnemo != i_BTST)
+           if (curi->mnemo != i_BTST) {
                printf ("\tif (src > 15) do_cycles_ce (2 * CYCLE_UNIT / 2);\n");
+               count_ncycles++;
+           }
        }
     }
 }
 
 static int islongimm (struct instr *curi)
 {
-    return (curi->size == sz_long && (isreg (curi->smode) || curi->smode == imm || curi->smode == immi));
+    return (curi->size == sz_long && (curi->smode == Dreg || curi->smode == imm));
 }
 
 static void gen_opcode (unsigned long int opcode)
@@ -1271,10 +1322,25 @@ static void gen_opcode (unsigned long int opcode)
        genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
        printf ("\tsrc %c= dst;\n", curi->mnemo == i_OR ? '|' : curi->mnemo == i_AND ? '&' : '^');
        genflags (flag_logical, curi->size, "src", "", "");
-       if (curi->size == sz_long) {
-           int c = (curi->mnemo == i_EOR ? 4 : 2);
-           if (curi->mnemo != i_EOR && islongimm (curi))
-               c += 2;
+       if (curi->smode == imm) {
+           int c = 0;
+           if (curi->size == sz_long && curi->dmode == Dreg) {
+                // op.L #,Dn = +2 cycles (AND), +4 cycles (EOR,OR)
+               if (curi->mnemo == i_EOR || curi->mnemo == i_OR)
+                   c += 4;
+               else
+                   c += 2;
+           }
+           if (c > 0)
+               addcycles (c);
+       } else if (curi->smode == Dreg) {
+           int c = 0;
+           if (curi->dmode == Dreg) {
+               if (curi->size == sz_long)
+                   c += 2;
+               if (curi->size == sz_long && curi->smode == Dreg)
+                   c += 2;
+           }
            if (c > 0)
                addcycles (c);
        }
@@ -1307,11 +1373,11 @@ static void gen_opcode (unsigned long int opcode)
     case i_SUB:
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
        genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
-       if (isreg (curi->dmode)) {
+       if (curi->dmode == Dreg) {
            int c = 0;
            if (curi->size == sz_long) {
                c += 2;
-               if (islongimm (curi))
+               if (curi->smode == imm || curi->smode == immi || curi->smode == Dreg)
                    c += 2;
            }
            if (c > 0)
@@ -1325,7 +1391,11 @@ static void gen_opcode (unsigned long int opcode)
     case i_SUBA:
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
        genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
-       if (isreg (curi->dmode)) {
+       if (curi->smode == immi) {
+           int c = 4;
+           if (c > 0)
+               addcycles (c);
+       } else {
            int c = curi->size == sz_long ? 2 : 4;
            if (islongimm (curi))
                c += 2;
@@ -1340,12 +1410,10 @@ static void gen_opcode (unsigned long int opcode)
     case i_SUBX:
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
        genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
-       if (curi->size == sz_long) {
-           if (isreg (curi->smode))
-               addcycles (4);
-           else
-               addcycles (2);
-       }
+       if (curi->size == sz_long && isreg (curi->smode))
+           addcycles (4);
+       if (!isreg (curi->smode))
+           addcycles (2);
        fill_prefetch_next ();
        start_brace ();
        printf ("\tuae_u32 newv = dst - src - (GET_XFLG (&regs->ccrflags) ? 1 : 0);\n");
@@ -1382,11 +1450,11 @@ static void gen_opcode (unsigned long int opcode)
     case i_ADD:
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
        genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
-       if (isreg (curi->dmode)) {
+       if (curi->dmode == Dreg) {
            int c = 0;
            if (curi->size == sz_long) {
                c += 2;
-               if (islongimm (curi))
+               if (curi->smode == imm || curi->smode == immi || curi->smode == Dreg)
                    c += 2;
            }
            if (c > 0)
@@ -1400,7 +1468,13 @@ static void gen_opcode (unsigned long int opcode)
     case i_ADDA:
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
        genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
-       if (isreg (curi->dmode)) {
+       if (curi->smode == immi) {
+           int c = curi->size == sz_long ? 4 : 0;
+           if (islongimm (curi))
+               c += 2;
+           if (c > 0)
+               addcycles (c);
+       } else {
            int c = curi->size == sz_long ? 2 : 4;
            if (islongimm (curi))
                c += 2;
@@ -1415,12 +1489,10 @@ static void gen_opcode (unsigned long int opcode)
     case i_ADDX:
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
        genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
-       if (curi->size == sz_long) {
-           if (isreg (curi->smode))
-               addcycles (4);
-           else
-               addcycles (2);
-       }
+       if (curi->size == sz_long && isreg (curi->smode))
+           addcycles (4);
+       if (!isreg (curi->smode))
+           addcycles (2);
        fill_prefetch_next ();
        start_brace ();
        printf ("\tuae_u32 newv = dst + src + (GET_XFLG (&regs->ccrflags) ? 1 : 0);\n");
@@ -1539,7 +1611,7 @@ static void gen_opcode (unsigned long int opcode)
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
        genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
        bsetcycles (curi);
-       if (curi->mnemo == i_BCLR)
+       if (curi->mnemo == i_BCLR && curi->dmode == Dreg)
            addcycles (2);
        fill_prefetch_next ();
        if (curi->mnemo == i_BCHG) {
@@ -1564,10 +1636,8 @@ static void gen_opcode (unsigned long int opcode)
     case i_CMP:
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
        genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
-       if (isreg (curi->dmode)) {
-           if (curi->dmode == Areg || (curi->dmode == Dreg && curi->size == sz_long))
-               addcycles (2);
-       }
+       if (curi->dmode == Dreg && curi->size == sz_long)
+           addcycles (2);
        fill_prefetch_next ();
        start_brace ();
        genflags (flag_cmp, curi->size, "newv", "src", "dst");
@@ -1575,52 +1645,57 @@ static void gen_opcode (unsigned long int opcode)
     case i_CMPA:
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
        genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
-       if (isreg (curi->dmode)) {
-           if (curi->dmode == Areg || (curi->dmode == Dreg && curi->size == sz_long))
-               addcycles (2);
-       }
+       addcycles (2);
        fill_prefetch_next ();
        start_brace ();
        genflags (flag_cmp, sz_long, "newv", "src", "dst");
        break;
        /* The next two are coded a little unconventional, but they are doing
         * weird things... */
-    case i_MVPRM:
+    case i_MVPRM: // MOVEP R->M
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
        printf ("\tuaecptr memp = m68k_areg (regs, dstreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword (0));
        if (using_ce) {
            if (curi->size == sz_word) {
                printf ("\tput_byte_ce (memp, src >> 8); put_byte_ce (memp + 2, src);\n");
+               count_write += 2;
            } else {
                printf ("\tput_byte_ce (memp, src >> 24); put_byte_ce (memp + 2, src >> 16);\n");
                printf ("\tput_byte_ce (memp + 4, src >> 8); put_byte_ce (memp + 6, src);\n");
+               count_write += 4;
            }
        } else {
            if (curi->size == sz_word) {
                printf ("\tput_byte (memp, src >> 8); put_byte (memp + 2, src);\n");
+               count_write += 2;
            } else {
                printf ("\tput_byte (memp, src >> 24); put_byte (memp + 2, src >> 16);\n");
                printf ("\tput_byte (memp + 4, src >> 8); put_byte (memp + 6, src);\n");
+               count_write += 4;
            }
        }
        fill_prefetch_next ();
        break;
-    case i_MVPMR: // MOVEP
+    case i_MVPMR: // MOVEP M->R
        printf ("\tuaecptr memp = m68k_areg (regs, srcreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword (0));
        genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
        if (using_ce) {
            if (curi->size == sz_word) {
                printf ("\tuae_u16 val = (get_byte_ce (memp) << 8) + get_byte_ce (memp + 2);\n");
+               count_read += 2;
            } else {
                printf ("\tuae_u32 val = (get_byte_ce (memp) << 24) + (get_byte_ce (memp + 2) << 16)\n");
                printf ("              + (get_byte_ce (memp + 4) << 8) + get_byte_ce (memp + 6);\n");
+               count_read += 4;
            }
        } else {
            if (curi->size == sz_word) {
                printf ("\tuae_u16 val = (get_byte (memp) << 8) + get_byte (memp + 2);\n");
+               count_read += 2;
            } else {
                printf ("\tuae_u32 val = (get_byte (memp) << 24) + (get_byte (memp + 2) << 16)\n");
                printf ("              + (get_byte (memp + 4) << 8) + get_byte (memp + 6);\n");
+               count_read += 4;
            }
        }
        fill_prefetch_next ();
@@ -1742,7 +1817,8 @@ static void gen_opcode (unsigned long int opcode)
        break;
     case i_RESET:
        fill_prefetch_next ();
-       printf ("\tcpureset();\n");
+       printf ("\tcpureset ();\n");
+       addcycles (128);
        if (using_prefetch)
            printf ("\tregs->irc = get_iword (regs, 4);\n");
        break;
@@ -1848,16 +1924,17 @@ static void gen_opcode (unsigned long int opcode)
            printf ("\tm68k_do_rtsi(regs);\n");
        else
            printf ("\tm68k_do_rts(regs);\n");
+       count_read += 2;
        m68k_pc_offset = 0;
        fill_prefetch_full ();
        break;
     case i_TRAPV:
        sync_m68k_pc ();
+       fill_prefetch_next ();
        printf ("\tif (GET_VFLG (&regs->ccrflags)) {\n");
        printf ("\t\tException (7, regs, m68k_getpc (regs));\n");
        printf ("\t\tgoto %s;\n", endlabelstr);
        printf ("\t}\n");
-       fill_prefetch_next ();
        need_endlabel = 1;
        break;
     case i_RTR:
@@ -1881,9 +1958,13 @@ static void gen_opcode (unsigned long int opcode)
            printf ("\t}\n");
            need_endlabel = 1;
        }
+       if (curi->smode == Ad16 || curi->smode == absw || curi->smode == PC16)
+           addcycles (2);
        printf ("\tm68k_setpc (regs, srca);\n");
        m68k_pc_offset = 0;
        fill_prefetch_1 (0);
+       if (curi->smode == Ad8r || curi->smode == PC8r)
+           addcycles (6);
        printf("\tm68k_areg (regs, 7) -= 4;\n");
        if (using_ce) {
            printf("\tput_word_ce (m68k_areg (regs, 7), oldpc >> 16);\n");
@@ -1891,10 +1972,11 @@ static void gen_opcode (unsigned long int opcode)
        } else {
            printf("\tput_long (m68k_areg (regs, 7), oldpc);\n");
        }
+       count_write += 2;
        fill_prefetch_next ();
        break;
     case i_JMP:
-       genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA|GF_NOREFILL);
+       genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA | ((curi->smode == Ad8r || curi->smode == PC8r) ? 0 : GF_NOREFILL));
        if (using_exception_3) {
            printf ("\tif (srca & 1) {\n");
            printf ("\t\texception3i (opcode, m68k_getpc (regs) + 6, srca);\n");
@@ -1904,6 +1986,7 @@ static void gen_opcode (unsigned long int opcode)
        }
        if (curi->smode == Ad16 || curi->smode == Ad8r || curi->smode == absw || curi->smode == PC16 || curi->smode == PC8r)
            addcycles (2);
+//     if (using_ce && (curi->smode == Ad8r || curi->smode == PC8r))
        printf ("\tm68k_setpc (regs, srca);\n");
        m68k_pc_offset = 0;
        fill_prefetch_full ();
@@ -1926,6 +2009,7 @@ static void gen_opcode (unsigned long int opcode)
            printf ("\tm68k_do_bsri (regs, m68k_getpc (regs) + %d, s);\n", m68k_pc_offset);
        else
            printf ("\tm68k_do_bsr (regs, m68k_getpc (regs) + %d, s);\n", m68k_pc_offset);
+       count_write += 2;
        m68k_pc_offset = 0;
        fill_prefetch_full ();
        break;
@@ -1979,25 +2063,33 @@ static void gen_opcode (unsigned long int opcode)
            addcycles (2);
            irc2ir ();
            fill_prefetch_2 ();
-       } else
+       } else if (curi->size == sz_word) {
+           addcycles (2);
            fill_prefetch_full ();
+       } else {
+           fill_prefetch_full ();
+       }
        insn_n_cycles = curi->size == sz_byte ? 8 : 12;
        break;
     case i_LEA:
        genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA);
        genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, GF_AA);
        if (curi->smode == Ad8r || curi->smode == PC8r)
-           addcycles (4);
+           addcycles (2);
        fill_prefetch_next ();
+       if (curi->smode == Ad8r || curi->smode == PC8r)
+           addcycles (2);
        genastore ("srca", curi->dmode, "dstreg", curi->size, "dst");
        break;
     case i_PEA:
        genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA);
        genamode (Apdi, "7", sz_long, "dst", 2, 0, GF_AA);
        if (curi->smode == Ad8r || curi->smode == PC8r)
-           addcycles (4);
+           addcycles (2);
        if (!(curi->smode == absw || curi->smode == absl))
            fill_prefetch_next ();
+       if (curi->smode == Ad8r || curi->smode == PC8r)
+           addcycles (2);
        genastore ("srca", Apdi, "7", sz_long, "dst");
        if ((curi->smode == absw || curi->smode == absl))
            fill_prefetch_next ();
@@ -2068,8 +2160,10 @@ static void gen_opcode (unsigned long int opcode)
        printf ("\t} else {\n");
        printf ("\t\tuae_u32 newv = (uae_u32)dst / (uae_u32)(uae_u16)src;\n");
        printf ("\t\tuae_u32 rem = (uae_u32)dst %% (uae_u32)(uae_u16)src;\n");
+       fill_prefetch_next ();
        if (using_ce) {
-           printf ("\t\tint cycles = getDivu68kCycles((uae_u32)dst, (uae_u16)src) * CYCLE_UNIT / 2;\n");
+           start_brace ();
+           printf ("\t\tint cycles = (getDivu68kCycles((uae_u32)dst, (uae_u16)src) - 4) * CYCLE_UNIT / 2;\n");
            addcycles3 ("\t\t");
        }
        /* The N flag appears to be set each time there is an overflow.
@@ -2087,9 +2181,9 @@ static void gen_opcode (unsigned long int opcode)
        printf ("\t\t\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n");
        printf ("\t\t"); genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
        printf ("\t\t}\n");
-       fill_prefetch_next ();
        sync_m68k_pc ();
        printf ("\t}\n");
+       count_ncycles++;
        insn_n_cycles += 136 - (136 - 76) / 2; /* average */
        need_endlabel = 1;
        break;
@@ -2112,8 +2206,10 @@ static void gen_opcode (unsigned long int opcode)
        printf ("\t} else {\n");
        printf ("\t\tuae_s32 newv = (uae_s32)dst / (uae_s32)(uae_s16)src;\n");
        printf ("\t\tuae_u16 rem = (uae_s32)dst %% (uae_s32)(uae_s16)src;\n");
+       fill_prefetch_next ();
        if (using_ce) {
-           printf ("\t\tint cycles = getDivs68kCycles((uae_s32)dst, (uae_s16)src) * CYCLE_UNIT / 2;\n");
+           start_brace ();
+           printf ("\t\tint cycles = (getDivs68kCycles((uae_s32)dst, (uae_s16)src) - 4) * CYCLE_UNIT / 2;\n");
            addcycles3 ("\t\t");
        }
        printf ("\t\tif ((newv & 0xffff8000) != 0 && (newv & 0xffff8000) != 0xffff8000) {\n");
@@ -2130,9 +2226,9 @@ static void gen_opcode (unsigned long int opcode)
        printf ("\t\t\tnewv = (newv & 0xffff) | ((uae_u32)rem << 16);\n");
        printf ("\t\t"); genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
        printf ("\t\t}\n");
-       fill_prefetch_next ();
        sync_m68k_pc ();
        printf ("\t}\n");
+       count_ncycles++;
        insn_n_cycles += 156 - (156 - 120) / 2; /* average */
        need_endlabel = 1;
        break;
@@ -2143,7 +2239,7 @@ static void gen_opcode (unsigned long int opcode)
        start_brace ();
        printf ("\tuae_u32 newv = (uae_u32)(uae_u16)dst * (uae_u32)(uae_u16)src;\n");
        if (using_ce)
-           printf ("\tint cycles = 36 * CYCLE_UNIT / 2, bits;\n");
+           printf ("\tint cycles = (38 - 4) * CYCLE_UNIT / 2, bits;\n");
        genflags (flag_logical, sz_long, "newv", "", "");
        if (using_ce) {
            printf ("\tfor(bits = 0; bits < 16 && src; bits++, src >>= 1)\n");
@@ -2152,6 +2248,8 @@ static void gen_opcode (unsigned long int opcode)
        }
        genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
        sync_m68k_pc ();
+       count_cycles += 38 - 4;
+       count_ncycles++;
        insn_n_cycles += (70 - 38) / 2 + 38; /* average */
        break;
     case i_MULS:
@@ -2161,7 +2259,7 @@ static void gen_opcode (unsigned long int opcode)
        start_brace ();
        printf ("\tuae_u32 newv = (uae_s32)(uae_s16)dst * (uae_s32)(uae_s16)src;\n");
        if (using_ce) {
-           printf ("\tint cycles = 36 * CYCLE_UNIT / 2, bits;\n");
+           printf ("\tint cycles = (38 - 4) * CYCLE_UNIT / 2, bits;\n");
            printf ("\tuae_u32 usrc;\n");
        }
        genflags (flag_logical, sz_long, "newv", "", "");
@@ -2172,6 +2270,8 @@ static void gen_opcode (unsigned long int opcode)
            addcycles3 ("\t");
        }
        genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
+       count_cycles += 38 - 4;
+       count_ncycles++;
        insn_n_cycles += (70 - 38) / 2 + 38; /* average */
        break;
     case i_CHK:
@@ -2179,17 +2279,19 @@ static void gen_opcode (unsigned long int opcode)
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
        genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
        sync_m68k_pc ();
-       fill_prefetch_next ();
-       addcycles (6);
-       printf ("\tif ((uae_s32)dst < 0) {\n");
-       printf ("\t\tSET_NFLG (&regs->ccrflags, 1);\n");
+       addcycles (4);
+       printf ("\tif (dst > src) {\n");
+       printf ("\t\tSET_NFLG (&regs->ccrflags, 0);\n");
        printf ("\t\tException (6, regs, oldpc);\n");
        printf ("\t\tgoto %s;\n", endlabelstr);
-       printf ("\t} else if (dst > src) {\n");
-       printf ("\t\tSET_NFLG (&regs->ccrflags, 0);\n");
+       printf ("\t}\n");
+       addcycles (2);
+       printf ("\tif ((uae_s32)dst < 0) {\n");
+       printf ("\t\tSET_NFLG (&regs->ccrflags, 1);\n");
        printf ("\t\tException (6, regs, oldpc);\n");
        printf ("\t\tgoto %s;\n", endlabelstr);
        printf ("\t}\n");
+       fill_prefetch_next ();
        need_endlabel = 1;
        break;
     case i_CHK2:
@@ -2361,7 +2463,7 @@ static void gen_opcode (unsigned long int opcode)
     case i_ROL:
        genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
        genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0);
-       fill_prefetch_next();
+       fill_prefetch_next ();
        start_brace ();
        switch (curi->size) {
        case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
@@ -2391,7 +2493,7 @@ static void gen_opcode (unsigned long int opcode)
     case i_ROR:
        genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
        genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0);
-       fill_prefetch_next();
+       fill_prefetch_next ();
        start_brace ();
        switch (curi->size) {
        case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
@@ -2421,7 +2523,7 @@ static void gen_opcode (unsigned long int opcode)
     case i_ROXL:
        genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
        genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0);
-       fill_prefetch_next();
+       fill_prefetch_next ();
        start_brace ();
        switch (curi->size) {
        case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
@@ -2454,7 +2556,7 @@ static void gen_opcode (unsigned long int opcode)
     case i_ROXR:
        genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
        genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, 0);
-       fill_prefetch_next();
+       fill_prefetch_next ();
        start_brace ();
        switch (curi->size) {
        case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
@@ -3133,6 +3235,8 @@ static char *outopcode (int opcode)
        strcpy (out, s);
        xfree (s);
     }
+    if (ins->smode == immi)
+       strcat (out, "Q");
     if (ins->size == sz_byte)
        strcat (out,".B");
     if (ins->size == sz_word)
@@ -3255,11 +3359,23 @@ static void generate_one_opcode (int rp)
     need_endlabel = 0;
     endlabelno++;
     sprintf (endlabelstr, "endlabel%d", endlabelno);
+    count_read = count_write = count_ncycles = count_cycles = 0;
+    count_read_ea = count_write_ea = count_cycles_ea = 0;
     gen_opcode (opcode);
     if (need_endlabel)
        printf ("%s: ;\n", endlabelstr);
     returncycles ("", insn_n_cycles);
-    printf ("}\n");
+    printf ("}");
+    if (using_ce || using_prefetch) {
+       if (count_read + count_write + count_cycles == 0)
+           count_cycles = 4;
+       printf (" /* %d%s (%d/%d)",
+           (count_read + count_write) * 4 + count_cycles, count_ncycles ? "+" : "", count_read, count_write);
+       printf (" */\n");
+    } else {
+       printf("\n");
+    }
+    printf ("\n");
     if (i68000)
        printf("#endif\n");
     opcode_next_clev[rp] = next_cpu_level;
index 8d642a26c8b20fe4066e9d94ce963666d6131e8c..8eaebd7dd202c67105bec6cc9902b28d615a1ddb 100644 (file)
@@ -35,7 +35,7 @@ extern int blitnasty (void);
 extern int blitnnasty (int);
 extern void blitter_handler (uae_u32);
 extern void build_blitfilltable (void);
-extern void do_blitter (int);
+extern void do_blitter (int, int);
 extern void decide_blitter (int hpos);
 extern int blitter_need (int hpos);
 extern void blitter_done_notify (int hpos);
index f57a3b696fb1cecf46dc336cca677bf687ca964d..6c4b08d5e432af4c0000abe882f759ba12facdd8 100644 (file)
@@ -1925,13 +1925,13 @@ static int inputdelay;
 
 void inputdevice_hsync (void)
 {
-
+    static int cnt;
     cap_check ();
 
 #ifdef CATWEASEL
     catweasel_hsync ();
 #endif
-    if ((vpos & 31) == 31 && handle_msgpump ()) {
+    if ((++cnt & 63) == 63 && handle_msgpump ()) {
         idev[IDTYPE_MOUSE].read ();
         idev[IDTYPE_JOYSTICK].read ();
         idev[IDTYPE_KEYBOARD].read ();
index 03cd3b2faf4020e60a1147ac4364df236ff4332b..39ff49d62664ef0a8e9cb3cea4e0d11e1441e1a2 100644 (file)
--- a/newcpu.c
+++ b/newcpu.c
@@ -892,72 +892,124 @@ static void exception_debug (int nr)
 
 /* cycle-exact exception handler, 68000 only */
 
+/*
+
+Address/Bus Error:
+
+- 6 idle cycles
+- write PC low word
+- write SR
+- write PC high word
+- write instruction word
+- write fault address low word
+- write status code
+- write fault address high word
+- 2 idle cycles
+- read exception address high word
+- read exception address low word
+- prefetch
+- 2 idle cycles
+- prefetch
+
+Division by Zero:
+
+- 6 idle cycles
+- write PC low word
+- write SR
+- write PC high word
+- read exception address high word
+- read exception address low word
+- prefetch
+- 2 idle cycles
+- prefetch
+
+Traps:
+
+- 2 idle cycles
+- write PC low word
+- write SR
+- write PC high word
+- read exception address high word
+- read exception address low word
+- prefetch
+- 2 idle cycles
+- prefetch
+
+TrapV:
+
+- write PC low word
+- write SR
+- write PC high word
+- read exception address high word
+- read exception address low word
+- prefetch
+- 2 idle cycles
+- prefetch
+
+CHK:
+
+- 6 idle cycles
+- write PC low word
+- write SR
+- write PC high word
+- read exception address high word
+- read exception address low word
+- prefetch
+- 2 idle cycles
+- prefetch
+
+Illegal Instruction:
+
+- 2 idle cycles
+- write PC low word
+- write SR
+- write PC high word
+- read exception address high word
+- read exception address low word
+- prefetch
+- 2 idle cycles
+- prefetch
+
+Interrupt cycle diagram:
+
+- 6 idle cycles
+- read exception number byte from (0xfffff1 | (interrupt number << 1))
+- write PC low word
+- write SR
+- 4 idle cycles
+- write PC high word
+- read exception address high word
+- read exception address low word
+- prefetch
+- 2 idle cycles
+- prefetch
+
+*/
+
 static void Exception_ce (int nr, struct regstruct *regs, uaecptr oldpc)
 {
     uae_u32 currpc = m68k_getpc (regs), newpc;
-    int c;
     int sv = regs->s;
+    int start;
+    
+    start = 6;
+    if (nr == 7) // TRAPV
+       start = 0;
+    else if (nr >= 32 && nr < 32 + 16) // TRAP #x
+       start = 2;
+    else if (nr == 4 || nr == 8) // ILLG & PRIVIL VIOL
+       start = 2;
+
+    if (start)
+       do_cycles_ce (start * CYCLE_UNIT / 2);
+
+    if (nr >= 24 && nr < 24 + 8) { // fetch interrupt vector number
+       nr = get_byte_ce (0x00fffff1 | ((nr - 24) << 1));
+    }
 
     exception_debug (nr);
     MakeSR (regs);
 
-    c = 0;
-    switch (nr)
-    {
-       case 2: /* bus */
-       case 3: /* address */
-       c = 6;
-       break;
-       case 4: /* illegal instruction */
-       c = 6;
-       break;
-       case 5: /* divide by zero */
-       c = 10;
-       break;
-       case 6: /* chk */
-       c = 12;
-       break;
-       case 7: /* trapv */
-       c = 6;
-       break;
-       case 8: /* privilege */
-       c = 6;
-       break;
-       case 9: /* trace */
-       c = 6;
-       break;
-       case 25: /* interrupts */
-       case 26:
-       case 27:
-       case 28:
-       case 29:
-       case 30:
-       case 31:
-       c = 12;
-       break;
-       case 32: /* traps */
-       case 33:
-       case 34:
-       case 35:
-       case 36:
-       case 37:
-       case 38:
-       case 39:
-       case 40:
-       case 41:
-       case 42:
-       case 43:
-       case 44:
-       case 45:
-       case 46:
-       case 47:
-       c = 6;
-       break;
-    }
-    /* some delays are interleaved with stack pushes, not bothered yet..
-     */
-    if (c)
-       do_cycles_ce (c * CYCLE_UNIT / 2);
     if (!regs->s) {
        regs->usp = m68k_areg (regs, 7);
        m68k_areg (regs, 7) = regs->isp;
@@ -975,16 +1027,17 @@ static void Exception_ce (int nr, struct regstruct *regs, uaecptr oldpc)
        put_word_ce (m68k_areg (regs, 7) + 4, last_fault_for_exception_3);
        put_word_ce (m68k_areg (regs, 7) + 0, mode);
        put_word_ce (m68k_areg (regs, 7) + 2, last_fault_for_exception_3 >> 16);
+       do_cycles_ce (2 * CYCLE_UNIT / 2);
        write_log (L"Exception %d (%x) at %x -> %x!\n", nr, oldpc, currpc, get_long (4 * nr));
        goto kludge_me_do;
     }
     m68k_areg (regs, 7) -= 6;
-    put_word_ce (m68k_areg (regs, 7) + 4, currpc);
-    put_word_ce (m68k_areg (regs, 7) + 0, regs->sr);
-    put_word_ce (m68k_areg (regs, 7) + 2, currpc >> 16);
+    put_word_ce (m68k_areg (regs, 7) + 4, currpc); // write low address
+    put_word_ce (m68k_areg (regs, 7) + 0, regs->sr); // write SR
+    put_word_ce (m68k_areg (regs, 7) + 2, currpc >> 16); // write high address
 kludge_me_do:
-    newpc = get_word_ce (4 * nr) << 16;
-    newpc |= get_word_ce (4 * nr + 2);
+    newpc = get_word_ce (4 * nr) << 16; // read high address
+    newpc |= get_word_ce (4 * nr + 2); // read low address
     if (newpc & 1) {
        if (nr == 2 || nr == 3)
            uae_reset (1); /* there is nothing else we can do.. */
@@ -993,7 +1046,9 @@ kludge_me_do:
        return;
     }
     m68k_setpc (regs, newpc);
-    fill_prefetch_slow (regs);
+    regs->ir = get_word_ce (m68k_getpc (regs)); // prefetch 1
+    do_cycles_ce (2 * CYCLE_UNIT / 2);
+    regs->irc = get_word_ce (m68k_getpc (regs) + 2); // prefetch 2
     set_special (regs, SPCFLAG_END_COMPILE);
     exception_trace (nr);
 }
@@ -1004,6 +1059,9 @@ static void Exception_normal (int nr, struct regstruct *regs, uaecptr oldpc)
     uae_u32 currpc = m68k_getpc (regs), newpc;
     int sv = regs->s;
 
+    if (nr >= 24 && nr < 24 + 8 && currprefs.cpu_model <= 68010)
+       nr = get_byte (0x00fffff1 | (nr << 1));
+
     exception_debug (nr);
     MakeSR (regs);
 
@@ -1123,12 +1181,6 @@ kludge_me_do:
 
 void REGPARAM2 Exception (int nr, struct regstruct *regs, uaecptr oldpc)
 {
-#if 0
-    //if (nr < 24)
-    if (nr == 24 + 3)
-       write_log (L"exception %d %08X %08X (%04X %04X)\n",
-           nr, oldpc, m68k_getpc (regs), intena, intreq);
-#endif
 #ifdef CPUEMU_12
     if (currprefs.cpu_cycle_exact && currprefs.cpu_model == 68000)
        Exception_ce (nr, regs, oldpc);
@@ -1139,24 +1191,11 @@ void REGPARAM2 Exception (int nr, struct regstruct *regs, uaecptr oldpc)
 
 STATIC_INLINE void do_interrupt (int nr, struct regstruct *regs)
 {
-    int vector;
-#if 0
-    if (nr == 2)
-       write_log (L".");
-       //write_log (L"irq %d at %x (%04X) ", nr, m68k_getpc (regs), intena & intreq);
-#endif
     regs->stopped = 0;
     unset_special (regs, SPCFLAG_STOP);
     assert (nr < 8 && nr >= 0);
 
-    if (currprefs.cpu_cycle_exact)
-       vector = get_byte_ce (0x00fffff1 | (nr << 1));
-    else if (currprefs.cpu_model <= 68010)
-       vector = get_byte (0x00fffff1 | (nr << 1));
-    else
-       vector = nr + 24;
-
-    Exception (vector, regs, 0);
+    Exception (nr + 24, regs, 0);
 
     regs->intmask = nr;
     doint ();
@@ -3310,9 +3349,9 @@ int getDivu68kCycles (uae_u32 dividend, uae_u16 divisor)
 
     // Overflow
     if ((dividend >> 16) >= divisor)
-       return (mcycles = 5 - 2) * 2;
+       return (mcycles = 5) * 2;
 
-    mcycles = 38 - 2;
+    mcycles = 38;
     hdivisor = divisor << 16;
 
     for (i = 0; i < 15; i++) {
@@ -3344,7 +3383,7 @@ int getDivs68kCycles (uae_s32 dividend, uae_s16 divisor)
     if (divisor == 0)
        return 0;
 
-    mcycles = 6 - 2;
+    mcycles = 6;
 
     if (dividend < 0)
        mcycles++;
index ae29348128d3bb2f84280fc1f586fba44b163ffa..62eb0adad826a32d58d76527a618178d2498c418 100644 (file)
@@ -2298,6 +2298,7 @@ kludge:
 
                BSDTRACE((L"OK (%s)\n", h->h_name));
                bsdsocklib_seterrno(sb, 0);
+               bsdsocklib_setherrno(sb, 0);
 
        } else {
                BSDTRACE((L"failed (%d/%d)\n", sb->sb_errno, sb->sb_herrno));
index a4d368be50e36aaf040b4d8164ebbe841a206bcb..3ab3e4f304418802a899fc907801a2aff103674a 100644 (file)
@@ -1113,7 +1113,8 @@ static BOOL GetDevicePropertyFromName(const TCHAR *DevicePath, DWORD Index, DWOR
            PARTITION_INFORMATION *pi = &dli->PartitionEntry[i];
            if (pi->PartitionType == PARTITION_ENTRY_UNUSED)
                continue;
-           write_log (L"%d: num: %d type: %02X offset: %I64d size: %I64d, ", i, pi->PartitionNumber, pi->PartitionType, pi->StartingOffset.QuadPart, pi->PartitionLength.QuadPart);
+           write_log (L"%d: num: %d type: %02X offset: %I64d size: %I64d, ", i,
+               pi->PartitionNumber, pi->PartitionType, pi->StartingOffset.QuadPart, pi->PartitionLength.QuadPart);
            if (pi->RecognizedPartition == 0) {
                write_log (L"unrecognized\n");
                continue;
@@ -1128,12 +1129,10 @@ static BOOL GetDevicePropertyFromName(const TCHAR *DevicePath, DWORD Index, DWOR
            udi->offset = pi->StartingOffset.QuadPart;
            udi->size = pi->PartitionLength.QuadPart;
            write_log (L"used\n");
-           if (safetycheck (hDevice, udi->device_path, udi->offset, buffer, dg.BytesPerSector) <= 0) {
-               _stprintf (udi->device_name, L"HD_P#%d_%s", pi->PartitionNumber, orgname);
-               udi++;
-               (*index2)++;
-               safepart = 1;
-           }
+           _stprintf (udi->device_name, L"HD_P#%d_%s", pi->PartitionNumber, orgname);
+           udi++;
+           (*index2)++;
+           safepart = 1;
            gotpart = 1;
        }
        if (!nonzeropart) {
@@ -1146,10 +1145,11 @@ static BOOL GetDevicePropertyFromName(const TCHAR *DevicePath, DWORD Index, DWOR
     } else {
        write_log (L"no MBR partition table detected, checking for RDB\n");
     }
-
-    udi->dangerous = safetycheck (hDevice, udi->device_path, 0, buffer, dg.BytesPerSector);
-    if (udi->dangerous > 0)
-       goto end;
+    if (udi->offset == 0) {
+       udi->dangerous = safetycheck (hDevice, udi->device_path, 0, buffer, dg.BytesPerSector);
+       if (udi->dangerous > 0)
+           goto end;
+    }
 amipartfound:
     _stprintf (udi->device_name, L"HD_%s", orgname);
     {
index 31d7e2e9fe12f52386203c2949e5e2ecf578cebb..8c962921d479a8b6b707c7e868a12612cc848a25 100644 (file)
 #define IDC_PATHS_CONFIGS               1662
 #define IDC_SOUNDSWAP                   1662
 #define IDC_PATHS_SCREENSHOTS           1663
+#define IDC_SOUNDFREQ2                  1663
 #define IDC_PATHS_SAVESTATES            1664
 #define IDC_SOUNDSTEREOSWAPTXT          1664
 #define IDC_SOUNDSWAPTXT                1664
 #define IDC_SOUND_AUTO                  1709
 #define IDC_FILTERKEEPASPECT            1709
 #define IDC_CS_RTC                      1710
-#define IDC_SOUND_AUTO2                 1710
 #define IDC_SOUND_EXCLUSIVE             1710
 #define IDC_CS_CIAA_TOD1                1711
 #define IDC_CS_CIAA_TOD2                1712
 #define IDC_CS_EXT                      1712
 #define IDC_CS_CIAA_TOD3                1713
+#define IDC_SOUND_DS                    1713
 #define IDC_CS_COMPATIBLE               1714
 #define IDC_CS_RAMSEYREV                1715
+#define IDC_SOUND_WASAPI                1715
 #define IDC_CS_KSMIRROR_E0              1716
 #define IDC_STRINGBOXEDIT               1716
+#define IDC_SOUND_OPENAL                1716
 #define IDC_CS_CD32CD                   1717
 #define IDC_CS_CD32C2P                  1718
+#define IDC_SOUND_PORTAUDIO             1718
 #define IDC_CS_CD32NVRAM                1719
 #define IDC_CS_CDTVCD                   1720
 #define IDC_CS_CDTVRAM                  1721
index ff7636111915e0278b73b071e82c506b0a63a6bc..d4dcb9cc4d0deec8ed0ff38857dc63e284079944 100644 (file)
@@ -293,44 +293,49 @@ BEGIN
                     "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,203,100,10\r
 END\r
 \r
-IDD_SOUND DIALOGEX 0, 0, 300, 231\r
+IDD_SOUND DIALOGEX 0, 0, 300, 237\r
 STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD\r
 FONT 8, "MS Sans Serif", 0, 0, 0x1\r
 BEGIN\r
-    COMBOBOX        IDC_SOUNDCARDLIST,5,9,291,50,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
-    GROUPBOX        "Sound Emulation",IDC_SOUNDSETTINGS,5,26,120,85\r
-    CONTROL         "Disabled",IDC_SOUND0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,13,41,101,10\r
-    CONTROL         "Disabled, but emulated",IDC_SOUND1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,54,102,10\r
-    CONTROL         "Enabled",IDC_SOUND2,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,67,102,10\r
-    CONTROL         "Enabled, 100% accurate",IDC_SOUND3,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,80,101,10\r
-    GROUPBOX        "Volume",IDC_STATIC,132,42,164,31\r
-    CONTROL         "",IDC_SOUNDVOLUME,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,137,50,105,20\r
-    EDITTEXT        IDC_SOUNDVOLUME2,247,53,40,12,ES_CENTER | ES_READONLY\r
-    GROUPBOX        "Sound Buffer Size",IDC_STATIC,132,79,164,31\r
-    CONTROL         "Slider1",IDC_SOUNDBUFFERRAM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,137,87,105,19\r
-    EDITTEXT        IDC_SOUNDBUFFERMEM,247,90,40,12,ES_CENTER | ES_READONLY\r
-    GROUPBOX        "Settings",IDC_SOUNDINTERPOLATION2,6,114,290,60\r
-    LTEXT           "Frequency:",IDC_SOUNDFREQTXT,11,148,53,8,SS_CENTERIMAGE\r
-    COMBOBOX        IDC_SOUNDFREQ,13,157,51,75,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP\r
-    LTEXT           "Audio filter:",IDC_SOUNDFILTERTXT,209,148,77,8,SS_CENTERIMAGE\r
-    COMBOBOX        IDC_SOUNDFILTER,209,157,80,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
-    LTEXT           "Channel mode:",IDC_SOUNDSTEREOTXT,11,124,57,8,SS_CENTERIMAGE\r
-    COMBOBOX        IDC_SOUNDSTEREO,13,133,122,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
-    LTEXT           "Interpolation:",IDC_SOUNDINTERPOLATIONTXT,209,124,75,8,SS_CENTERIMAGE\r
-    COMBOBOX        IDC_SOUNDINTERPOLATION,209,133,80,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
-    LTEXT           "Stereo separation:",IDC_SOUNDSTEREOSEPTXT,141,124,63,8,SS_CENTERIMAGE\r
-    COMBOBOX        IDC_SOUNDSTEREOSEP,142,133,62,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
-    LTEXT           "Stereo delay:",IDC_SOUNDSTEREOMIXTXT,141,148,63,8,SS_CENTERIMAGE\r
-    COMBOBOX        IDC_SOUNDSTEREOMIX,142,157,62,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
-    GROUPBOX        "Floppy Drive Sound Emulation",IDC_STATIC,6,177,290,46\r
-    CONTROL         "",IDC_SOUNDDRIVEVOLUME,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,14,185,107,19\r
-    EDITTEXT        IDC_SOUNDDRIVEVOLUME2,124,187,40,12,ES_CENTER | ES_READONLY\r
-    COMBOBOX        IDC_SOUNDDRIVE,237,187,46,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
-    COMBOBOX        IDC_SOUNDDRIVESELECT,18,205,265,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
-    COMBOBOX        IDC_SOUNDSWAP,73,157,62,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
-    LTEXT           "Swap channels:",IDC_SOUNDSWAPTXT,74,148,61,8,SS_CENTERIMAGE\r
-    CONTROL         "Automatic switching",IDC_SOUND_AUTO,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,14,95,103,10\r
-    CONTROL         "Exclusive mode",IDC_SOUND_EXCLUSIVE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,137,31,154,10\r
+    COMBOBOX        IDC_SOUNDCARDLIST,5,3,291,50,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
+    GROUPBOX        "Sound Emulation",IDC_SOUNDSETTINGS,5,20,120,85\r
+    CONTROL         "Disabled",IDC_SOUND0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,13,35,101,10\r
+    CONTROL         "Disabled, but emulated",IDC_SOUND1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,48,102,10\r
+    CONTROL         "Enabled",IDC_SOUND2,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,61,102,10\r
+    CONTROL         "Enabled, 100% accurate",IDC_SOUND3,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,13,74,101,10\r
+    GROUPBOX        "Volume",IDC_STATIC,132,36,164,31\r
+    CONTROL         "",IDC_SOUNDVOLUME,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,137,44,105,20\r
+    EDITTEXT        IDC_SOUNDVOLUME2,247,47,40,12,ES_CENTER | ES_READONLY\r
+    GROUPBOX        "Sound Buffer Size",IDC_STATIC,132,73,164,31\r
+    CONTROL         "Slider1",IDC_SOUNDBUFFERRAM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,137,81,105,19\r
+    EDITTEXT        IDC_SOUNDBUFFERMEM,247,84,40,12,ES_CENTER | ES_READONLY\r
+    GROUPBOX        "Settings",IDC_SOUNDINTERPOLATION2,6,106,290,60\r
+    LTEXT           "Frequency:",IDC_SOUNDFREQTXT,11,140,53,8,SS_CENTERIMAGE\r
+    COMBOBOX        IDC_SOUNDFREQ,13,149,51,75,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP\r
+    LTEXT           "Audio filter:",IDC_SOUNDFILTERTXT,209,140,77,8,SS_CENTERIMAGE\r
+    COMBOBOX        IDC_SOUNDFILTER,209,149,80,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
+    LTEXT           "Channel mode:",IDC_SOUNDSTEREOTXT,11,116,57,8,SS_CENTERIMAGE\r
+    COMBOBOX        IDC_SOUNDSTEREO,13,125,122,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
+    LTEXT           "Interpolation:",IDC_SOUNDINTERPOLATIONTXT,209,116,75,8,SS_CENTERIMAGE\r
+    COMBOBOX        IDC_SOUNDINTERPOLATION,209,125,80,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
+    LTEXT           "Stereo separation:",IDC_SOUNDSTEREOSEPTXT,141,116,63,8,SS_CENTERIMAGE\r
+    COMBOBOX        IDC_SOUNDSTEREOSEP,142,125,62,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
+    LTEXT           "Stereo delay:",IDC_SOUNDSTEREOMIXTXT,141,140,63,8,SS_CENTERIMAGE\r
+    COMBOBOX        IDC_SOUNDSTEREOMIX,142,149,62,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
+    GROUPBOX        "Floppy Drive Sound Emulation",IDC_STATIC,6,172,220,60\r
+    CONTROL         "",IDC_SOUNDDRIVEVOLUME,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,14,186,107,19\r
+    EDITTEXT        IDC_SOUNDDRIVEVOLUME2,124,188,40,12,ES_CENTER | ES_READONLY\r
+    COMBOBOX        IDC_SOUNDDRIVE,173,187,46,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
+    COMBOBOX        IDC_SOUNDDRIVESELECT,18,209,202,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
+    COMBOBOX        IDC_SOUNDSWAP,73,149,62,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
+    LTEXT           "Swap channels:",IDC_SOUNDSWAPTXT,74,140,61,8,SS_CENTERIMAGE\r
+    CONTROL         "Automatic switching",IDC_SOUND_AUTO,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,14,89,103,10\r
+    CONTROL         "Exclusive mode",IDC_SOUND_EXCLUSIVE,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,137,25,154,10\r
+    CONTROL         "DirectSound",IDC_SOUND_DS,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,235,181,55,10\r
+    CONTROL         "WASAPI",IDC_SOUND_WASAPI,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,235,193,53,10\r
+    CONTROL         "OpenAL",IDC_SOUND_OPENAL,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,235,205,53,10\r
+    CONTROL         "PortAudio",IDC_SOUND_PORTAUDIO,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,235,217,58,10\r
+    GROUPBOX        "Drivers",IDC_STATIC,230,172,66,60\r
 END\r
 \r
 IDD_LOADSAVE DIALOGEX 0, 0, 302, 241\r
index 107f8bce1af81520c8f2868246cfd8d3264ecfab..21e3c47dc02627e7e2cf68fd4c37d4a97bdf3a2f 100644 (file)
@@ -113,6 +113,7 @@ struct sound_dp
 
 int sound_debug = 0;
 int sound_mode_skip = 0;
+int sounddrivermask;
 
 static int have_sound;
 static int statuscnt;
@@ -2139,61 +2140,65 @@ int enumerate_sound_devices (void)
     if (!num_sound_devices) {
        HMODULE l = NULL;
        write_log (L"Enumerating DirectSound devices..\n");
-       if (os_vista)
+       if (os_vista && (sounddrivermask & SOUNDDRIVER_WASAPI))
            wasapi_enum (sound_devices);
-       if (1 || force_directsound || !os_vista) {
+       if ((1 || force_directsound || !os_vista) && (sounddrivermask & SOUNDDRIVER_DS)) {
            DirectSoundEnumerate ((LPDSENUMCALLBACK)DSEnumProc, sound_devices);
            //DirectSoundCaptureEnumerate ((LPDSENUMCALLBACK)DSEnumProc, record_devices);
        }
-       __try {
-           if (isdllversion (L"openal32.dll", 6, 14, 357, 22)) {
-               write_log (L"Enumerating OpenAL devices..\n");
-               if (alcIsExtensionPresent (NULL, "ALC_ENUMERATION_EXT")) {
-                   const char* ppDefaultDevice = alcGetString (NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
-                   const char* pDeviceNames = alcGetString (NULL, ALC_DEVICE_SPECIFIER);
-                   if (alcIsExtensionPresent (NULL, "ALC_ENUMERATE_ALL_EXT"))
-                       pDeviceNames = alcGetString (NULL, ALC_ALL_DEVICES_SPECIFIER);
-                   OpenALEnumerate (sound_devices, pDeviceNames, ppDefaultDevice, FALSE);
-#if 0
-                   ppDefaultDevice = alcGetString (NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
-                   pDeviceNames = alcGetString (NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
-                   OpenALEnumerate (record_devices, pDeviceNames, ppDefaultDevice, TRUE);
-#endif
+       if (sounddrivermask & SOUNDDRIVER_OPENAL) {
+           __try {
+               if (isdllversion (L"openal32.dll", 6, 14, 357, 22)) {
+                   write_log (L"Enumerating OpenAL devices..\n");
+                   if (alcIsExtensionPresent (NULL, "ALC_ENUMERATION_EXT")) {
+                       const char* ppDefaultDevice = alcGetString (NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
+                       const char* pDeviceNames = alcGetString (NULL, ALC_DEVICE_SPECIFIER);
+                       if (alcIsExtensionPresent (NULL, "ALC_ENUMERATE_ALL_EXT"))
+                           pDeviceNames = alcGetString (NULL, ALC_ALL_DEVICES_SPECIFIER);
+                       OpenALEnumerate (sound_devices, pDeviceNames, ppDefaultDevice, FALSE);
+    #if 0
+                       ppDefaultDevice = alcGetString (NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
+                       pDeviceNames = alcGetString (NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
+                       OpenALEnumerate (record_devices, pDeviceNames, ppDefaultDevice, TRUE);
+    #endif
+                   }
                }
+           } __except(ExceptionFilter (GetExceptionInformation (), GetExceptionCode ())) {
+               write_log (L"OpenAL enumeration crashed!\n");
+               flush_log ();
            }
-    } __except(ExceptionFilter (GetExceptionInformation (), GetExceptionCode ())) {
-       write_log (L"OpenAL enumeration crashed!\n");
-        flush_log ();
-    }
+       }
 #if PORTAUDIO
-       __try {
-           HMODULE hm = WIN32_LoadLibrary (L"portaudio_x86.dll");
-           if (hm) {
-               TCHAR *s;
-               PaError err;
-               write_log (L"Enumerating PortAudio devices..\n");
-               s = au (Pa_GetVersionText ());
-               write_log (L"%s (%d)\n", s, Pa_GetVersion ());
-               xfree (s);
-               if (Pa_GetVersion () >= 1899) {
-                   err = Pa_Initialize ();
-                   if (err == paNoError) {
-                       PortAudioEnumerate (sound_devices);
+       if (sounddrivermask & SOUNDDRIVER_PORTAUDIO) {
+           __try {
+               HMODULE hm = WIN32_LoadLibrary (L"portaudio_x86.dll");
+               if (hm) {
+                   TCHAR *s;
+                   PaError err;
+                   write_log (L"Enumerating PortAudio devices..\n");
+                   s = au (Pa_GetVersionText ());
+                   write_log (L"%s (%d)\n", s, Pa_GetVersion ());
+                   xfree (s);
+                   if (Pa_GetVersion () >= 1899) {
+                       err = Pa_Initialize ();
+                       if (err == paNoError) {
+                           PortAudioEnumerate (sound_devices);
+                       } else {
+                           s = au (Pa_GetErrorText (err));
+                           write_log (L"Portaudio initialization failed: %d (%s)\n",
+                               err, s);
+                           xfree (s);
+                           FreeLibrary (hm);
+                       }
                    } else {
-                       s = au (Pa_GetErrorText (err));
-                       write_log (L"Portaudio initialization failed: %d (%s)\n",
-                           err, s);
-                       xfree (s);
+                       write_log (L"Too old PortAudio library\n");
+                       flush_log ();
                        FreeLibrary (hm);
                    }
-               } else {
-                   write_log (L"Too old PortAudio library\n");
-                   flush_log ();
-                   FreeLibrary (hm);
                }
+           } __except(ExceptionFilter (GetExceptionInformation (), GetExceptionCode ())) {
+               write_log (L"Portaudio enumeration crashed!\n");
            }
-       } __except(ExceptionFilter (GetExceptionInformation (), GetExceptionCode ())) {
-           write_log (L"Portaudio enumeration crashed!\n");
        }
 #endif
        write_log (L"Enumeration end\n");
index 3bbef36c5f6e3948b0042d29116562d66c06c5de..215af0d483da934becac38d6ac1acdae07ab5b97 100644 (file)
@@ -143,3 +143,9 @@ struct dsaudiomodes {
     int ch;
     DWORD ksmode;
 };
+
+extern int sounddrivermask;
+#define SOUNDDRIVER_DS 1
+#define SOUNDDRIVER_WASAPI 2
+#define SOUNDDRIVER_OPENAL 4
+#define SOUNDDRIVER_PORTAUDIO 8
index f9ea889fb51f5b4e7c591f7a81dbbfc8c1aeaab5..8aff34b805a151839e67204f9be209d5db34c807 100644 (file)
@@ -1883,7 +1883,7 @@ static int WIN32_InitLibraries (void)
     LARGE_INTEGER freq;
     SETCURRENTPROCESSEXPLICITAPPUSERMODEIDD pSetCurrentProcessExplicitAppUserModelID; 
 
-    CoInitialize (0);
+    CoInitializeEx (NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
     /* Determine our processor speed and capabilities */
     if (!init_mmtimer ()) {
        pre_gui_message (L"MMTimer initialization failed, exiting..");
@@ -2097,28 +2097,296 @@ static get_aspi (int old)
        return UAESCSI_SPTI;
 }
 
+
+/***
+*static void parse_cmdline(cmdstart, argv, args, numargs, numchars)
+*
+*Purpose:
+*       Parses the command line and sets up the argv[] array.
+*       On entry, cmdstart should point to the command line,
+*       argv should point to memory for the argv array, args
+*       points to memory to place the text of the arguments.
+*       If these are NULL, then no storing (only counting)
+*       is done.  On exit, *numargs has the number of
+*       arguments (plus one for a final NULL argument),
+*       and *numchars has the number of bytes used in the buffer
+*       pointed to by args.
+*
+*Entry:
+*       _TSCHAR *cmdstart - pointer to command line of the form
+*           <progname><nul><args><nul>
+*       _TSCHAR **argv - where to build argv array; NULL means don't
+*                       build array
+*       _TSCHAR *args - where to place argument text; NULL means don't
+*                       store text
+*
+*Exit:
+*       no return value
+*       int *numargs - returns number of argv entries created
+*       int *numchars - number of characters used in args buffer
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+#define NULCHAR    _T('\0')
+#define SPACECHAR  _T(' ')
+#define TABCHAR    _T('\t')
+#define DQUOTECHAR _T('\"')
+#define SLASHCHAR  _T('\\')
+
+
+static void __cdecl wparse_cmdline (
+    _TSCHAR *cmdstart,
+    _TSCHAR **argv,
+    _TSCHAR *args,
+    int *numargs,
+    int *numchars
+    )
+{
+        _TSCHAR *p;
+        _TUCHAR c;
+        int inquote;                    /* 1 = inside quotes */
+        int copychar;                   /* 1 = copy char to *args */
+        unsigned numslash;              /* num of backslashes seen */
+
+        *numchars = 0;
+        *numargs = 1;                   /* the program name at least */
+
+        /* first scan the program name, copy it, and count the bytes */
+        p = cmdstart;
+        if (argv)
+            *argv++ = args;
+
+#ifdef WILDCARD
+        /* To handle later wild card expansion, we prefix each entry by
+        it's first character before quote handling.  This is done
+        so _[w]cwild() knows whether to expand an entry or not. */
+        if (args)
+            *args++ = *p;
+        ++*numchars;
+
+#endif  /* WILDCARD */
+
+        /* A quoted program name is handled here. The handling is much
+           simpler than for other arguments. Basically, whatever lies
+           between the leading double-quote and next one, or a terminal null
+           character is simply accepted. Fancier handling is not required
+           because the program name must be a legal NTFS/HPFS file name.
+           Note that the double-quote characters are not copied, nor do they
+           contribute to numchars. */
+        inquote = FALSE;
+        do {
+            if (*p == DQUOTECHAR )
+            {
+                inquote = !inquote;
+                c = (_TUCHAR) *p++;
+                continue;
+            }
+            ++*numchars;
+            if (args)
+                *args++ = *p;
+
+            c = (_TUCHAR) *p++;
+#ifdef _MBCS
+            if (_ismbblead(c)) {
+                ++*numchars;
+                if (args)
+                    *args++ = *p;   /* copy 2nd byte too */
+                p++;  /* skip over trail byte */
+            }
+#endif  /* _MBCS */
+
+        } while ( (c != NULCHAR && (inquote || (c !=SPACECHAR && c != TABCHAR))) );
+
+        if ( c == NULCHAR ) {
+            p--;
+        } else {
+            if (args)
+                *(args-1) = NULCHAR;
+        }
+
+        inquote = 0;
+
+        /* loop on each argument */
+        for(;;) {
+
+            if ( *p ) {
+                while (*p == SPACECHAR || *p == TABCHAR)
+                    ++p;
+            }
+
+            if (*p == NULCHAR)
+                break;              /* end of args */
+
+            /* scan an argument */
+            if (argv)
+                *argv++ = args;     /* store ptr to arg */
+            ++*numargs;
+
+#ifdef WILDCARD
+        /* To handle later wild card expansion, we prefix each entry by
+        it's first character before quote handling.  This is done
+        so _[w]cwild() knows whether to expand an entry or not. */
+        if (args)
+            *args++ = *p;
+        ++*numchars;
+
+#endif  /* WILDCARD */
+
+        /* loop through scanning one argument */
+        for (;;) {
+            copychar = 1;
+            /* Rules: 2N backslashes + " ==> N backslashes and begin/end quote
+               2N+1 backslashes + " ==> N backslashes + literal "
+               N backslashes ==> N backslashes */
+            numslash = 0;
+            while (*p == SLASHCHAR) {
+                /* count number of backslashes for use below */
+                ++p;
+                ++numslash;
+            }
+            if (*p == DQUOTECHAR) {
+                /* if 2N backslashes before, start/end quote, otherwise
+                    copy literally */
+                if (numslash % 2 == 0) {
+                    if (inquote && p[1] == DQUOTECHAR) {
+                        p++;    /* Double quote inside quoted string */
+                    } else {    /* skip first quote char and copy second */
+                        copychar = 0;       /* don't copy quote */
+                        inquote = !inquote;
+                    }
+                }
+                numslash /= 2;          /* divide numslash by two */
+            }
+
+            /* copy slashes */
+            while (numslash--) {
+                if (args)
+                    *args++ = SLASHCHAR;
+                ++*numchars;
+            }
+
+            /* if at end of arg, break loop */
+            if (*p == NULCHAR || (!inquote && (*p == SPACECHAR || *p == TABCHAR)))
+                break;
+
+            /* copy character into argument */
+#ifdef _MBCS
+            if (copychar) {
+                if (args) {
+                    if (_ismbblead(*p)) {
+                        *args++ = *p++;
+                        ++*numchars;
+                    }
+                    *args++ = *p;
+                } else {
+                    if (_ismbblead(*p)) {
+                        ++p;
+                        ++*numchars;
+                    }
+                }
+                ++*numchars;
+            }
+            ++p;
+#else  /* _MBCS */
+            if (copychar) {
+                if (args)
+                    *args++ = *p;
+                ++*numchars;
+            }
+            ++p;
+#endif  /* _MBCS */
+            }
+
+            /* null-terminate the argument */
+
+            if (args)
+                *args++ = NULCHAR;          /* terminate string */
+            ++*numchars;
+        }
+
+        /* We put one last argument in -- a null ptr */
+        if (argv)
+            *argv++ = NULL;
+        ++*numargs;
+}
+
+#define MAX_ARGUMENTS 128
+
+static TCHAR **parseargstring (TCHAR *s)
+{
+    TCHAR **p;
+    int numa, numc;
+
+    if (_tcslen (s) == 0)
+       return NULL;
+    wparse_cmdline (s, NULL, NULL, &numa, &numc);
+    numa++;
+    p = xcalloc (numa * sizeof (TCHAR*) + numc * sizeof (TCHAR), 1);
+    wparse_cmdline (s, (wchar_t **)p, (wchar_t *)(((char *)p) + numa * sizeof(wchar_t *)), &numa, &numc);
+    if (numa > MAX_ARGUMENTS)
+       p[MAX_ARGUMENTS] = NULL;
+    return p;
+}
+
+
 static void shellexecute (TCHAR *command)
 {
-    SHELLEXECUTEINFO sei = { 0 };
-    TCHAR *f = command;
-    TCHAR *sf, *s, *p;
+    STARTUPINFO si = { 0 };
+    PROCESS_INFORMATION pi = { 0 };
 
-    sf = s = xcalloc (_tcslen (f) + 1 + 1, sizeof (TCHAR));
-    if (!s)
-       return;
-    _tcscpy (s, f);
-    for (;;) {
-       p = _tcschr (s, ';');
-       if (!p)
-           break;
-       *p = 0;
+    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 ());
     }
-    while (s[0]) {
+}
+
+#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_FLAG_NO_UI | SEE_MASK_NOCLOSEPROCESS;
-       sei.lpFile = s;
+       sei.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT | SEE_MASK_DOENVSUBST | SEE_MASK_FLAG_NO_UI;
+       sei.lpFile = cmd;
        sei.nShow = SW_HIDE;
-       write_log (L"ShellExecuteEx('%s')\n", s);
+       j = i;
+       len = 0;
+       while (args[i] && _tcscmp (args[i], L";")) {
+           len += _tcslen (args[i]) + 1;
+           i++;
+       }
+       if (i > j) {
+           s = xcalloc (len + 1, sizeof (TCHAR));
+           while (j < i) {
+               if (s[0])
+                   _tcscat (s, L" ");
+               _tcscat (s, args[j]);
+               j++;
+           }
+           sei.lpParameters = s;
+       }
+       write_log (L"ShellExecuteEx('%s','%s')\n", cmd, s ? s : L"<NULL>");
        if (ShellExecuteEx (&sei)) {
            HANDLE h = sei.hProcess;
            if (h) {
@@ -2129,10 +2397,11 @@ static void shellexecute (TCHAR *command)
        } else {
            write_log (L"Failed. ERR=%d\n", GetLastError ());
        }
-       s += _tcslen (s) + 1;
+       xfree (s);
     }
-    xfree (sf);
+    xfree (args);
 }
+#endif
 
 void target_run (void)
 {
@@ -3092,6 +3361,12 @@ static void WIN32_HandleRegistryStuff (void)
     }
 
     regqueryint (NULL, L"DirectDraw_Secondary", &ddforceram);
+    if (regexists (NULL, L"SoundDriverMask")) {
+       regqueryint (NULL, L"SoundDriverMask", &sounddrivermask);
+    } else {
+       sounddrivermask = 15;
+       regsetint (NULL, L"SoundDriverMask", sounddrivermask);
+    }
     if (regexists (NULL, L"ConfigurationCache"))
        regqueryint (NULL, L"ConfigurationCache", &configurationcache);
     else
@@ -3555,8 +3830,6 @@ static void makeverstr (TCHAR *s)
     }
 }
 
-#define MAX_ARGUMENTS 128
-
 static int parseargs (const TCHAR *arg, const TCHAR *np, const TCHAR *np2)
 {
     if (!_tcscmp (arg, L"-convert") && np && np2) {
@@ -3752,239 +4025,6 @@ static int parseargs (const TCHAR *arg, const TCHAR *np, const TCHAR *np2)
     return 0;
 }
 
-/***
-*static void parse_cmdline(cmdstart, argv, args, numargs, numchars)
-*
-*Purpose:
-*       Parses the command line and sets up the argv[] array.
-*       On entry, cmdstart should point to the command line,
-*       argv should point to memory for the argv array, args
-*       points to memory to place the text of the arguments.
-*       If these are NULL, then no storing (only counting)
-*       is done.  On exit, *numargs has the number of
-*       arguments (plus one for a final NULL argument),
-*       and *numchars has the number of bytes used in the buffer
-*       pointed to by args.
-*
-*Entry:
-*       _TSCHAR *cmdstart - pointer to command line of the form
-*           <progname><nul><args><nul>
-*       _TSCHAR **argv - where to build argv array; NULL means don't
-*                       build array
-*       _TSCHAR *args - where to place argument text; NULL means don't
-*                       store text
-*
-*Exit:
-*       no return value
-*       int *numargs - returns number of argv entries created
-*       int *numchars - number of characters used in args buffer
-*
-*Exceptions:
-*
-*******************************************************************************/
-
-#define NULCHAR    _T('\0')
-#define SPACECHAR  _T(' ')
-#define TABCHAR    _T('\t')
-#define DQUOTECHAR _T('\"')
-#define SLASHCHAR  _T('\\')
-
-
-static void __cdecl wparse_cmdline (
-    _TSCHAR *cmdstart,
-    _TSCHAR **argv,
-    _TSCHAR *args,
-    int *numargs,
-    int *numchars
-    )
-{
-        _TSCHAR *p;
-        _TUCHAR c;
-        int inquote;                    /* 1 = inside quotes */
-        int copychar;                   /* 1 = copy char to *args */
-        unsigned numslash;              /* num of backslashes seen */
-
-        *numchars = 0;
-        *numargs = 1;                   /* the program name at least */
-
-        /* first scan the program name, copy it, and count the bytes */
-        p = cmdstart;
-        if (argv)
-            *argv++ = args;
-
-#ifdef WILDCARD
-        /* To handle later wild card expansion, we prefix each entry by
-        it's first character before quote handling.  This is done
-        so _[w]cwild() knows whether to expand an entry or not. */
-        if (args)
-            *args++ = *p;
-        ++*numchars;
-
-#endif  /* WILDCARD */
-
-        /* A quoted program name is handled here. The handling is much
-           simpler than for other arguments. Basically, whatever lies
-           between the leading double-quote and next one, or a terminal null
-           character is simply accepted. Fancier handling is not required
-           because the program name must be a legal NTFS/HPFS file name.
-           Note that the double-quote characters are not copied, nor do they
-           contribute to numchars. */
-        inquote = FALSE;
-        do {
-            if (*p == DQUOTECHAR )
-            {
-                inquote = !inquote;
-                c = (_TUCHAR) *p++;
-                continue;
-            }
-            ++*numchars;
-            if (args)
-                *args++ = *p;
-
-            c = (_TUCHAR) *p++;
-#ifdef _MBCS
-            if (_ismbblead(c)) {
-                ++*numchars;
-                if (args)
-                    *args++ = *p;   /* copy 2nd byte too */
-                p++;  /* skip over trail byte */
-            }
-#endif  /* _MBCS */
-
-        } while ( (c != NULCHAR && (inquote || (c !=SPACECHAR && c != TABCHAR))) );
-
-        if ( c == NULCHAR ) {
-            p--;
-        } else {
-            if (args)
-                *(args-1) = NULCHAR;
-        }
-
-        inquote = 0;
-
-        /* loop on each argument */
-        for(;;) {
-
-            if ( *p ) {
-                while (*p == SPACECHAR || *p == TABCHAR)
-                    ++p;
-            }
-
-            if (*p == NULCHAR)
-                break;              /* end of args */
-
-            /* scan an argument */
-            if (argv)
-                *argv++ = args;     /* store ptr to arg */
-            ++*numargs;
-
-#ifdef WILDCARD
-        /* To handle later wild card expansion, we prefix each entry by
-        it's first character before quote handling.  This is done
-        so _[w]cwild() knows whether to expand an entry or not. */
-        if (args)
-            *args++ = *p;
-        ++*numchars;
-
-#endif  /* WILDCARD */
-
-        /* loop through scanning one argument */
-        for (;;) {
-            copychar = 1;
-            /* Rules: 2N backslashes + " ==> N backslashes and begin/end quote
-               2N+1 backslashes + " ==> N backslashes + literal "
-               N backslashes ==> N backslashes */
-            numslash = 0;
-            while (*p == SLASHCHAR) {
-                /* count number of backslashes for use below */
-                ++p;
-                ++numslash;
-            }
-            if (*p == DQUOTECHAR) {
-                /* if 2N backslashes before, start/end quote, otherwise
-                    copy literally */
-                if (numslash % 2 == 0) {
-                    if (inquote && p[1] == DQUOTECHAR) {
-                        p++;    /* Double quote inside quoted string */
-                    } else {    /* skip first quote char and copy second */
-                        copychar = 0;       /* don't copy quote */
-                        inquote = !inquote;
-                    }
-                }
-                numslash /= 2;          /* divide numslash by two */
-            }
-
-            /* copy slashes */
-            while (numslash--) {
-                if (args)
-                    *args++ = SLASHCHAR;
-                ++*numchars;
-            }
-
-            /* if at end of arg, break loop */
-            if (*p == NULCHAR || (!inquote && (*p == SPACECHAR || *p == TABCHAR)))
-                break;
-
-            /* copy character into argument */
-#ifdef _MBCS
-            if (copychar) {
-                if (args) {
-                    if (_ismbblead(*p)) {
-                        *args++ = *p++;
-                        ++*numchars;
-                    }
-                    *args++ = *p;
-                } else {
-                    if (_ismbblead(*p)) {
-                        ++p;
-                        ++*numchars;
-                    }
-                }
-                ++*numchars;
-            }
-            ++p;
-#else  /* _MBCS */
-            if (copychar) {
-                if (args)
-                    *args++ = *p;
-                ++*numchars;
-            }
-            ++p;
-#endif  /* _MBCS */
-            }
-
-            /* null-terminate the argument */
-
-            if (args)
-                *args++ = NULCHAR;          /* terminate string */
-            ++*numchars;
-        }
-
-        /* We put one last argument in -- a null ptr */
-        if (argv)
-            *argv++ = NULL;
-        ++*numargs;
-}
-
-
-
-
-static TCHAR **parseargstring (TCHAR *s)
-{
-    TCHAR **p;
-    int numa, numc;
-
-    if (_tcslen (s) == 0)
-       return NULL;
-    wparse_cmdline (s, NULL, NULL, &numa, &numc);
-    numa++;
-    p = xcalloc (numa * sizeof (TCHAR*) + numc * sizeof (TCHAR), 1);
-    wparse_cmdline (s, (wchar_t **)p, (wchar_t *)(((char *)p) + numa * sizeof(wchar_t *)), &numa, &numc);
-    if (numa > MAX_ARGUMENTS)
-       p[MAX_ARGUMENTS] = NULL;
-    return p;
-}
-
 static TCHAR **parseargstrings (TCHAR *s, TCHAR **xargv)
 {
     int cnt, i, xargc;
@@ -4164,6 +4204,7 @@ static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR
        DEVMODE devmode;
        DWORD i;
 
+       WIN32_HandleRegistryStuff ();
        DirectDraw_Release ();
        write_log (L"Enumerating display devices.. \n");
        enumeratedisplays (multi_display);
@@ -4190,7 +4231,6 @@ static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR
            else
                default_freq = 60;
        }
-       WIN32_HandleRegistryStuff ();
        WIN32_InitLang ();
        WIN32_InitHtmlHelp ();
        DirectDraw_Release ();
index f6a54f1a4c71879d1e6382cb976bc1aca6c69b70..ad08b766736593797f1ad87d6d94f69c163d0a77 100644 (file)
@@ -17,8 +17,8 @@
 
 #define WINUAEPUBLICBETA 1
 
-#define WINUAEBETA L"Beta 2"
-#define WINUAEDATE MAKEBD(2009, 7, 25)
+#define WINUAEBETA L"Beta 3"
+#define WINUAEDATE MAKEBD(2009, 7, 30)
 #define WINUAEEXTRA L""
 #define WINUAEREV L""
 
index e9b0f81cf43e9a330d786ee06fe7f98f57b34df6..bf1c2732ccc136f614c279e716def89d39bf7874 100644 (file)
@@ -7073,6 +7073,7 @@ static void update_soundgui (HWND hDlg)
 }
 
 static int soundfreqs[] = { 11025, 15000, 22050, 32000, 44100, 48000, 0 };
+static int sounddrivers[] = { IDC_SOUND_DS, IDC_SOUND_WASAPI, IDC_SOUND_OPENAL, IDC_SOUND_PORTAUDIO, 0 };
 
 static void values_to_sounddlg (HWND hDlg)
 {
@@ -7249,7 +7250,7 @@ static void values_from_sounddlg (HWND hDlg)
 {
     TCHAR txt[10];
     LRESULT idx;
-    int soundcard;
+    int soundcard, i;
 
     idx = SendDlgItemMessage (hDlg, IDC_SOUNDFREQ, CB_GETCURSEL, 0, 0);
     if (idx >= 0) {
@@ -7320,6 +7321,15 @@ static void values_from_sounddlg (HWND hDlg)
     workprefs.sound_stereo_swap_paula = (SendDlgItemMessage (hDlg, IDC_SOUNDSWAP, CB_GETCURSEL, 0, 0) & 1) ? 1 : 0;
     workprefs.sound_stereo_swap_ahi = (SendDlgItemMessage (hDlg, IDC_SOUNDSWAP, CB_GETCURSEL, 0, 0) & 2) ? 1 : 0;
 
+    for (i = 0; sounddrivers[i]; i++) {
+       int old = sounddrivermask;
+       sounddrivermask &= ~(1 << i);
+       if (IsDlgButtonChecked (hDlg, sounddrivers[i]))
+           sounddrivermask |= 1 << i;
+       if (old != sounddrivermask)
+           regsetint (NULL, L"SoundDriverMask", sounddrivermask);
+    }
+
     idx = SendDlgItemMessage (hDlg, IDC_SOUNDDRIVE, CB_GETCURSEL, 0, 0);
     if (idx != CB_ERR && idx >= 0) {
        LRESULT res = SendDlgItemMessage (hDlg, IDC_SOUNDDRIVESELECT, CB_GETCURSEL, 0, 0);
@@ -7340,13 +7350,11 @@ static void values_from_sounddlg (HWND hDlg)
     }
 }
 
-extern int sound_calibrate (HWND, struct uae_prefs*);
-
 static INT_PTR CALLBACK SoundDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 {
     static int recursive = 0;
     int numdevs;
-    int card;
+    int card, i;
 
     switch (msg) {
     case WM_INITDIALOG:
@@ -7365,6 +7373,10 @@ static INT_PTR CALLBACK SoundDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM
        SendDlgItemMessage (hDlg, IDC_SOUNDADJUST, TBM_SETRANGE, TRUE, MAKELONG (-100, +30));
        SendDlgItemMessage (hDlg, IDC_SOUNDADJUST, TBM_SETPAGESIZE, 0, 1);
 
+       for (i = 0; i < sounddrivers[i]; i++) {
+           CheckDlgButton (hDlg, sounddrivers[i], (sounddrivermask & (1 << i)) ? TRUE : FALSE);
+       }
+
        SendDlgItemMessage (hDlg, IDC_SOUNDCARDLIST, CB_RESETCONTENT, 0, 0L);
        numdevs = enumerate_sound_devices ();
        for (card = 0; card < numdevs; card++) {
index ecf687dc663d4050dfee2412636587087e3ed24c..b8333832a0ef42b275db9527775dc8e6415f8066 100644 (file)
@@ -1,4 +1,26 @@
 
+Beta 3:
+
+Two main compatibility testing demos work perfectly now:
+Final Bobs/Complex and Hulkamania/TSP. (Rampage/TEK still won't work..)
+
+Both require very exact CPU/DMA timing to work. First has "scrambling"
+that uses vertical beam position as a key, main demo has already worked
+if "scrambling" was bypassed, and second writes to BPLxPTs with CPU when
+display DMA is already fetching data.. Yes, sane coders use copper..)
+
+- lots more cycle-exact CPU cycle count updates
+- some more blitter updates (correct startup and copper wake-up delays)
+- non-DMA mode sprites were always reset during vblank (I remember that
+  this was working long long time ago, possibly broke during Superfrog
+  "intro bee" fix or something) Fixes B2 world rotozoomer graphic glitch
+
+- added sound driver use/do not use GUI to sound panel (stored to
+  registry/.ini) Faster startup.
+- exec* command lines should work better. Check the log if problems
+- 0x76/0x30 partition types are always available read/write
+- bsdsocket fix, cvs (SR)
+
 Beta 2:
 
 Background information:
@@ -28,7 +50,7 @@ is known but I am not sure how to implement the fix)
   blitter finished. (not necessarily exactly same thing)
 
 - chipset bitplane/copper/blitter cycle exact mode DMA sequence
-  routines rewritten. Emulation may be much due to missing
+  routines rewritten. Emulation may be slower due to missing
   optimizations. Later.
 - blitter cycle diagrams rechecked with logic analyzer, errors fixed