]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
2310b1
authorToni Wilen <twilen@winuae.net>
Sat, 23 Oct 2010 11:29:45 +0000 (14:29 +0300)
committerToni Wilen <twilen@winuae.net>
Sat, 23 Oct 2010 11:29:45 +0000 (14:29 +0300)
78 files changed:
a2065.cpp
akiko.cpp
ar.cpp
audio.cpp
blitter.cpp
blkdev.cpp
cdtv.cpp
cfgfile.cpp
cia.cpp
cpummu.cpp
custom.cpp
debug.cpp
disk.cpp
drawing.cpp
ersatz.cpp
expansion.cpp
filesys.cpp
filesys_bootrom.cpp
fpp.cpp
gayle.cpp
gencpu.cpp
include/blkdev.h
include/cia.h
include/cpu_prefetch.h
include/custom.h
include/disk.h
include/drawing.h
include/events.h
include/events_jit.h
include/fsdb.h
include/gfxfilter.h
include/inputdevice.h
include/inputrecord.h [new file with mode: 0644]
include/keyboard.h
include/newcpu.h
include/options.h
include/savestate.h
include/statusline.h
include/uae.h
include/xwin.h
include/zarchive.h
include/zfile.h
inputdevice.cpp
inputevents.def
inputrecord.cpp [new file with mode: 0644]
keybuf.cpp
main.cpp
memory.cpp
newcpu.cpp
od-win32/blkdev_win32_aspi.cpp
od-win32/blkdev_win32_ioctl.cpp
od-win32/blkdev_win32_spti.cpp
od-win32/caps/CapsAPI.h
od-win32/caps/caps_win32.cpp
od-win32/debug_win32.cpp
od-win32/dinput.cpp
od-win32/keyboard_win32.cpp
od-win32/registry.cpp
od-win32/resources/resource
od-win32/resources/winuae.rc
od-win32/rp.cpp
od-win32/sysconfig.h
od-win32/win32.cpp
od-win32/win32.h
od-win32/win32_scaler.cpp
od-win32/win32_uaenet.cpp
od-win32/win32gfx.cpp
od-win32/win32gui.cpp
od-win32/winuae_msvc10/winuae_msvc.vcxproj
od-win32/winuae_msvc10/winuae_msvc.vcxproj.filters
od-win32/winuaechangelog.txt
od-win32/writelog.cpp
savestate.cpp
statusline.cpp [new file with mode: 0644]
traps.cpp
uaeunp.cpp
zfile.cpp
zfile_archive.cpp

index c445f8e812a610ba3c7a7212b80490c8f172a77f..bc32c8ac60ae777cf9bac760893fb0b09ef82d4d 100644 (file)
--- a/a2065.cpp
+++ b/a2065.cpp
 #include "a2065.h"
 #include "win32_uaenet.h"
 #include "crc32.h"
+#include "savestate.h"
+#include "autoconf.h"
 
-static int a2065_log = 0;
+int log_a2065 = 0;
+static int log_transmit = 1;
+static int log_receive = 1;
+int a2065_promiscuous = 0;
 
 #define RAP 0x4002
 #define RDP 0x4000
@@ -30,7 +35,7 @@ static int a2065_log = 0;
 
 static uae_u8 config[256];
 static uae_u8 boardram[RAM_SIZE];
-static uae_u16 csr[4];
+static volatile uae_u16 csr[4];
 static int rap;
 static int configured;
 
@@ -38,13 +43,13 @@ static struct netdriverdata *td;
 static void *sysdata;
 
 static int am_initialized;
-static int transmitnow;
+static volatile int transmitnow;
 static uae_u16 am_mode;
 static uae_u64 am_ladrf;
 static uae_u32 am_rdr, am_rdr_rlen, am_rdr_rdra;
 static uae_u32 am_tdr, am_tdr_tlen, am_tdr_tdra;
 static int tdr_offset, rdr_offset;
-static int byteswap, prom;
+static int byteswap, prom, fakeprom;
 static uae_u8 fakemac[6], realmac[6];
 static uae_u8 broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
@@ -142,7 +147,7 @@ static void dumppacket (TCHAR *n, uae_u8 *packet, int len)
 
 #define MAX_PACKET_SIZE 4000
 static uae_u8 transmitbuffer[MAX_PACKET_SIZE];
-static int transmitlen;
+static volatile int transmitlen;
 
 static int dofakemac (uae_u8 *packet)
 {
@@ -225,23 +230,6 @@ static int mungepacket (uae_u8 *packet, int len)
        return ret;
 }
 
-static int getfunc (struct s2devstruct *dev, uae_u8 *d, int *len)
-{
-       int tlen;
-
-       tlen = transmitlen;
-       transmitlen = 0;
-       if (tlen > 0) {
-               if (tlen > *len)
-                       return 0;
-               memcpy (d, transmitbuffer, tlen);
-               *len = tlen;
-               transmitnow = 1;
-               return 1;
-       }
-       return 0;
-}
-
 static int mcfilter (const uae_u8 *data)
 {
        if (am_ladrf == 0) // multicast filter completely disabled?
@@ -249,7 +237,7 @@ static int mcfilter (const uae_u8 *data)
        return 1; // just allow everything
 }
 
-static void gotfunc (struct s2devstruct *dev, const uae_u8 *data2, int len)
+static void gotfunc (struct s2devstruct *dev, const uae_u8 *databuf, int len)
 {
        int i;
        int size, insize, first;
@@ -258,44 +246,89 @@ static void gotfunc (struct s2devstruct *dev, const uae_u8 *data2, int len)
        uae_u16 rmd0, rmd1, rmd2, rmd3;
        uae_u32 crc32;
        uae_u8 tmp[MAX_PACKET_SIZE], *data;
+       const uae_u8 *dstmac, *srcmac;
+
+       if (log_a2065 > 1 && log_receive) {
+               dstmac = databuf;
+               srcmac = databuf + 6;
+               write_log (L"A2065<!DST:%02X.%02X.%02X.%02X.%02X.%02X SRC:%02X.%02X.%02X.%02X.%02X.%02X E=%04X S=%d\n",
+                       dstmac[0], dstmac[1], dstmac[2], dstmac[3], dstmac[4], dstmac[5],
+                       srcmac[6], srcmac[7], srcmac[8], srcmac[9], srcmac[10], srcmac[11],
+                       (databuf[12] << 8) | databuf[13], len);
+       }
 
        if (!(csr[0] & CSR0_RXON)) // receiver off?
                return;
-       if (len < 60) // too short
+       if (len < 60) { // too short
+               if (log_a2065)
+                       write_log (L"A2065: short frame, %d bytes\n", len);
                return;
+       }
 
-       if (data2[0] & 0x80) {
+       dstmac = databuf;
+       srcmac = databuf + 6;
+
+       if ((dstmac[0] & 0x01) && memcmp (dstmac, broadcast, sizeof broadcast) != 0) {
                // multicast
-               if (!mcfilter (data2))
+               if (!mcfilter (dstmac)) {
+                       if (log_a2065 > 1)
+                               write_log (L"mc filtered\n");
                        return;
+               }
        } else {
                // !promiscuous and dst != me and dst != broadcast
-               if (!prom && (memcmp (data2, realmac, sizeof realmac) != 0 && memcmp (data2, broadcast, sizeof broadcast) != 0))
+               if (!prom && (memcmp (dstmac, realmac, sizeof realmac) != 0 && memcmp (dstmac, broadcast, sizeof broadcast) != 0)) {
+                       if (log_a2065 > 1)
+                               write_log (L"not for me1\n");
                        return;
+               }
        }
 
        // src and dst = me? right, better drop it.
-       if (memcmp (data2, realmac, sizeof realmac) == 0 && memcmp (data2 + 6, realmac, sizeof realmac) == 0)
+       if (memcmp (dstmac, realmac, sizeof realmac) == 0 && memcmp (srcmac, realmac, sizeof realmac) == 0) {
+               if (log_a2065 > 1)
+                       write_log (L"not for me2\n");
                return;
+       }
        // dst = broadcast and src = me? no thanks.
-       if (memcmp (data2, broadcast, sizeof broadcast) == 0 && memcmp (data2 + 6, realmac, sizeof realmac) == 0)
+       if (memcmp (dstmac, broadcast, sizeof broadcast) == 0 && memcmp (srcmac, realmac, sizeof realmac) == 0) {
+               if (log_a2065 > 1)
+                       write_log (L"not for me3\n");
                return;
+       }
 
-       memcpy (tmp, data2, len);
+       memcpy (tmp, databuf, len);
+#if 0
+       FILE *f = fopen("s:\\d\\wireshark2.cap", "rb");
+       fseek (f, 474, SEEK_SET);
+       fread (tmp, 342, 1, f);
+       fclose (f);
+       realmac[0] = 0xc8;
+       realmac[1] = 0x0a;
+       realmac[2] = 0xa9;
+       realmac[3] = 0x81;
+       realmac[4] = 0xff;
+       realmac[5] = 0x2f;
+       fakemac[3] = realmac[3];
+       fakemac[4] = realmac[4];
+       fakemac[5] = realmac[5];
+#endif
        d = tmp;
-       if (a2065_log) {
-               if (memcmp (d, realmac, sizeof realmac) == 0) {
+       dstmac = d;
+       srcmac = d + 6;
+       if (log_a2065 && log_receive) {
+               if (memcmp (dstmac, realmac, sizeof realmac) == 0) {
                        write_log (L"A2065<-DST:%02X.%02X.%02X.%02X.%02X.%02X SRC:%02X.%02X.%02X.%02X.%02X.%02X E=%04X S=%d\n",
-                               d[0], d[1], d[2], d[3], d[4], d[5],
-                               d[6], d[7], d[8], d[9], d[10], d[11],
+                               dstmac[0], dstmac[1], dstmac[2], dstmac[3], dstmac[4], dstmac[5],
+                               srcmac[6], srcmac[7], srcmac[8], srcmac[9], srcmac[10], srcmac[11],
                                (d[12] << 8) | d[13], len);
                }
        }
        if (mungepacket (d, len)) {
-               if (a2065_log) {
+               if (log_a2065 && log_receive) {
                        write_log (L"A2065<*DST:%02X.%02X.%02X.%02X.%02X.%02X SRC:%02X.%02X.%02X.%02X.%02X.%02X E=%04X S=%d\n",
-                               d[0], d[1], d[2], d[3], d[4], d[5],
-                               d[6], d[7], d[8], d[9], d[10], d[11],
+                               dstmac[0], dstmac[1], dstmac[2], dstmac[3], dstmac[4], dstmac[5],
+                               srcmac[6], srcmac[7], srcmac[8], srcmac[9], srcmac[10], srcmac[11],
                                (d[12] << 8) | d[13], len);
                }
        }
@@ -323,6 +356,7 @@ static void gotfunc (struct s2devstruct *dev, const uae_u8 *data2, int len)
                addr &= RAM_MASK;
 
                if (!(rmd1 & RX_OWN)) {
+                       write_log (L"A2065: RECEIVE BUFFER ERROR\n");
                        if (!first) {
                                rmd1 |= RX_BUFF | RX_OFLO;
                                csr[0] &= ~CSR0_RXON;
@@ -331,6 +365,7 @@ static void gotfunc (struct s2devstruct *dev, const uae_u8 *data2, int len)
                        }
                        p[3] = rmd1 >> 8;
                        p[2] = rmd1 >> 0;
+                       rethink_a2065 ();
                        return;
                }
 
@@ -363,6 +398,22 @@ static void gotfunc (struct s2devstruct *dev, const uae_u8 *data2, int len)
        rethink_a2065 ();
 }
 
+static int getfunc (struct s2devstruct *dev, uae_u8 *d, int *len)
+{
+       if (transmitlen <= 0)
+               return 0;
+       if (transmitlen > *len) {
+               write_log (L"A2065: too large packet transmission attempt %d > %d\n", transmitlen, *len);
+               transmitlen = 0;
+               return 0;
+       }
+       memcpy (d, transmitbuffer, transmitlen);
+       *len = transmitlen;
+       transmitlen = 0;
+       transmitnow = 1;
+       return 1;
+}
+
 static void do_transmit (void)
 {
        int i;
@@ -379,8 +430,13 @@ static void do_transmit (void)
        tdr_offset %= am_tdr_tlen;
        p = boardram + ((am_tdr_tdra + tdr_offset * 8) & RAM_MASK);
        tmd1 = (p[3] << 8) | (p[2] << 0);
-       if (!(tmd1 & TX_OWN) || !(tmd1 & TX_STP))
+       if (!(tmd1 & TX_OWN) || !(tmd1 & TX_STP)) {
+               tdr_offset++;
                return;
+       }
+       if (!(tmd1 & TX_ENP) && log_a2065 > 0)
+               write_log (L"A2065: chained transmit!?\n");
+
        add_fcs = tmd1 & TX_ADD_FCS;
 
        for (;;) {
@@ -395,8 +451,9 @@ static void do_transmit (void)
 
                if (!(tmd1 & TX_OWN)) {
                        tmd3 |= TX_BUFF | TX_UFLO;
+                       tmd1 |= TX_ERR;
                        csr[0] &= ~CSR0_TXON;
-                       write_log (L"A2065: TRANSMIT BUFFER ERROR\n");
+                       write_log (L"A2065: TRANSMIT OWN NOT SET\n");
                        err = 1;
                } else {
                        tmd1 &= ~TX_OWN;
@@ -416,16 +473,21 @@ static void do_transmit (void)
        }
        if (outsize < 60) {
                tmd3 |= TX_BUFF | TX_UFLO;
+               tmd1 |= TX_ERR;
                csr[0] &= ~CSR0_TXON;
-               write_log (L"A2065: TRANSMIT SIZE %d\n", outsize);
+               write_log (L"A2065: TRANSMIT UNDERFLOW %d\n", outsize);
                err = 1;
+               p[3] = tmd1 >> 8;
+               p[2] = tmd1 >> 0;
+               p[7] = tmd3 >> 8;
+               p[6] = tmd3 >> 0;
        }
 
        if (!err) {
                uae_u8 *d = transmitbuffer;
                if ((am_mode & MODE_DTCR) && !add_fcs)
                        outsize -= 4; // do not include checksum bytes
-               if (a2065_log) {
+               if (log_a2065 && log_transmit) {
                        write_log (L"A2065->DST:%02X.%02X.%02X.%02X.%02X.%02X SRC:%02X.%02X.%02X.%02X.%02X.%02X E=%04X S=%d\n",
                                d[0], d[1], d[2], d[3], d[4], d[5],
                                d[6], d[7], d[8], d[9], d[10], d[11],
@@ -433,7 +495,7 @@ static void do_transmit (void)
                }
                transmitlen = outsize;
                if (mungepacket (d, transmitlen)) {
-                       if (a2065_log) {
+                       if (log_a2065 && log_transmit) {
                                write_log (L"A2065*>DST:%02X.%02X.%02X.%02X.%02X.%02X SRC:%02X.%02X.%02X.%02X.%02X.%02X E=%04X S=%d\n",
                                        d[0], d[1], d[2], d[3], d[4], d[5],
                                        d[6], d[7], d[8], d[9], d[10], d[11],
@@ -441,9 +503,19 @@ static void do_transmit (void)
                        }
                }
                uaenet_trigger (sysdata);
-               csr[0] |= CSR0_TINT;
-               rethink_a2065 ();
        }
+       csr[0] |= CSR0_TINT;
+       rethink_a2065 ();
+}
+
+static void check_transmit (void)
+{
+       if (transmitlen > 0)
+               return;
+       if (!(csr[0] & CSR0_TXON))
+               return;
+       transmitnow = 0;
+       do_transmit ();
 }
 
 void a2065_hsync_handler (void)
@@ -452,31 +524,21 @@ void a2065_hsync_handler (void)
 
        cnt--;
        if (cnt < 0 || transmitnow) {
-               transmitnow = 0;
-               if ((csr[0] & CSR0_TXON) && transmitlen <= 0)
-                       do_transmit ();
+               check_transmit ();
                cnt = 15;
        }
 }
 
 void rethink_a2065 (void)
 {
-       uae_u16 csr0 = csr[0];
-
+       uae_int_requested &= ~4;
        if (!configured)
                return;
-       if (csr0 & (CSR0_BABL | CSR0_MISS | CSR0_MERR | CSR0_RINT | CSR0_TINT | CSR0_IDON)) {
-               if (!(csr0 & CSR0_INTR)) {
-                       csr0 |= CSR0_INTR;
-                       if (csr0 & CSR0_INEA) {
-                               INTREQ_0 (0x8000 | 0x0008);
-                       }
-               }
-       } else {
-               csr0 &= ~CSR0_INTR;
-       }
-
-       csr[0] = csr0;
+       csr[0] &= ~CSR0_INTR;
+       if (csr[0] & (CSR0_BABL | CSR0_MISS | CSR0_MERR | CSR0_RINT | CSR0_TINT | CSR0_IDON))
+               csr[0] |= CSR0_INTR;
+       if ((csr[0] & (CSR0_INTR | CSR0_INEA)) == (CSR0_INTR | CSR0_INEA))
+               uae_int_requested |= 4;
 }
 
 static void chip_init (void)
@@ -484,6 +546,11 @@ static void chip_init (void)
        uae_u32 iaddr = ((csr[2] & 0xff) << 16) | csr[1];
        uae_u8 *p = boardram + (iaddr & RAM_MASK);
 
+       write_log (L"A2065: Initialization block2:\n");
+       for (int i = 0; i < 24; i++)
+               write_log (L".%02X", p[i]);
+       write_log (L"\n");
+
        am_mode = (p[0] << 8) | (p[1] << 0);
        am_ladrf = ((uae_u64)p[15] << 56) | ((uae_u64)p[14] << 48) | ((uae_u64)p[13] << 40) | ((uae_u64)p[12] << 32) | (p[11] << 24) | (p[10] << 16) | (p[9] << 8) | (p[8] << 0);
        am_rdr = (p[19] << 24) | (p[18] << 16) | (p[17] << 8) | (p[16] << 0);
@@ -495,7 +562,8 @@ static void chip_init (void)
        am_tdr_tdra = am_tdr & 0x00fffff8;
 
        prom = (am_mode & MODE_PROM) ? 1 : 0;
-
+       fakeprom = a2065_promiscuous ? 1 : 0;
+       
        fakemac[0] = p[2];
        fakemac[1] = p[3];
        fakemac[2] = p[4];
@@ -503,8 +571,8 @@ static void chip_init (void)
        fakemac[4] = p[6];
        fakemac[5] = p[7];
 
-       write_log (L"A2065: %06X %d %d %d %06X %06X %02X:%02X:%02X:%02X:%02X:%02X\n",
-               iaddr, prom, am_rdr_rlen, am_tdr_tlen, am_rdr_rdra, am_tdr_tdra,
+       write_log (L"A2065: %04X %06X %d %d %d %d %06X %06X %02X:%02X:%02X:%02X:%02X:%02X\n",
+               am_mode, iaddr, prom, fakeprom, am_rdr_rlen, am_tdr_tlen, am_rdr_rdra, am_tdr_tdra,
                fakemac[0], fakemac[1], fakemac[2], fakemac[3], fakemac[4], fakemac[5]);
 
 
@@ -516,7 +584,7 @@ static void chip_init (void)
        if (td != NULL) {
                if (!sysdata)
                        sysdata = xcalloc (uae_u8, uaenet_getdatalenght());
-               if (!uaenet_open (sysdata, td, NULL, gotfunc, getfunc, prom)) {
+               if (!uaenet_open (sysdata, td, NULL, gotfunc, getfunc, prom || fakeprom)) {
                        write_log (L"A2065: failed to initialize winpcap driver\n");
                }
        }
@@ -532,7 +600,7 @@ static uae_u16 chip_wget (uaecptr addr)
                        if (v & (CSR0_BABL | CSR0_CERR | CSR0_MISS | CSR0_MERR))
                                v |= CSR0_ERR;
                }
-               if (a2065_log > 2)
+               if (log_a2065 > 2)
                        write_log (L"A2065_CHIPWGET: CSR%d=%04X PC=%08X\n", rap, v, M68K_GETPC);
                return v;
        }
@@ -548,85 +616,84 @@ static void chip_wput (uaecptr addr, uae_u16 v)
 
        } else if (addr == RDP) {
 
-               uae_u16 reg = csr[rap];
-               uae_u16 oreg = reg;
+               uae_u16 oreg = csr[rap];
                uae_u16 t;
 
-               if (a2065_log > 2)
+               if (log_a2065 > 2)
                        write_log (L"A2065_CHIPWPUT: CSR%d=%04X PC=%08X\n", rap, v & 0xffff, M68K_GETPC);
 
                switch (rap)
                {
                case 0:
-                       reg &= ~CSR0_INEA; reg |= v & CSR0_INEA;
+                       csr[0] &= ~CSR0_INEA; csr[0] |= v & CSR0_INEA;
                        // bit = 1 -> set, bit = 0 -> nop
                        t = v & (CSR0_INIT | CSR0_STRT | CSR0_STOP | CSR0_TDMD);
-                       reg |= t;
+                       csr[0] |= t;
                        // bit = 1 -> clear, bit = 0 -> nop
                        t = v & (CSR0_IDON | CSR0_TINT | CSR0_RINT | CSR0_MERR | CSR0_MISS | CSR0_CERR | CSR0_BABL);
-                       reg &= ~t;
-                       reg &= ~CSR0_ERR;
+                       csr[0] &= ~t;
+                       csr[0] &= ~CSR0_ERR;
 
-                       if ((reg & (CSR0_STOP | CSR0_STRT | CSR0_INIT)) == (CSR0_STOP | CSR0_STRT | CSR0_INIT))
-                               reg &= ~(CSR0_STRT | CSR0_INIT);
-                       if (reg & CSR0_INIT)
-                               reg &= ~CSR0_STOP;
+                       if ((csr[0] & (CSR0_STOP | CSR0_STRT | CSR0_INIT)) == (CSR0_STOP | CSR0_STRT | CSR0_INIT))
+                               csr[0] &= ~(CSR0_STRT | CSR0_INIT);
+                       if (csr[0] & CSR0_INIT)
+                               csr[0] &= ~CSR0_STOP;
 
-                       if ((reg & CSR0_STRT) && !(oreg & CSR0_STRT)) {
-                               reg &= ~CSR0_STOP;
+                       if ((csr[0] & CSR0_STRT) && !(oreg & CSR0_STRT)) {
+                               csr[0] &= ~CSR0_STOP;
                                if (!(am_mode & MODE_DTX))
-                                       reg |= CSR0_TXON;
+                                       csr[0] |= CSR0_TXON;
                                if (!(am_mode & MODE_DRX))
-                                       reg |= CSR0_RXON;
-                               if (a2065_log)
-                                       write_log (L"A2065: START\n");
+                                       csr[0] |= CSR0_RXON;
+                               if (log_a2065)
+                                       write_log (L"A2065: START.\n");
                        }
 
-                       if ((reg & CSR0_STOP) && !(oreg & CSR0_STOP)) {
-                               reg = CSR0_STOP;
-                               if (a2065_log)
-                                       write_log (L"A2065: STOP\n");
+                       if ((csr[0] & CSR0_STOP) && !(oreg & CSR0_STOP)) {
+                               csr[0] = CSR0_STOP;
+                               if (log_a2065)
+                                       write_log (L"A2065: STOP.\n");
                                csr[3] = 0;
                                am_initialized = 0;
                        }
 
-                       if ((reg & CSR0_INIT) && am_initialized == 0) {
-                               if (a2065_log)
-                                       write_log (L"A2065: INIT\n");
+                       if ((csr[0] & CSR0_INIT) && am_initialized == 0) {
+                               if (log_a2065)
+                                       write_log (L"A2065: INIT.\n");
                                chip_init ();
-                               reg |= CSR0_IDON;
+                               csr[0] |= CSR0_IDON;
                                am_initialized = 1;
                        }
 
-                       if ((reg & CSR0_STRT) && am_initialized) {
-                               if (reg & CSR0_TDMD)
-                                       transmitnow = 1;
+                       if ((csr[0] & CSR0_STRT) && am_initialized) {
+                               if (csr[0] & CSR0_TDMD)
+                                       check_transmit ();
                        }
-                       reg &= ~CSR0_TDMD;
+                       csr[0] &= ~CSR0_TDMD;
 
+                       rethink_a2065 ();
                        break;
                case 1:
                        if (csr[0] & 4) {
-                               reg = v;
-                               reg &= ~1;
+                               csr[1] = v;
+                               csr[1] &= ~1;
                        }
                        break;
                case 2:
                        if (csr[0] & 4) {
-                               reg = v;
-                               reg &= 0x00ff;
+                               csr[2] = v;
+                               csr[2] &= 0x00ff;
                        }
                        break;
                case 3:
                        if (csr[0] & 4) {
-                               reg = v;
-                               reg &= 7;
+                               csr[3] = v;
+                               csr[3] &= 7;
                        }
-                       byteswap = (reg & CSR3_BSWP) ? 1 : 0;
+                       byteswap = (csr[3] & CSR3_BSWP) ? 1 : 0;
                        break;
 
                }
-               csr[rap] = reg;
        }
 }
 
@@ -640,7 +707,7 @@ static uae_u32 a2065_bget2 (uaecptr addr)
        } else if (addr >= RAM_OFFSET) {
                v = boardram[(addr & RAM_MASK) ^ 1];
        }
-       if (a2065_log > 2)
+       if (log_a2065 > 2)
                write_log (L"A2065_BGET: %08X -> %02X PC=%08X\n", addr, v & 0xff, M68K_GETPC);
        return v;
 }
@@ -650,7 +717,7 @@ static void a2065_bput2 (uaecptr addr, uae_u32 v)
        if (addr >= RAM_OFFSET) {
                boardram[(addr & RAM_MASK) ^ 1] = v;
        }
-       if (a2065_log > 2)
+       if (log_a2065 > 2)
                write_log (L"A2065_BPUT: %08X <- %02X PC=%08X\n", addr, v & 0xff, M68K_GETPC);
 }
 
@@ -731,13 +798,13 @@ static void REGPARAM2 a2065_bput (uaecptr addr, uae_u32 b)
        if (addr == 0x48 && !configured) {
                map_banks (&a2065_bank, b, 0x10000 >> 16, 0x10000);
                write_log (L"A2065 Z2 autoconfigured at %02X0000\n", b);
-               configured = 1;
+               configured = b;
                expamem_next ();
                return;
        }
        if (addr == 0x4c && !configured) {
                write_log (L"A2065 DMAC AUTOCONFIG SHUT-UP!\n");
-               configured = 1;
+               configured = 0xff;
                expamem_next ();
                return;
        }
@@ -773,10 +840,9 @@ static addrbank a2065_bank = {
        a2065_lgeti, a2065_wgeti, ABFLAG_IO
 };
 
-void a2065_init (void)
+static void a2065_config (void)
 {
        memset (config, 0xff, sizeof config);
-       configured = 0;
        ew (0x00, 0xc0 | 0x01);
        // hardware id
        ew (0x04, 0x70);
@@ -812,7 +878,49 @@ void a2065_init (void)
        fakemac[4] = realmac[4];
        fakemac[5] = realmac[5];
 
-       /* KS autoconfig handles the rest */
-       map_banks (&a2065_bank, 0xe80000 >> 16, 0x10000 >> 16, 0x10000);
+       if (configured) {
+               if (configured != 0xff)
+                       map_banks (&a2065_bank, configured, 0x10000 >> 16, 0x10000);
+       } else {
+               /* KS autoconfig handles the rest */
+               map_banks (&a2065_bank, 0xe80000 >> 16, 0x10000 >> 16, 0x10000);
+       }
+}
 
+uae_u8 *save_a2065 (int *len, uae_u8 *dstptr)
+{
+       uae_u8 *dstbak,*dst;
+
+       if (currprefs.a2065name[0] == 0)
+               return NULL;
+       if (dstptr)
+               dstbak = dst = dstptr;
+       else
+               dstbak = dst = (uae_u8*)malloc (16);
+       save_u32 (0);
+       save_u8 (configured);
+       for (int i = 0; i < 6; i++)
+               save_u8 (realmac[i]);
+       *len = dst - dstbak;
+       return dstbak;
+}
+uae_u8 *restore_a2065 (uae_u8 *src)
+{
+       restore_u32 ();
+       configured = restore_u8 ();
+       for (int i = 0; i < 6; i++)
+               realmac[i] = restore_u8 ();
+       return src;
+}
+
+void restore_a2065_finish (void)
+{
+       if (configured)
+               a2065_config ();
+}
+
+void a2065_init (void)
+{
+       configured = 0;
+       a2065_config ();
 }
index 9c19c45ec3f251fbaa1770cf6010db705176a54f..b937eefba2bd32877d02b44975e07220308b088a 100644 (file)
--- a/akiko.cpp
+++ b/akiko.cpp
@@ -1702,7 +1702,7 @@ int akiko_init (void)
 
 #ifdef SAVESTATE
 
-uae_u8 *save_akiko (int *len)
+uae_u8 *save_akiko (int *len, uae_u8 *dstptr)
 {
        uae_u8 *dstbak, *dst;
        int i;
@@ -1710,7 +1710,10 @@ uae_u8 *save_akiko (int *len)
        if (!currprefs.cs_cd32cd)
                return NULL;
 
-       dstbak = dst = xmalloc (uae_u8, 1000);
+       if (dstptr)
+               dstbak = dst = dstptr;
+       else
+               dstbak = dst = xmalloc (uae_u8, 1000);
        save_u16 (0);
        save_u16 (0xCAFE);
        save_u32 (cdrom_intreq);
diff --git a/ar.cpp b/ar.cpp
index 2cd4387ee12db82d5aea9e9077ccb1ce98ef121d..e3bf8eac9699ea88b699bb7d3413b0140442d84f 100644 (file)
--- a/ar.cpp
+++ b/ar.cpp
@@ -997,7 +997,7 @@ static void hrtmon_go (void)
                old = get_long ((uaecptr)(regs.vbr + 0x8));
                put_word (hrtmem_start + 0xc0000, 4);
                put_long ((uaecptr)(regs.vbr + 8), get_long (hrtmem_start + 8));
-               Exception (2, 0);
+               Exception (2);
                put_long ((uaecptr)(regs.vbr + 8), old);
        } else if (cart_type == CART_SUPER4) {
                uae_u32 v = get_long (hrtmem_start + 0x7c);
@@ -1076,7 +1076,7 @@ void check_prefs_changed_carts (int in_memory_reset)
 void action_replay_reset (void)
 {
        if (hrtmemory) {
-               if (savestate_state == STATE_RESTORE) {
+               if (isrestore ()) {
                        if (m68k_getpc () >= hrtmem_start && m68k_getpc () <= hrtmem_start + hrtmem_size)
                                hrtmon_map_banks ();
                        else
@@ -1086,7 +1086,7 @@ void action_replay_reset (void)
                if (action_replay_flag == ACTION_REPLAY_INACTIVE)
                        return;
 
-               if (savestate_state == STATE_RESTORE) {
+               if (isrestore ()) {
                        if (m68k_getpc () >= arrom_start && m68k_getpc () <= arrom_start + arrom_size) {
                                action_replay_flag = ACTION_REPLAY_ACTIVE;
                                hide_cart (0);
index 436a0c7556de30a3d217237ce188a2f8f1c094f7..5cad8700bd0eda0a9b1345269810f73b67f7a7c8 100644 (file)
--- a/audio.cpp
+++ b/audio.cpp
@@ -49,6 +49,7 @@
 //#define TEST_AUDIO
 
 #define PERIOD_MIN 4
+#define PERIOD_MIN_NONCE 60
 
 int audio_channel_mask = 15;
 
@@ -1073,10 +1074,12 @@ static void audio_event_reset (void)
 {
        int i;
 
-       last_cycles = get_cycles () - 1;
+       last_cycles = get_cycles ();
        next_sample_evtime = scaled_sample_evtime;
-       for (i = 0; i < 4; i++)
-               zerostate (i);
+       if (!isrestore ()) {
+               for (i = 0; i < 4; i++)
+                       zerostate (i);
+       }
        schedule_audio ();
        events_schedule ();
        samplecnt = 0;
@@ -1180,23 +1183,23 @@ STATIC_INLINE void setdr (int nr)
        }
 }
 
-static void loaddat (int nr)
+static void loaddat (int nr, bool modper)
 {
        struct audio_channel_data *cdp = audio_channel + nr;
        int audav = adkcon & (0x01 << nr);
        int audap = adkcon & (0x10 << nr);
-       if (audav || audap) {
-               if (nr > 3)
+       if (audav || (modper && audap)) {
+               if (nr >= 3)
                        return;
-               if (audav) {
-                       cdp[1].vol = cdp->dat;
-               } else if (audap) {
+               if (modper && audap) {
                        if (cdp->dat == 0)
                                cdp[1].per = PERIOD_MAX;
                        else if (cdp->dat > PERIOD_MIN)
                                cdp[1].per = cdp->dat * CYCLE_UNIT;
                        else
                                cdp[1].per = PERIOD_MIN * CYCLE_UNIT;
+               } else  if (audav) {
+                       cdp[1].vol = cdp->dat;
                }
        } else {
 #ifdef TEST_AUDIO
@@ -1210,6 +1213,10 @@ static void loaddat (int nr)
                cdp->dat2 = cdp->dat;
        }
 }
+static void loaddat (int nr)
+{
+       loaddat (nr, false);
+}
 
 STATIC_INLINE void loadper (int nr)
 {
@@ -1353,7 +1360,7 @@ static void audio_state_channel2 (int nr, bool perfin)
                if (!perfin)
                        return;
                if (audap)
-                       loaddat (nr);
+                       loaddat (nr, true);
                if (chan_ena) {
                        if (audap)
                                setdr (nr);
@@ -1438,7 +1445,7 @@ void audio_reset (void)
 #endif
        reset_sound ();
        memset (sound_filter_state, 0, sizeof sound_filter_state);
-       if (savestate_state != STATE_RESTORE) {
+       if (!isrestore ()) {
                for (i = 0; i < 4; i++) {
                        cdp = &audio_channel[i];
                        memset (cdp, 0, sizeof *audio_channel);
@@ -1448,7 +1455,7 @@ void audio_reset (void)
                }
        }
 
-       last_cycles = get_cycles () - 1;
+       last_cycles = get_cycles ();
        next_sample_evtime = scaled_sample_evtime;
        schedule_audio ();
        events_schedule ();
@@ -1563,7 +1570,7 @@ void set_audio (void)
                        }
                }
                next_sample_evtime = scaled_sample_evtime;
-               last_cycles = get_cycles () - 1;
+               last_cycles = get_cycles ();
                compute_vsynctime ();
        } else {
                sound_volume (0);
@@ -1659,7 +1666,7 @@ void update_audio (void)
 
        if (!isaudio ())
                goto end;
-       if (savestate_state == STATE_RESTORE)
+       if (isrestore ())
                goto end;
        if (!is_audio_active ())
                goto end;
@@ -1858,6 +1865,10 @@ void AUDxPER (int nr, uae_u16 v)
                /* smaller values would cause extremely high cpu usage */
                per = PERIOD_MIN * CYCLE_UNIT;
        }
+       if (per < PERIOD_MIN_NONCE * CYCLE_UNIT && !currprefs.cpu_cycle_exact && (cdp->dmaenstore || cdp->state == 0)) {
+               /* DMAL emulation and low period can cause very very high cpu usage on slow performance PCs */
+               per = PERIOD_MIN_NONCE * CYCLE_UNIT;
+       }
 
        if (cdp->per == PERIOD_MAX - 1 && per != PERIOD_MAX - 1) {
                cdp->evtime = CYCLE_UNIT;
@@ -1966,11 +1977,19 @@ void audio_vsync (void)
 #endif
 }
 
+void restore_audio_finish (void)
+{
+       last_cycles = get_cycles ();
+       schedule_audio ();
+       events_schedule ();
+}
+
 uae_u8 *restore_audio (int nr, uae_u8 *src)
 {
        struct audio_channel_data *acd = audio_channel + nr;
        uae_u16 p;
 
+       zerostate (nr);
        acd->state = restore_u8 ();
        acd->vol = restore_u8 ();
        acd->intreq2 = restore_u8 () ? true : false;
index 3d4a74365975fb9ec3461fe52158ffea8e0d44b7..e8eaeaf48ffa80c89c02177efebb7f448d532a82 100644 (file)
@@ -30,6 +30,7 @@
 
 /* we must not change ce-mode while blitter is running.. */
 static int blitter_cycle_exact;
+static int blt_statefile_type;
 
 uae_u16 bltcon0, bltcon1;
 uae_u32 bltapt, bltbpt, bltcpt, bltdpt;
@@ -44,7 +45,6 @@ static int blitonedot, blitsign, blitlinepixel;
 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;
@@ -98,7 +98,9 @@ same in both block and line modes
 number of cycles, initial cycle, main cycle
 */
 
-static const int blit_cycle_diagram[][10] =
+#define DIAGSIZE 10
+
+static const int blit_cycle_diagram[][DIAGSIZE] =
 {
        { 2, 0,0,           0,0 },              /* 0 */
        { 2, 0,0,           0,4 },              /* 1 */
@@ -125,7 +127,7 @@ idle cycle added (still requires free bus cycle)
 
 */
 
-static const int blit_cycle_diagram_fill[][10] =
+static const int blit_cycle_diagram_fill[][DIAGSIZE] =
 {
        { 0 },                                          /* 0 */
        { 3, 0,0,0,         0,4,0 },    /* 1 */
@@ -188,6 +190,36 @@ static const int blit_cycle_diagram_finalld[] =
        2, 0,0,     0,0
 };
 
+static int get_cycle_diagram_type (const int *diag)
+{
+       for (int i = 0; i < 16; i++) {
+               if (diag == &blit_cycle_diagram[i][0])
+                       return i;
+               if (diag == &blit_cycle_diagram_fill[i][0])
+                       return i + 0x40;
+       }
+       if (diag == blit_cycle_diagram_line)
+               return 0x80;
+       if (diag == blit_cycle_diagram_finald)
+               return 0x81;
+       if (diag == blit_cycle_diagram_finalld)
+               return 0x82;
+       return 0xff;
+}
+static const int *set_cycle_diagram_type (uae_u8 diag)
+{
+       if (diag >= 0x00 && diag <= 0x0f)
+               return &blit_cycle_diagram[diag][0];
+       if (diag >= 0x40 && diag <= 0x4f)
+               return &blit_cycle_diagram_fill[diag][0];
+       if (diag == 0x80)
+               return blit_cycle_diagram_line;
+       if (diag == 0x81)
+               return blit_cycle_diagram_finald;
+       if (diag == 0x82)
+               return blit_cycle_diagram_finalld;
+       return NULL;
+}
 
 void build_blitfilltable (void)
 {
@@ -336,23 +368,23 @@ static void blitter_dofast (void)
        uae_u8 mt = bltcon0 & 0xFF;
 
        blit_masktable[0] = blt_info.bltafwm;
-       blit_masktable[hblitsize - 1] &= blt_info.bltalwm;
+       blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm;
 
        if (bltcon0 & 0x800) {
                bltadatptr = bltapt;
-               bltapt += (hblitsize * 2 + blt_info.bltamod) * vblitsize;
+               bltapt += (blt_info.hblitsize * 2 + blt_info.bltamod) * blt_info.vblitsize;
        }
        if (bltcon0 & 0x400) {
                bltbdatptr = bltbpt;
-               bltbpt += (hblitsize * 2 + blt_info.bltbmod) * vblitsize;
+               bltbpt += (blt_info.hblitsize * 2 + blt_info.bltbmod) * blt_info.vblitsize;
        }
        if (bltcon0 & 0x200) {
                bltcdatptr = bltcpt;
-               bltcpt += (hblitsize * 2 + blt_info.bltcmod) * vblitsize;
+               bltcpt += (blt_info.hblitsize * 2 + blt_info.bltcmod) * blt_info.vblitsize;
        }
        if (bltcon0 & 0x100) {
                bltddatptr = bltdpt;
-               bltdpt += (hblitsize * 2 + blt_info.bltdmod) * vblitsize;
+               bltdpt += (blt_info.hblitsize * 2 + blt_info.bltdmod) * blt_info.vblitsize;
        }
 
 #ifdef SPEEDUP
@@ -366,9 +398,9 @@ static void blitter_dofast (void)
                uaecptr dstp = 0;
                int dodst = 0;
 
-               for (j = 0; j < vblitsize; j++) {
+               for (j = 0; j < blt_info.vblitsize; j++) {
                        blitfc = !!(bltcon1 & 0x4);
-                       for (i = 0; i < hblitsize; i++) {
+                       for (i = 0; i < blt_info.hblitsize; i++) {
                                uae_u32 bltadat, blitahold;
                                uae_u16 bltbdat;
                                if (bltadatptr) {
@@ -424,7 +456,7 @@ static void blitter_dofast (void)
                blt_info.bltbhold = blitbhold;
        }
        blit_masktable[0] = 0xFFFF;
-       blit_masktable[hblitsize - 1] = 0xFFFF;
+       blit_masktable[blt_info.hblitsize - 1] = 0xFFFF;
 
        bltstate = BLT_done;
 }
@@ -436,23 +468,23 @@ static void blitter_dofast_desc (void)
        uae_u8 mt = bltcon0 & 0xFF;
 
        blit_masktable[0] = blt_info.bltafwm;
-       blit_masktable[hblitsize - 1] &= blt_info.bltalwm;
+       blit_masktable[blt_info.hblitsize - 1] &= blt_info.bltalwm;
 
        if (bltcon0 & 0x800) {
                bltadatptr = bltapt;
-               bltapt -= (hblitsize*2 + blt_info.bltamod)*vblitsize;
+               bltapt -= (blt_info.hblitsize * 2 + blt_info.bltamod) * blt_info.vblitsize;
        }
        if (bltcon0 & 0x400) {
                bltbdatptr = bltbpt;
-               bltbpt -= (hblitsize*2 + blt_info.bltbmod)*vblitsize;
+               bltbpt -= (blt_info.hblitsize * 2 + blt_info.bltbmod) * blt_info.vblitsize;
        }
        if (bltcon0 & 0x200) {
                bltcdatptr = bltcpt;
-               bltcpt -= (hblitsize*2 + blt_info.bltcmod)*vblitsize;
+               bltcpt -= (blt_info.hblitsize * 2 + blt_info.bltcmod) * blt_info.vblitsize;
        }
        if (bltcon0 & 0x100) {
                bltddatptr = bltdpt;
-               bltdpt -= (hblitsize*2 + blt_info.bltdmod)*vblitsize;
+               bltdpt -= (blt_info.hblitsize * 2 + blt_info.bltdmod) * blt_info.vblitsize;
        }
 #ifdef SPEEDUP
        if (blitfunc_dofast_desc[mt] && !blitfill) {
@@ -465,9 +497,9 @@ static void blitter_dofast_desc (void)
                uaecptr dstp = 0;
                int dodst = 0;
 
-               for (j = 0; j < vblitsize; j++) {
+               for (j = 0; j < blt_info.vblitsize; j++) {
                        blitfc = !!(bltcon1 & 0x4);
-                       for (i = 0; i < hblitsize; i++) {
+                       for (i = 0; i < blt_info.hblitsize; i++) {
                                uae_u32 bltadat, blitahold;
                                uae_u16 bltbdat;
                                if (bltadatptr) {
@@ -523,7 +555,7 @@ static void blitter_dofast_desc (void)
                blt_info.bltbhold = blitbhold;
        }
        blit_masktable[0] = 0xFFFF;
-       blit_masktable[hblitsize - 1] = 0xFFFF;
+       blit_masktable[blt_info.hblitsize - 1] = 0xFFFF;
 
        bltstate = BLT_done;
 }
@@ -633,7 +665,7 @@ static void blitter_line_proc (void)
 STATIC_INLINE void blitter_nxline (void)
 {
        blineb = (blineb << 1) | (blineb >> 15);
-       vblitsize--;
+       blt_info.vblitsize--;
        bltstate = BLT_read;
 }
 
@@ -645,7 +677,7 @@ static int blitter_vcounter1, blitter_vcounter2;
 
 static void decide_blitter_line (int hsync, int hpos)
 {
-       if (blit_final && vblitsize)
+       if (blit_final && blt_info.vblitsize)
                blit_final = 0;
        while (last_blitter_hpos < hpos) {
                int c = channel_state (blit_cyclecounter);
@@ -707,7 +739,7 @@ static void decide_blitter_line (int hsync, int hpos)
                                        record_dma_blit (0x00, blt_info.bltddat, bltdpt, last_blitter_hpos);
                                        blitlinepixel = 0;
                                }
-                               if (vblitsize == 0) {
+                               if (blt_info.vblitsize == 0) {
                                        bltdpt = bltcpt;
                                        blit_final = 1;
                                        blit_cyclecounter = 0;
@@ -742,7 +774,7 @@ static void actually_do_blit (void)
                                blitter_write ();
                                blitlinepixel = 0;
                        }
-                       if (vblitsize == 0)
+                       if (blt_info.vblitsize == 0)
                                bltstate = BLT_done;
                } while (bltstate != BLT_done);
                bltdpt = bltcpt;
@@ -798,7 +830,7 @@ STATIC_INLINE uae_u16 blitter_doblit (void)
        bltadat = blt_info.bltadat;
        if (blitter_hcounter1 == 0)
                bltadat &= blt_info.bltafwm;
-       if (blitter_hcounter1 == hblitsize - 1)
+       if (blitter_hcounter1 == blt_info.hblitsize - 1)
                bltadat &= blt_info.bltalwm;
        if (blitdesc)
                blitahold = (((uae_u32)bltadat << 16) | preva) >> blt_info.blitdownashift;
@@ -851,7 +883,7 @@ STATIC_INLINE void blitter_doddma (int hpos)
        chipmem_agnus_wput2 (bltdpt, d);
        bltdpt += blit_add;
        blitter_hcounter2++;
-       if (blitter_hcounter2 == hblitsize) {
+       if (blitter_hcounter2 == blt_info.hblitsize) {
                blitter_hcounter2 = 0;
                bltdpt += blit_modaddd;
                blitter_vcounter2++;
@@ -909,7 +941,7 @@ STATIC_INLINE void blitter_dodma (int ch, int hpos)
                if (bltcon0 & 0x100)
                        ddat1use = 1;
                blitter_hcounter1++;
-               if (blitter_hcounter1 == hblitsize) {
+               if (blitter_hcounter1 == blt_info.hblitsize) {
                        blitter_hcounter1 = 0;
                        if (bltcon0 & 0x800)
                                bltapt += blit_modadda;
@@ -1049,14 +1081,14 @@ void decide_blitter (int hpos)
                                blit_cyclecounter++;
                                blit_totalcyclecounter++;
                        } else {
-                               if (blitter_vcounter1 < vblitsize) {
+                               if (blitter_vcounter1 < blt_info.vblitsize) {
                                        blitter_dodma (c, last_blitter_hpos);
                                }
                                blit_cyclecounter++;
                                blit_totalcyclecounter++;
                        }
 
-                       if (blitter_vcounter1 >= vblitsize && blitter_vcounter2 >= vblitsize) {
+                       if (blitter_vcounter1 >= blt_info.vblitsize && blitter_vcounter2 >= blt_info.vblitsize) {
                                if (!ddat1use && !ddat2use) {
                                        blitter_done (last_blitter_hpos);
                                        return;
@@ -1065,7 +1097,7 @@ void decide_blitter (int hpos)
                        break;
                }
 
-               if (!blit_final && blitter_vcounter1 == vblitsize && channel_pos (blit_cyclecounter - 1) == blit_diag[0] - 1) {
+               if (!blit_final && blitter_vcounter1 == blt_info.vblitsize && channel_pos (blit_cyclecounter - 1) == blit_diag[0] - 1) {
                        blitter_interrupt (last_blitter_hpos, 0);
                        blit_cyclecounter = 0;
                        blit_final = 1;
@@ -1130,9 +1162,9 @@ static void blit_bltset (int con)
        blitfill = !!(bltcon1 & 0x18);
 
        if (blitline) {
-               if (hblitsize != 2)
-                       debugtest (DEBUGTEST_BLITTER, L"weird hblitsize in linemode: %d vsize=%d\n",
-                       hblitsize, vblitsize);
+               if (blt_info.hblitsize != 2)
+                       debugtest (DEBUGTEST_BLITTER, L"weird blt_info.hblitsize in linemode: %d vsize=%d\n",
+                       blt_info.hblitsize, blt_info.vblitsize);
                blit_diag = blit_cycle_diagram_line;
        } else {
                if (con & 2) {
@@ -1257,8 +1289,6 @@ static void do_blitter2 (int hpos, int copper)
 
        bltstate = BLT_done;
 
-       hblitsize = blt_info.hblitsize;
-       vblitsize = blt_info.vblitsize;
        blitter_cycle_exact = currprefs.blitter_cycle_exact;
        blt_info.blitzero = 1;
        preva = 0;
@@ -1285,10 +1315,10 @@ static void do_blitter2 (int hpos, int copper)
                blitonedot = 0;
                blitlinepixel = 0;
                blitsing = bltcon1 & 0x2;
-               cycles = vblitsize;
+               cycles = blt_info.vblitsize;
        } else {
-               blit_firstline_cycles = blit_first_cycle + (blit_diag[0] * hblitsize + cpu_cycles) * CYCLE_UNIT;
-               cycles = vblitsize * hblitsize;
+               blit_firstline_cycles = blit_first_cycle + (blit_diag[0] * blt_info.hblitsize + cpu_cycles) * CYCLE_UNIT;
+               cycles = blt_info.vblitsize * blt_info.hblitsize;
        }
 
        if (cleanstart) {
@@ -1310,7 +1340,7 @@ static void do_blitter2 (int hpos, int copper)
                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",
-                       hblitsize, vblitsize, ch, blit_diag[0], cycles, blit_diag[0] * cycles,
+                       blt_info.hblitsize, blt_info.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 ();
        }
@@ -1345,16 +1375,16 @@ static void do_blitter2 (int hpos, int copper)
                blitter_hcounter1 = blitter_hcounter2 = 0;
                blitter_vcounter1 = blitter_vcounter2 = 0;
                if (blit_nod)
-                       blitter_vcounter2 = vblitsize;
+                       blitter_vcounter2 = blt_info.vblitsize;
                blit_cyclecounter = -BLITTER_STARTUP_CYCLES;
                blit_waitcyclecounter = copper;
                blit_startcycles = 0;
-               blit_maxcyclecounter = hblitsize * vblitsize + 2;
+               blit_maxcyclecounter = blt_info.hblitsize * blt_info.vblitsize + 2;
 #endif
                return;
        }
 
-       if (vblitsize == 0 || (blitline && hblitsize != 2)) {
+       if (blt_info.vblitsize == 0 || (blitline && blt_info.hblitsize != 2)) {
                blitter_done (hpos);
                return;
        }
@@ -1466,10 +1496,32 @@ void blitter_slowdown (int ddfstrt, int ddfstop, int totalcycles, int freecycles
 
 #ifdef SAVESTATE
 
+void restore_blitter_finish (void)
+{
+       record_dma_reset ();
+       record_dma_reset ();
+       if (blt_statefile_type == 0) {
+               blit_interrupt = 1;
+               if (bltstate == BLT_init) {
+                       write_log (L"blitter was started but DMA was inactive during save\n");
+                       //do_blitter (0);
+               }
+               if (blt_delayed_irq < 0) {
+                       if (intreq & 0x0040)
+                               blt_delayed_irq = 3;
+                       intreq &= 0x0040;
+               }
+       } else {
+               last_blitter_hpos = 0;
+               blit_modset ();
+       }
+}
+
 uae_u8 *restore_blitter (uae_u8 *src)
 {
        uae_u32 flags = restore_u32();
 
+       blt_statefile_type = 0;
        blt_delayed_irq = 0;
        bltstate = BLT_done;
        if (flags & 4) {
@@ -1486,22 +1538,6 @@ uae_u8 *restore_blitter (uae_u8 *src)
        return src;
 }
 
-void restore_blitter_finish (void)
-{
-       record_dma_reset ();
-       record_dma_reset ();
-       blit_interrupt = 1;
-       if (bltstate == BLT_init) {
-               write_log (L"blitter was started but DMA was inactive during save\n");
-               //do_blitter (0);
-       }
-       if (blt_delayed_irq < 0) {
-               if (intreq & 0x0040)
-                       blt_delayed_irq = 3;
-               intreq &= 0x0040;
-       }
-}
-
 uae_u8 *save_blitter (int *len, uae_u8 *dstptr)
 {
        uae_u8 *dstbak,*dst;
@@ -1524,4 +1560,169 @@ uae_u8 *save_blitter (int *len, uae_u8 *dstptr)
 
 }
 
+// totally non-real-blitter-like state save but better than nothing..
+
+uae_u8 *restore_blitter_new (uae_u8 *src)
+{
+       uae_u8 state;
+       blt_statefile_type = 1;
+       blitter_cycle_exact = restore_u8 ();
+       state = restore_u8 ();
+
+       blit_first_cycle = restore_u32 ();
+       blit_last_cycle = restore_u32 ();
+       blit_waitcyclecounter = restore_u32 ();
+       blit_startcycles = restore_u32 ();
+       blit_maxcyclecounter = restore_u32 ();
+       blit_firstline_cycles = restore_u32 ();
+       blit_cyclecounter = restore_u32 ();
+       blit_slowdown = restore_u32 ();
+       blit_misscyclecounter = restore_u32 ();
+
+       blitter_hcounter1 = restore_u16 ();
+       blitter_hcounter2 = restore_u16 ();
+       blitter_vcounter1 = restore_u16 ();
+       blitter_vcounter2 = restore_u16 ();
+       blit_ch = restore_u8 ();
+       blit_dmacount = restore_u8 ();
+       blit_dmacount2 = restore_u8 ();
+       blit_nod = restore_u8 ();
+       blit_final = restore_u8 ();
+       blitfc = restore_u8 ();
+       blitife = restore_u8 ();
+
+       blt_info.blitbshift = restore_u8 ();
+       blt_info.blitdownbshift = restore_u8 ();
+       blt_info.blitashift = restore_u8 ();
+       blt_info.blitdownashift = restore_u8 ();
+
+       ddat1use = restore_u8 ();
+       ddat2use = restore_u8 ();
+       ddat1 = restore_u16 ();
+       ddat2 = restore_u16 ();
+
+       blitline = restore_u8 ();
+       blitfill = restore_u8 ();
+       blinea = restore_u16 ();
+       blineb = restore_u16 ();
+       blinea_shift = restore_u8 ();
+       blitonedot = restore_u8 ();
+       blitlinepixel = restore_u8 ();
+       blitsing = restore_u8 ();
+       blitlinepixel = restore_u8 ();
+       blit_interrupt = restore_u8 ();
+       blt_delayed_irq = restore_u8 ();
+       blt_info.blitzero = restore_u8 ();
+       blt_info.got_cycle = restore_u8 ();
+
+       blit_frozen = restore_u8 ();
+       blit_faulty = restore_u8 ();
+       original_ch = restore_u8 ();
+       original_fill = restore_u8 ();
+       original_line = restore_u8 ();
+
+       blit_diag = set_cycle_diagram_type (restore_u8 ());
+
+       if (restore_u16 () != 0x1234)
+               write_log (L"error\n");
+
+       blitter_nasty = restore_u8 ();
+
+       bltstate = BLT_done;
+       if (!blitter_cycle_exact) {
+               if (state > 0)
+                       do_blitter (0, 0);
+       } else {
+               if (state == 1)
+                       bltstate = BLT_init;
+               else if (state == 2)
+                       bltstate = BLT_work;
+       }
+       return src;
+}
+
+uae_u8 *save_blitter_new (int *len, uae_u8 *dstptr)
+{
+       uae_u8 *dstbak,*dst;
+       if (dstptr)
+               dstbak = dst = dstptr;
+       else
+               dstbak = dst = xmalloc (uae_u8, 1000);
+
+       uae_u8 state;
+       save_u8 (blitter_cycle_exact ? 1 : 0);
+       if (bltstate == BLT_done)
+               state = 0;
+       else if (bltstate == BLT_init)
+               state = 1;
+       else
+               state = 2;
+       save_u8 (state);
+
+       if (bltstate != BLT_done) {
+               write_log (L"BLITTER active while saving state\n");
+               blitter_dump ();
+       }
+
+       save_u32 (blit_first_cycle);
+       save_u32 (blit_last_cycle);
+       save_u32 (blit_waitcyclecounter);
+       save_u32 (blit_startcycles);
+       save_u32 (blit_maxcyclecounter);
+       save_u32 (blit_firstline_cycles);
+       save_u32 (blit_cyclecounter);
+       save_u32 (blit_slowdown);
+       save_u32 (blit_misscyclecounter);
+
+       save_u16 (blitter_hcounter1);
+       save_u16 (blitter_hcounter2);
+       save_u16 (blitter_vcounter1);
+       save_u16 (blitter_vcounter2);
+       save_u8 (blit_ch);
+       save_u8 (blit_dmacount);
+       save_u8 (blit_dmacount2);
+       save_u8 (blit_nod);
+       save_u8 (blit_final);
+       save_u8 (blitfc);
+       save_u8 (blitife);
+
+       save_u8 (blt_info.blitbshift);
+       save_u8 (blt_info.blitdownbshift);
+       save_u8 (blt_info.blitashift);
+       save_u8 (blt_info.blitdownashift);
+
+       save_u8 (ddat1use);
+       save_u8 (ddat2use);
+       save_u16 (ddat1);
+       save_u16 (ddat2);
+
+       save_u8 (blitline);
+       save_u8 (blitfill);
+       save_u16 (blinea);
+       save_u16 (blineb);
+       save_u8 (blinea_shift);
+       save_u8 (blitonedot);
+       save_u8 (blitlinepixel);
+       save_u8 (blitsing);
+       save_u8 (blitlinepixel);
+       save_u8 (blit_interrupt);
+       save_u8 (blt_delayed_irq);
+       save_u8 (blt_info.blitzero);
+       save_u8 (blt_info.got_cycle);
+       
+       save_u8 (blit_frozen);
+       save_u8 (blit_faulty);
+       save_u8 (original_ch);
+       save_u8 (original_fill);
+       save_u8 (original_line);
+       save_u8 (get_cycle_diagram_type (blit_diag));
+
+       save_u16 (0x1234);
+
+       save_u8 (blitter_nasty);
+
+       *len = dst - dstbak;
+       return dstbak;
+}
+
 #endif /* SAVESTATE */
index 8c549f594de3511b42e124f6cda6ef55cc5b69c8..68d988e985d863bfbad4f96ab8c219fb7c988eda 100644 (file)
@@ -35,6 +35,10 @@ static int delayed[MAX_TOTAL_SCSI_DEVICES];
 static uae_sem_t unitsem[MAX_TOTAL_SCSI_DEVICES];
 static int unitsem_cnt[MAX_TOTAL_SCSI_DEVICES];
 
+static TCHAR newimagefiles[MAX_TOTAL_SCSI_DEVICES][256];
+static int imagechangetime[MAX_TOTAL_SCSI_DEVICES];
+static bool cdimagefileinuse[MAX_TOTAL_SCSI_DEVICES], wasopen[MAX_TOTAL_SCSI_DEVICES];
+
 /* convert minutes, seconds and frames -> logical sector number */
 int msf2lsn (int msf)
 {
@@ -421,11 +425,17 @@ void blkdev_cd_change (int unitnum, const TCHAR *name)
 
 void device_func_reset (void)
 {
+       for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
+               wasopen[i] = false;
+               waspaused[i] = false;
+               imagechangetime[i] = 0;
+               cdimagefileinuse[i] = false;
+               newimagefiles[i][0] = 0;
+       }
 }
 
 int device_func_init (int flags)
 {
-       device_func_reset ();
        blkdev_fix_prefs (&currprefs);
        install_driver (flags);
        return 1;
@@ -455,12 +465,6 @@ void blkdev_exitgui (void)
        }
 }
 
-
-
-static TCHAR newimagefiles[MAX_TOTAL_SCSI_DEVICES][256];
-static int imagechangetime[MAX_TOTAL_SCSI_DEVICES];
-static bool cdimagefileinuse[MAX_TOTAL_SCSI_DEVICES], wasopen[MAX_TOTAL_SCSI_DEVICES];
-
 static void check_changes (int unitnum)
 {
        bool changed = false;
@@ -1038,6 +1042,19 @@ static int addtocentry (uae_u8 **dstp, int *len, int point, int newpoint, int ms
        return -1;
 }
 
+static int scsiemudrv (int unitnum, uae_u8 *cmd)
+{
+       if (failunit (unitnum))
+               return -1;
+       if (!getsem (unitnum))
+               return 0;
+       int v = 0;
+       if (device_func[unitnum]->scsiemu)
+               v = device_func[unitnum]->scsiemu (unitnum, cmd);
+       freesem (unitnum);
+       return v;
+}
+
 static int scsi_read_cd (int unitnum, uae_u8 *cmd, uae_u8 *data, struct device_info *di)
 {
        int msf = cmd[0] == 0xb9;
@@ -1419,6 +1436,7 @@ static int scsi_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
                break;
                case 0x1b: // START/STOP
                        sys_command_cd_stop (unitnum);
+                       scsiemudrv (unitnum, cmdbuf);
                        scsi_len = 0;
                break;
                case 0x1e: // PREVENT/ALLOW MEDIA REMOVAL
@@ -1743,6 +1761,8 @@ uae_u8 *save_cd (int num, int *len)
 
        if (!currprefs.cdslots[num].inuse || num >= MAX_TOTAL_SCSI_DEVICES)
                return NULL;
+       if (!currprefs.cs_cd32cd && !currprefs.cs_cdtvcd && !currprefs.scsi)
+               return NULL;
        dstbak = dst = xmalloc (uae_u8, 4 + 256 + 4 + 4);
        save_u32 (4);
        save_string (currprefs.cdslots[num].name);
index 308e965f729a1306766d701bd5d33797c2c1c0aa..a83d99f6056aaf58c6c220da05dccb607da2ebe2 100644 (file)
--- a/cdtv.cpp
+++ b/cdtv.cpp
@@ -324,7 +324,7 @@ static int play_cdtrack (uae_u8 *p)
 
        end = last_cd_position;
        start_found = end_found = 0;
-       for (j = 0; j < toc.points; j++) {
+       for (j = toc.first_track_offset; j <= toc.last_track_offset; j++) {
                struct cd_toc *s = &toc.toc[j];
                if (track_start == s->track) {
                        start_found++;
@@ -1771,11 +1771,16 @@ void cdtv_check_banks (void)
 
 #ifdef SAVESTATE
 
-uae_u8 *save_dmac (int *len)
+uae_u8 *save_dmac (int *len, uae_u8 *dstptr)
 {
        uae_u8 *dstbak, *dst;
        
-       dstbak = dst = xmalloc (uae_u8, 1000);
+       if (!currprefs.cs_cdtvcd)
+               return NULL;
+       if (dstptr)
+               dstbak = dst = dstptr;
+       else
+               dstbak = dst = xmalloc (uae_u8, 1000);
 
        // model (0=original,1=rev2,2=superdmac)
        save_u32 (1);
@@ -1806,13 +1811,17 @@ uae_u8 *restore_dmac (uae_u8 *src)
        return src;
 }
 
-uae_u8 *save_cdtv (int *len)
+uae_u8 *save_cdtv (int *len, uae_u8 *dstptr)
 {
        uae_u8 *dstbak, *dst;
 
        if (!currprefs.cs_cdtvcd)
                return NULL;
-       dstbak = dst = xmalloc (uae_u8, 1000);
+
+       if (dstptr) 
+               dstbak = dst = dstptr;
+       else
+               dstbak = dst = xmalloc (uae_u8, 1000);
 
        save_u32 (1);
 
index ea693cea1cf8ceacd53668faa6ff3e9315b9f3f0..45d9630002f6907f72309d245a98252551573952 100644 (file)
@@ -165,8 +165,8 @@ static const TCHAR *maxhoriz[] = { L"lores", L"hires", L"superhires", 0 };
 static const TCHAR *maxvert[] = { L"nointerlace", L"interlace", 0 };
 static const TCHAR *abspointers[] = { L"none", L"mousehack", L"tablet", 0 };
 static const TCHAR *magiccursors[] = { L"both", L"native", L"host", 0 };
-static const TCHAR *autoscale[] = { L"none", L"standard", L"max", L"scale", L"resize", L"center", 0 };
-static const TCHAR *joyportmodes[] = { L"", L"mouse", L"djoy", L"ajoy", L"cdtvjoy", L"cd32joy", L"lightpen", 0 };
+static const TCHAR *autoscale[] = { L"none", L"auto", L"standard", L"max", L"scale", L"resize", L"center", 0 };
+static const TCHAR *joyportmodes[] = { L"", L"mouse", L"djoy", L"gamepad", L"ajoy", L"cdtvjoy", L"cd32joy", L"lightpen", 0 };
 static const TCHAR *joyaf[] = { L"none", L"normal", L"toggle", 0 };
 static const TCHAR *epsonprinter[] = { L"none", L"ascii", L"epson_matrix_9pin", L"epson_matrix_24pin", L"epson_matrix_48pin", 0 };
 static const TCHAR *aspects[] = { L"none", L"vga", L"tv", 0 };
@@ -190,7 +190,7 @@ static const TCHAR *obsolete[] = {
        L"kickstart_key_file", L"fast_copper", L"sound_adjust",
        L"serial_hardware_dtrdsr", L"gfx_filter_upscale",
        L"gfx_correct_aspect", L"gfx_autoscale", L"parallel_sampler", L"parallel_ascii_emulation",
-       L"avoid_vid", L"avoid_dga", L"z3chipmem_size",
+       L"avoid_vid", L"avoid_dga", L"z3chipmem_size", L"state_replay_buffer", L"state_replay",
        NULL
 };
 
@@ -888,9 +888,9 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
                : p->keyboard_lang == KBD_LANG_IT ? L"it"
                : L"FOO"));
 
-       cfgfile_dwrite_str (f, L"state_replay", p->statecapture ? L"yes" : L"no");
        cfgfile_dwrite (f, L"state_replay_rate", L"%d", p->statecapturerate);
-       cfgfile_dwrite (f, L"state_replay_buffer", L"%d", p->statecapturebuffersize);
+       cfgfile_dwrite (f, L"state_replay_buffers", L"%d", p->statecapturebuffersize);
+       cfgfile_dwrite_bool (f, L"state_replay_autoplay", p->inprec_autoplay);
        cfgfile_dwrite_bool (f, L"warp", p->turbo_emulation);
 
 #ifdef FILESYS
@@ -1218,7 +1218,8 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
        if (cfgfile_intval (option, value, L"sound_latency", &p->sound_latency, 1)
                || cfgfile_intval (option, value, L"sound_max_buff", &p->sound_maxbsiz, 1)
                || cfgfile_intval (option, value, L"state_replay_rate", &p->statecapturerate, 1)
-               || cfgfile_intval (option, value, L"state_replay_buffer", &p->statecapturebuffersize, 1)
+               || cfgfile_intval (option, value, L"state_replay_buffers", &p->statecapturebuffersize, 1)
+               || cfgfile_yesno (option, value, L"state_replay_autoplay", &p->inprec_autoplay)
                || cfgfile_intval (option, value, L"sound_frequency", &p->sound_freq, 1)
                || cfgfile_intval (option, value, L"sound_volume", &p->sound_volume, 1)
                || cfgfile_intval (option, value, L"sound_stereo_separation", &p->sound_stereo_separation, 1)
@@ -1284,7 +1285,6 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
                || cfgfile_yesno (option, value, L"sound_auto", &p->sound_auto)
                || cfgfile_yesno (option, value, L"sound_stereo_swap_paula", &p->sound_stereo_swap_paula)
                || cfgfile_yesno (option, value, L"sound_stereo_swap_ahi", &p->sound_stereo_swap_ahi)
-               || cfgfile_yesno (option, value, L"state_replay", &p->statecapture)
                || cfgfile_yesno (option, value, L"avoid_cmov", &p->avoid_cmov)
                || cfgfile_yesno (option, value, L"log_illegal_mem", &p->illegal_mem)
                || cfgfile_yesno (option, value, L"filesys_no_fsdb", &p->filesys_no_uaefsdb)
@@ -3604,13 +3604,13 @@ void default_prefs (struct uae_prefs *p, int type)
        p->gfx_filter = 0;
        p->gfx_filtershader[0] = 0;
        p->gfx_filtermask[0] = 0;
-       p->gfx_filter_horiz_zoom_mult = 0;
-       p->gfx_filter_vert_zoom_mult = 0;
+       p->gfx_filter_horiz_zoom_mult = 1000;
+       p->gfx_filter_vert_zoom_mult = 1000;
        p->gfx_filter_bilinear = 0;
        p->gfx_filter_filtermode = 0;
        p->gfx_filter_scanlineratio = (1 << 4) | 1;
        p->gfx_filter_keep_aspect = 0;
-       p->gfx_filter_autoscale = 0;
+       p->gfx_filter_autoscale = AUTOSCALE_STATIC_AUTO;
        p->gfx_filteroverlay_overscan = 0;
 
        _tcscpy (p->floppyslots[0].df, L"df0.adf");
@@ -3672,9 +3672,9 @@ void default_prefs (struct uae_prefs *p, int type)
        p->dfxclickvolume = 33;
        p->dfxclickchannelmask = 0xffff;
 
-       p->statecapturebuffersize = 20 * 1024 * 1024;
+       p->statecapturebuffersize = 100;
        p->statecapturerate = 5 * 50;
-       p->statecapture = 0;
+       p->inprec_autoplay = true;
 
 #ifdef UAE_MINI
        default_prefs_mini (p, 0);
@@ -4394,13 +4394,6 @@ int built_in_chipset_prefs (struct uae_prefs *p)
 
 void config_check_vsync (void)
 {
-       static int cnt = 0;
-       if (cnt == 0) {
-               /* resolution_check_change (); */
-               DISK_check_change ();
-               cnt = 5;
-       }
-       cnt--;
        if (config_changed) {
 //             if (config_changed == 1)
 //                     write_log (L"* configuration check trigger\n");
diff --git a/cia.cpp b/cia.cpp
index 03d7fcdb7c1275a1781356d93ab8325c8f49ea4f..a2b163594cb09112cf3acefef3c6389413ce3b18 100644 (file)
--- a/cia.cpp
+++ b/cia.cpp
@@ -38,6 +38,7 @@
 #include "ersatz.h"
 #include "sampler.h"
 #include "dongle.h"
+#include "inputrecord.h"
 
 #define CIAA_DEBUG_R 0
 #define CIAA_DEBUG_W 0
@@ -145,15 +146,19 @@ static void compute_passed_time (void)
 one of the timer values will be modified, and CIA_calctimers will be called
 in the same cycle.  */
 
-static void CIA_update (void)
+static int CIA_update_check (void)
 {
        unsigned long int ccount = (get_cycles () - eventtab[ev_cia].oldcycles + div10);
        unsigned long int ciaclocks = ccount / DIV10;
 
        int aovfla = 0, aovflb = 0, asp = 0, bovfla = 0, bovflb = 0, bsp = 0;
+       int icr = 0;
 
        div10 = ccount % DIV10;
 
+       if (!ciaclocks)
+               return 0;
+
        /* CIA A timers */
        if ((ciaacra & 0x21) == 0x01) {
                assert ((ciaata + 1) >= ciaclocks);
@@ -170,7 +175,8 @@ static void CIA_update (void)
        }
        if ((ciaacrb & 0x61) == 0x01) {
                assert ((ciaatb + 1) >= ciaclocks);
-               if ((ciaatb + 1) == ciaclocks) aovflb = 1;
+               if ((ciaatb + 1) == ciaclocks)
+                       aovflb = 1;
                ciaatb -= ciaclocks;
        }
 
@@ -190,38 +196,53 @@ static void CIA_update (void)
        }
        if ((ciabcrb & 0x61) == 0x01) {
                assert ((ciabtb + 1) >= ciaclocks);
-               if ((ciabtb + 1) == ciaclocks) bovflb = 1;
+               if ((ciabtb + 1) == ciaclocks)
+                       bovflb = 1;
                ciabtb -= ciaclocks;
        }
 
        if (aovfla) {
-               ciaaicr |= 1; RethinkICRA ();
+               ciaaicr |= 1; icr = 1;
                ciaata = ciaala;
-               if (ciaacra & 0x8) ciaacra &= ~1;
+               if (ciaacra & 0x8)
+                       ciaacra &= ~1;
        }
        if (aovflb) {
-               ciaaicr |= 2; RethinkICRA ();
+               ciaaicr |= 2; icr = 1;
                ciaatb = ciaalb;
-               if (ciaacrb & 0x8) ciaacrb &= ~1;
+               if (ciaacrb & 0x8)
+                       ciaacrb &= ~1;
        }
        if (asp) {
-               ciaaicr |= 8; RethinkICRA ();
+               ciaaicr |= 8; icr = 1;
        }
        if (bovfla) {
-               ciabicr |= 1; RethinkICRB ();
+               ciabicr |= 1; icr |= 2;
                ciabta = ciabla;
-               if (ciabcra & 0x8) ciabcra &= ~1;
+               if (ciabcra & 0x8)
+                       ciabcra &= ~1;
        }
        if (bovflb) {
-               ciabicr |= 2; RethinkICRB ();
+               ciabicr |= 2; icr |= 2;
                ciabtb = ciablb;
-               if (ciabcrb & 0x8) ciabcrb &= ~1;
+               if (ciabcrb & 0x8)
+                       ciabcrb &= ~1;
        }
        if (bsp) {
-               ciabicr |= 8; RethinkICRB ();
+               ciabicr |= 8; icr |= 2;
        }
+       return icr;
+}
+static void CIA_update (void)
+{
+       int icr = CIA_update_check ();
+       if (icr & 1)
+               RethinkICRA ();
+       if (icr & 2)
+               RethinkICRB ();
 }
 
+
 /* Call this only after CIA_update has been called in the same cycle.  */
 
 static void CIA_calctimers (void)
@@ -232,6 +253,7 @@ static void CIA_calctimers (void)
        if ((ciaacra & 0x21) == 0x01) {
                ciaatimea = (DIV10 - div10) + DIV10 * ciaata;
        }
+#if 0
        if ((ciaacrb & 0x61) == 0x41) {
                /* Timer B will not get any pulses if Timer A is off. */
                if (ciaatimea >= 0) {
@@ -241,12 +263,11 @@ static void CIA_calctimers (void)
                                /* Otherwise, we can determine the time of the underflow. */
                                /* This may overflow, however.  So just ignore this timer and
                                use the fact that we'll call CIA_handler for the A timer.  */
-#if 0
-                               ciaatimeb = ciaatimea + ciaala * DIV10 * ciaatb;
-#endif
+                               /* ciaatimeb = ciaatimea + ciaala * DIV10 * ciaatb; */
                        }
                }
        }
+#endif
        if ((ciaacrb & 0x61) == 0x01) {
                ciaatimeb = (DIV10 - div10) + DIV10 * ciaatb;
        }
@@ -254,6 +275,7 @@ static void CIA_calctimers (void)
        if ((ciabcra & 0x21) == 0x01) {
                ciabtimea = (DIV10 - div10) + DIV10 * ciabta;
        }
+#if 0
        if ((ciabcrb & 0x61) == 0x41) {
                /* Timer B will not get any pulses if Timer A is off. */
                if (ciabtimea >= 0) {
@@ -261,12 +283,11 @@ static void CIA_calctimers (void)
                        * one pulse, it will not underflow. */
                        if (ciabtb == 0 || (ciabcra & 0x8) == 0) {
                                /* Otherwise, we can determine the time of the underflow. */
-#if 0
-                               ciabtimeb = ciabtimea + ciabla * DIV10 * ciabtb;
-#endif
+                               /* ciabtimeb = ciabtimea + ciabla * DIV10 * ciabtb; */
                        }
                }
        }
+#endif
        if ((ciabcrb & 0x61) == 0x01) {
                ciabtimeb = (DIV10 - div10) + DIV10 * ciabtb;
        }
@@ -274,10 +295,14 @@ static void CIA_calctimers (void)
                || ciabtimea != -1 || ciabtimeb != -1);
        if (eventtab[ev_cia].active) {
                unsigned long int ciatime = ~0L;
-               if (ciaatimea != -1) ciatime = ciaatimea;
-               if (ciaatimeb != -1 && ciaatimeb < ciatime) ciatime = ciaatimeb;
-               if (ciabtimea != -1 && ciabtimea < ciatime) ciatime = ciabtimea;
-               if (ciabtimeb != -1 && ciabtimeb < ciatime) ciatime = ciabtimeb;
+               if (ciaatimea != -1)
+                       ciatime = ciaatimea;
+               if (ciaatimeb != -1 && ciaatimeb < ciatime)
+                       ciatime = ciaatimeb;
+               if (ciabtimea != -1 && ciabtimea < ciatime)
+                       ciatime = ciabtimea;
+               if (ciabtimeb != -1 && ciabtimeb < ciatime)
+                       ciatime = ciabtimeb;
                eventtab[ev_cia].evtime = ciatime + get_cycles ();
        }
        events_schedule();
@@ -333,7 +358,6 @@ STATIC_INLINE void ciaa_checkalarm (int inc)
        }
 }
 
-
 #ifdef TOD_HACK
 static uae_u64 tod_hack_tv, tod_hack_tod, tod_hack_tod_last;
 static int tod_hack_enabled;
@@ -463,8 +487,13 @@ static void resetwarning_check (void)
        }
 }
 
-void CIA_hsync_handler (int dotod)
+void CIA_hsync_prehandler (void)
 {
+}
+
+void CIA_hsync_posthandler (bool dotod)
+{
+
        if (ciabtodon && dotod) {
                ciabtod++;
                ciabtod &= 0xFFFFFF;
@@ -478,7 +507,7 @@ void CIA_hsync_handler (int dotod)
                resetwarning_check ();
                while (keys_available ())
                        get_next_key ();
-       } else if ((keys_available() || kbstate < 3) && kback && (ciaacra & 0x40) == 0 && (hsync_counter & 15) == 0) {
+       } else if ((keys_available () || kbstate < 3) && kback && (ciaacra & 0x40) == 0 && (hsync_counter & 15) == 0) {
                /*
                * This hack lets one possible ciaaicr cycle go by without any key
                * being read, for every cycle in which a key is pulled out of the
@@ -548,7 +577,7 @@ static void led_vsync (void)
        else if (led_cycles_off && !led_cycles_on)
                v = 0;
        else if (led_cycles_off)
-               v = led_cycles_on * 255 / led_cycles_off;
+               v = led_cycles_on * 255 / (led_cycles_on + led_cycles_off);
        else
                v = 255;
        if (v < 0)
@@ -567,9 +596,14 @@ static void led_vsync (void)
        led_cycle = get_cycles ();
 }
 
-void CIA_vsync_handler (int dotod)
+void CIA_vsync_prehandler (void)
 {
        led_vsync ();
+       CIA_handler ();
+}
+
+void CIA_vsync_posthandler (bool dotod)
+{
 #ifdef TOD_HACK
        if (currprefs.tod_hack && tod_hack_enabled == 1)
                return;
@@ -579,6 +613,12 @@ void CIA_vsync_handler (int dotod)
                ciaatod &= 0xFFFFFF;
                ciaa_checkalarm (1);
        }
+#if 0
+       if (vpos == 0) {
+               write_log (L"%d\n", vsync_counter);
+               dumpcia ();
+       }
+#endif
 }
 
 static void bfe001_change (void)
@@ -632,6 +672,14 @@ static uae_u8 ReadCIAA (unsigned int addr)
                if (notinrom())
                        write_log (L"BFE001 R %02X %s\n", tmp, debuginfo(0));
 #endif
+
+               if (inputrecord_debug & 2) {
+                       if (input_record > 0)
+                               inprec_recorddebug_cia (tmp, div10, m68k_getpc ());
+                       else if (input_play > 0)
+                               inprec_playdebug_cia (tmp, div10, m68k_getpc ());
+               }
+
                return tmp;
        case 1:
 #ifdef PARALLEL_PORT
@@ -1146,11 +1194,6 @@ static void WriteCIAB (uae_u16 addr, uae_u8 val)
        }
 }
 
-void CIA_inprec_prepare (void)
-{
-       sleepyhead = 0;
-}
-
 void CIA_reset (void)
 {
 #ifdef TOD_HACK
@@ -1160,9 +1203,8 @@ void CIA_reset (void)
        if (currprefs.tod_hack)
                tod_hack_enabled = 312 * 50 * 10;
 #endif
+
        kback = 1;
-       kbstate = 3;
-       ciaasdr_unread = 0;
        serbits = 0;
        oldovl = 1;
        oldcd32mute = 1;
@@ -1171,6 +1213,8 @@ void CIA_reset (void)
 
        if (!savestate_state) {
                kbstate = 0;
+               ciaasdr_unread = 0;
+               sleepyhead = 0;
                ciaatlatch = ciabtlatch = 0;
                ciaapra = 0; ciaadra = 0;
                ciaatod = ciabtod = 0; ciaatodon = ciabtodon = 0;
@@ -1183,8 +1227,9 @@ void CIA_reset (void)
                ciaasdr_cnt = 0; ciaasdr = 0;
                ciabsdr_cnt = 0; ciabsdr = 0;
                ciaata_passed = ciaatb_passed = ciabta_passed = ciabtb_passed = 0;
+               CIA_calctimers ();
+               DISK_select_set (ciabprb);
        }
-       CIA_calctimers ();
        if (ersatzkickfile)
                ersatz_chipcopy ();
        else
@@ -1199,11 +1244,9 @@ void CIA_reset (void)
                        map_overlay (1);
                        oldovl = false;
                }
-               /* select drives */
-               DISK_select (ciabprb);
        }
 #ifdef CD32
-       if (savestate_state != STATE_RESTORE && savestate_state != STATE_DORESTORE) {
+       if (!isrestore ()) {
                akiko_reset ();
                if (!akiko_init ())
                        currprefs.cs_cd32cd = changed_prefs.cs_cd32cd = 0;
@@ -1213,14 +1256,14 @@ void CIA_reset (void)
 
 void dumpcia (void)
 {
-       console_out_f (L"A: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)\n",
+       write_log (L"A: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)\n",
                ciaacra, ciaacrb, ciaaicr, ciaaimask, ciaata, ciaala, ciaatb, ciaalb);
-       console_out_f (L"TOD %06x (%06x) ALARM %06x %c%c\n",
-               ciaatod, ciaatol, ciaaalarm, ciaatlatch ? 'L' : ' ', ciaatodon ? ' ' : 'S');
-       console_out_f (L"B: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)\n",
+       write_log (L"TOD %06x (%06x) ALARM %06x %c%c CYC=%08X\n",
+               ciaatod, ciaatol, ciaaalarm, ciaatlatch ? 'L' : ' ', ciaatodon ? ' ' : 'S', get_cycles ());
+       write_log (L"B: CRA %02x CRB %02x ICR %02x IM %02x TA %04x (%04x) TB %04x (%04x)\n",
                ciabcra, ciabcrb, ciaaicr, ciabimask, ciabta, ciabla, ciabtb, ciablb);
-       console_out_f (L"TOD %06x (%06x) ALARM %06x %c%c\n",
-               ciabtod, ciabtol, ciabalarm, ciabtlatch ? 'L' : ' ', ciabtodon ? ' ' : 'S');
+       write_log (L"TOD %06x (%06x) ALARM %06x %c%c CLK=%d\n",
+               ciabtod, ciabtol, ciabalarm, ciabtlatch ? 'L' : ' ', ciabtodon ? ' ' : 'S', div10 / CYCLE_UNIT);
 }
 
 /* CIA memory access */
@@ -1241,6 +1284,8 @@ addrbank cia_bank = {
        cia_lgeti, cia_wgeti, ABFLAG_IO
 };
 
+// Gayle does not enable CIA /CS lines if both CIAs are selected
+// Non-Gayle based Amigas enable both CIAs in this situation
 
 STATIC_INLINE int isgayle (void)
 {
@@ -1255,23 +1300,40 @@ STATIC_INLINE int isgayle (void)
 
 static void cia_wait_pre (void)
 {
+       if (currprefs.cachesize)
+               return;
+
 #ifndef CUSTOM_SIMPLE
-       int div10 = (get_cycles () - eventtab[ev_cia].oldcycles) % DIV10;
+       int div = (get_cycles () - eventtab[ev_cia].oldcycles) % DIV10;
        int cycles;
 
-       if (div10 > DIV10 * ECLOCK_DATA_CYCLE / 10) {
-               cycles = DIV10 - div10;
+       if (div > DIV10 * ECLOCK_DATA_CYCLE / 10) {
+               cycles = DIV10 - div;
                cycles += DIV10 * ECLOCK_DATA_CYCLE / 10;
        } else {
-               cycles = DIV10 * ECLOCK_DATA_CYCLE / 10 - div10;
+               cycles = DIV10 * ECLOCK_DATA_CYCLE / 10 - div;
+       }
+
+       if (cycles > 0) {
+               if (currprefs.cpu_cycle_exact)
+                       x_do_cycles_pre (cycles);
+               else
+                       do_cycles (cycles);
        }
-       do_cycles (cycles);
 #endif
 }
 
-static void cia_wait_post (void)
+static void cia_wait_post (uae_u32 value)
 {
-       do_cycles (6 * CYCLE_UNIT / 2);
+       if (currprefs.cachesize) {
+               do_cycles (8 * CYCLE_UNIT /2);
+       } else {
+               int c = 6 * CYCLE_UNIT / 2;
+               if (currprefs.cpu_cycle_exact)
+                       x_do_cycles_post (c, value);
+               else
+                       do_cycles (c);
+       }
 }
 
 static uae_u32 REGPARAM2 cia_bget (uaecptr addr)
@@ -1279,6 +1341,7 @@ static uae_u32 REGPARAM2 cia_bget (uaecptr addr)
        int r = (addr & 0xf00) >> 8;
        uae_u8 v;
 
+
 #ifdef JIT
        special_mem |= S_READ;
 #endif
@@ -1304,7 +1367,8 @@ static uae_u32 REGPARAM2 cia_bget (uaecptr addr)
                }
                break;
        }
-       cia_wait_post ();
+       cia_wait_post (v);
+
        return v;
 }
 
@@ -1339,16 +1403,13 @@ static uae_u32 REGPARAM2 cia_wget (uaecptr addr)
                }
                break;
        }
-       cia_wait_post ();
+       cia_wait_post (v);
        return v;
 }
 
 static uae_u32 REGPARAM2 cia_lget (uaecptr addr)
 {
        uae_u32 v;
-#ifdef JIT
-       special_mem |= S_READ;
-#endif
        v = cia_wget (addr) << 16;
        v |= cia_wget (addr + 2);
        return v;
@@ -1357,14 +1418,14 @@ static uae_u32 REGPARAM2 cia_lget (uaecptr addr)
 static uae_u32 REGPARAM2 cia_wgeti (uaecptr addr)
 {
        if (currprefs.cpu_model >= 68020)
-               return dummy_wgeti(addr);
-       return cia_wget(addr);
+               return dummy_wgeti (addr);
+       return cia_wget (addr);
 }
 static uae_u32 REGPARAM2 cia_lgeti (uaecptr addr)
 {
        if (currprefs.cpu_model >= 68020)
-               return dummy_lgeti(addr);
-       return cia_lget(addr);
+               return dummy_lgeti (addr);
+       return cia_lget (addr);
 }
 
 static void REGPARAM2 cia_bput (uaecptr addr, uae_u32 value)
@@ -1385,7 +1446,7 @@ static void REGPARAM2 cia_bput (uaecptr addr, uae_u32 value)
                        warned--;
                }
        }
-       cia_wait_post ();
+       cia_wait_post (value);
 }
 
 static void REGPARAM2 cia_wput (uaecptr addr, uae_u32 value)
@@ -1406,14 +1467,11 @@ static void REGPARAM2 cia_wput (uaecptr addr, uae_u32 value)
                        warned--;
                }
        }
-       cia_wait_post ();
+       cia_wait_post (value);
 }
 
 static void REGPARAM2 cia_lput (uaecptr addr, uae_u32 value)
 {
-#ifdef JIT
-       special_mem |= S_WRITE;
-#endif
        cia_wput (addr, value >> 16);
        cia_wput (addr + 2, value & 0xffff);
 }
@@ -1650,6 +1708,23 @@ static void REGPARAM2 clock_bput (uaecptr addr, uae_u32 value)
 
 /* CIA-A and CIA-B save/restore code */
 
+static void save_cia_prepare (void)
+{
+       CIA_update_check ();
+       CIA_calctimers ();
+       compute_passed_time ();
+}
+
+void restore_cia_finish (void)
+{
+       eventtab[ev_cia].oldcycles = get_cycles ();
+       CIA_update ();
+       CIA_calctimers ();
+       compute_passed_time ();
+       //dumpcia ();
+       DISK_select_set (ciabprb);
+}
+
 uae_u8 *restore_cia (int num, uae_u8 *src)
 {
        uae_u8 b;
@@ -1657,47 +1732,47 @@ uae_u8 *restore_cia (int num, uae_u8 *src)
        uae_u32 l;
 
        /* CIA registers */
-       b = restore_u8 ();                                      /* 0 PRA */
+       b = restore_u8 ();                                              /* 0 PRA */
        if (num) ciabpra = b; else ciaapra = b;
-       b = restore_u8 ();                                      /* 1 PRB */
+       b = restore_u8 ();                                              /* 1 PRB */
        if (num) ciabprb = b; else ciaaprb = b;
-       b = restore_u8 ();                                      /* 2 DDRA */
+       b = restore_u8 ();                                              /* 2 DDRA */
        if (num) ciabdra = b; else ciaadra = b;
-       b = restore_u8 ();                                      /* 3 DDRB */
+       b = restore_u8 ();                                              /* 3 DDRB */
        if (num) ciabdrb = b; else ciaadrb = b;
-       w = restore_u16 ();                                     /* 4 TA */
+       w = restore_u16 ();                                             /* 4 TA */
        if (num) ciabta = w; else ciaata = w;
-       w = restore_u16 ();                                     /* 6 TB */
+       w = restore_u16 ();                                             /* 6 TB */
        if (num) ciabtb = w; else ciaatb = w;
-       l = restore_u8 ();                                      /* 8/9/A TOD */
+       l = restore_u8 ();                                              /* 8/9/A TOD */
        l |= restore_u8 () << 8;
        l |= restore_u8 () << 16;
        if (num) ciabtod = l; else ciaatod = l;
-       restore_u8 ();                                  /* B unused */
-       b = restore_u8 ();                                      /* C SDR */
+       restore_u8 ();                                                  /* B unused */
+       b = restore_u8 ();                                              /* C SDR */
        if (num) ciabsdr = b; else ciaasdr = b;
-       b = restore_u8 ();                                      /* D ICR INFORMATION (not mask!) */
+       b = restore_u8 ();                                              /* D ICR INFORMATION (not mask!) */
        if (num) ciabicr = b; else ciaaicr = b;
-       b = restore_u8 ();                                      /* E CRA */
+       b = restore_u8 ();                                              /* E CRA */
        if (num) ciabcra = b; else ciaacra = b;
-       b = restore_u8 ();                                      /* F CRB */
+       b = restore_u8 ();                                              /* F CRB */
        if (num) ciabcrb = b; else ciaacrb = b;
 
        /* CIA internal data */
 
-       b = restore_u8 ();                                      /* ICR MASK */
+       b = restore_u8 ();                                              /* ICR MASK */
        if (num) ciabimask = b; else ciaaimask = b;
-       w = restore_u8 ();                                      /* timer A latch */
+       w = restore_u8 ();                                              /* timer A latch */
        w |= restore_u8 () << 8;
        if (num) ciabla = w; else ciaala = w;
-       w = restore_u8 ();                                      /* timer B latch */
+       w = restore_u8 ();                                              /* timer B latch */
        w |= restore_u8 () << 8;
        if (num) ciablb = w; else ciaalb = w;
-       w = restore_u8 ();                                      /* TOD latched value */
+       w = restore_u8 ();                                              /* TOD latched value */
        w |= restore_u8 () << 8;
        w |= restore_u8 () << 16;
        if (num) ciabtol = w; else ciaatol = w;
-       l = restore_u8 ();                                      /* alarm */
+       l = restore_u8 ();                                              /* alarm */
        l |= restore_u8 () << 8;
        l |= restore_u8 () << 16;
        if (num) ciabalarm = l; else ciaaalarm = l;
@@ -1720,9 +1795,9 @@ uae_u8 *save_cia (int num, int *len, uae_u8 *dstptr)
        if (dstptr)
                dstbak = dst = dstptr;
        else
-               dstbak = dst = (uae_u8*)malloc (16 + 12 + 1 + 1);
+               dstbak = dst = xmalloc (uae_u8, 1000);
 
-       compute_passed_time ();
+       save_cia_prepare ();
 
        /* CIA registers */
 
@@ -1738,13 +1813,13 @@ uae_u8 *save_cia (int num, int *len, uae_u8 *dstptr)
        save_u16 (t);
        t = (num ? ciabtb - ciabtb_passed : ciaatb - ciaatb_passed);/* 6 TB */
        save_u16 (t);
-       b = (num ? ciabtod : ciaatod);                  /* 8 TODL */
+       b = (num ? ciabtod : ciaatod);                          /* 8 TODL */
        save_u8 (b);
-       b = (num ? ciabtod >> 8 : ciaatod >> 8);                /* 9 TODM */
+       b = (num ? ciabtod >> 8 : ciaatod >> 8);        /* 9 TODM */
        save_u8 (b);
-       b = (num ? ciabtod >> 16 : ciaatod >> 16);              /* A TODH */
+       b = (num ? ciabtod >> 16 : ciaatod >> 16);      /* A TODH */
        save_u8 (b);
-       save_u8 (0);                                            /* B unused */
+       save_u8 (0);                                                            /* B unused */
        b = num ? ciabsdr : ciaasdr;                            /* C SDR */
        save_u8 (b);
        b = num ? ciabicr : ciaaicr;                            /* D ICR INFORMATION (not mask!) */
@@ -1756,24 +1831,24 @@ uae_u8 *save_cia (int num, int *len, uae_u8 *dstptr)
 
        /* CIA internal data */
 
-       save_u8 (num ? ciabimask : ciaaimask);                  /* ICR */
-       b = (num ? ciabla : ciaala);                    /* timer A latch LO */
+       save_u8 (num ? ciabimask : ciaaimask);          /* ICR */
+       b = (num ? ciabla : ciaala);                            /* timer A latch LO */
        save_u8 (b);
        b = (num ? ciabla >> 8 : ciaala >> 8);          /* timer A latch HI */
        save_u8 (b);
-       b = (num ? ciablb : ciaalb);                    /* timer B latch LO */
+       b = (num ? ciablb : ciaalb);                            /* timer B latch LO */
        save_u8 (b);
        b = (num ? ciablb >> 8 : ciaalb >> 8);          /* timer B latch HI */
        save_u8 (b);
-       b = (num ? ciabtol : ciaatol);                  /* latched TOD LO */
+       b = (num ? ciabtol : ciaatol);                          /* latched TOD LO */
        save_u8 (b);
-       b = (num ? ciabtol >> 8 : ciaatol >> 8);                /* latched TOD MED */
+       b = (num ? ciabtol >> 8 : ciaatol >> 8);        /* latched TOD MED */
        save_u8 (b);
-       b = (num ? ciabtol >> 16 : ciaatol >> 16);              /* latched TOD HI */
+       b = (num ? ciabtol >> 16 : ciaatol >> 16);      /* latched TOD HI */
        save_u8 (b);
        b = (num ? ciabalarm : ciaaalarm);                      /* alarm LO */
        save_u8 (b);
-       b = (num ? ciabalarm >> 8 : ciaaalarm >> 8);    /* alarm MED */
+       b = (num ? ciabalarm >> 8 : ciaaalarm >> 8);/* alarm MED */
        save_u8 (b);
        b = (num ? ciabalarm >> 16 : ciaaalarm >> 16);  /* alarm HI */
        save_u8 (b);
@@ -1787,10 +1862,38 @@ uae_u8 *save_cia (int num, int *len, uae_u8 *dstptr)
        else
                b |= ciaatodon ? 2 : 0;   /* TOD stopped? */
        save_u8 (b);
-       save_u8 (div10 / CYCLE_UNIT);
+       save_u8 (num ? div10 / CYCLE_UNIT : 0);
        save_u8 (num ? ciabsdr_cnt : ciaasdr_cnt);
        *len = dst - dstbak;
        return dstbak;
 }
 
+uae_u8 *save_keyboard (int *len, uae_u8 *dstptr)
+{
+       uae_u8 *dst, *dstbak;
+       if (dstptr)
+               dstbak = dst = dstptr;
+       else
+               dstbak = dst = xmalloc (uae_u8, 4 + 4 + 1 + 1 + 1);
+       save_u32 (getcapslockstate () ? 1 : 0);
+       save_u32 (1);
+       save_u8 (kbstate);
+       save_u8 (ciaasdr_unread);
+       save_u8 (sleepyhead);
+       *len = dst - dstbak;
+       return dstbak;
+}
+
+uae_u8 *restore_keyboard (uae_u8 *src)
+{
+       setcapslockstate (restore_u32 () & 1);
+       uae_u32 v = restore_u32 ();
+       kbstate = restore_u8 ();
+       ciaasdr_unread = restore_u8 ();
+       sleepyhead = restore_u8 ();
+       if (!(v & 1))
+               kbstate = 3;
+       return src;
+}
+
 #endif /* SAVESTATE */
index 603bf0e8f1a3844e34088a04ed01895e5b5497f8..cdc6bb04fe538d6c9774169087f0f17310f74297 100644 (file)
@@ -401,7 +401,7 @@ static ALWAYS_INLINE bool mmu_fill_atc_l1(uaecptr addr, bool super, bool data, b
                mmu_fill_atc_l2(addr, super, data, write, l);
        }
        if (!(data ? l->valid_data : l->valid_inst)) {
-               D(bug(L"MMU: non-resident page (%x,%x,%x)!\n", addr, regs.pc, regs.fault_pc));
+               D(bug(L"MMU: non-resident page (%x,%x,%x)!\n", addr, regs.pc, regs.instruction_pc));
                goto fail;
        }
        if (write) {
index f0444c61aa5ddd8ce92fea3d30ff7044ecc53366..5c771eb4cf2b68a000d83433a51eb5eb189a3052 100644 (file)
@@ -28,6 +28,7 @@
 #include "blitter.h"
 #include "xwin.h"
 #include "inputdevice.h"
+#include "inputrecord.h"
 #include "keybuf.h"
 #include "serial.h"
 #include "autoconf.h"
@@ -122,6 +123,9 @@ unsigned long int event_cycles, nextevent, is_lastline, currcycle;
 long cycles_to_next_event;
 long max_cycles_to_next_event;
 long cycles_to_hsync_event;
+unsigned long int vsync_cycles;
+static int extra_cycle;
+unsigned long start_cycles;
 
 static int rpt_did_reset;
 struct ev eventtab[ev_max];
@@ -174,7 +178,7 @@ int maxhpos = MAXHPOS_PAL;
 int maxhpos_short = MAXHPOS_PAL;
 int maxvpos = MAXVPOS_PAL;
 int maxvpos_nom = MAXVPOS_PAL; // nominal value (same as maxvpos but "faked" maxvpos in fake 60hz modes)
-int hsyncstartpos;
+int hsyncendpos, hsyncstartpos;
 static int maxvpos_total = 511;
 int minfirstline = VBLANK_ENDLINE_PAL;
 int equ_vblank_endline = EQU_ENDLINE_PAL;
@@ -318,7 +322,7 @@ static int cop_min_waittime;
 * Statistics
 */
 unsigned long int frametime = 0, lastframetime = 0, timeframes = 0;
-unsigned long hsync_counter = 0, vsync_counter = 0, ciavsync_counter = 0;
+unsigned long hsync_counter = 0, vsync_counter = 0;
 unsigned long int idletime;
 int bogusframe;
 
@@ -1952,7 +1956,7 @@ static void record_color_change (int hpos, int regno, unsigned long value)
                        int vpos2 = autoscale_bordercolors ? minfirstline : vpos;
                        if (first_planes_vpos == 0)
                                first_planes_vpos = vpos2 - 2;
-                       if (plffirstline_total == maxvpos)
+                       if (plffirstline_total == current_maxvpos ())
                                plffirstline_total = vpos2 - 2;
                        if (vpos2 > last_planes_vpos || vpos2 > plflastline_total)
                                plflastline_total = last_planes_vpos = vpos2 + 3;
@@ -2729,14 +2733,22 @@ static void dumpsync (void)
        write_log (L"  HSSTRT=%04X VSSTRT=%04X HCENTER=%04X\n", hsstrt, vsstrt, hcenter);
 }
 
+int current_maxvpos (void)
+{
+       return maxvpos + (lof_store ? 1 : 0);
+}
+
 /* set PAL/NTSC or custom timing variables */
-void init_hz (void)
+void init_hz (bool fullinit)
 {
        int isntsc;
        int odbl = doublescan, omaxvpos = maxvpos;
        int ovblank = vblank_hz;
        int hzc = 0;
 
+       if (fullinit)
+               vpos_count = vpos_count_prev = 0;
+
        if (vsync_switchmode (-1, 0))
                currprefs.gfx_avsync = changed_prefs.gfx_avsync = vsync_switchmode (-1, 0) ? 2 : 0;
 
@@ -2818,8 +2830,13 @@ void init_hz (void)
                        hsyncstartpos = hbstrt;
                else
                        hsyncstartpos = maxhpos + hbstrt;
+               if (hbstop > maxhpos)
+                       hsyncendpos = hbstop;
+               else
+                       hsyncendpos = maxhpos + hbstop;
        } else {
                hsyncstartpos = maxhpos_short + 13;
+               hsyncendpos = 24;
        }
        eventtab[ev_hsync].oldcycles = get_cycles ();
        eventtab[ev_hsync].evtime = get_cycles () + HSYNCTIME;
@@ -2851,15 +2868,24 @@ void init_hz (void)
        if (vblank_hz != ovblank)
                updatedisplayarea ();
        inputdevice_tablet_strobe ();
-       write_log (L"%s mode%s%s V=%dHz H=%dHz (%dx%d)\n",
+       write_log (L"%s mode%s%s V=%dHz H=%dHz (%dx%d+%d)\n",
                isntsc ? L"NTSC" : L"PAL",
                (bplcon0 & 4) ? L" interlaced" : L"",
                doublescan > 0 ? L" dblscan" : L"",
                vblank_hz, vblank_hz * maxvpos_nom,
-               maxhpos, maxvpos);
+               maxhpos, maxvpos, lof_store ? 1 : 0);
        config_changed = 1;
 }
 
+void init_hz (void)
+{
+       init_hz (false);
+}
+void init_hz_full (void)
+{
+       init_hz (true);
+}
+
 static void calcdiw (void)
 {
        int hstrt = diwstrt & 0xFF;
@@ -3063,8 +3089,11 @@ static void VPOSW (uae_u16 v)
                lof_changed = 1;
                lof_store = (v & 0x8000) ? 1 : 0;
        }
-       if (currprefs.chipset_mask & CSMASK_ECS_AGNUS)
+       if (currprefs.chipset_mask & CSMASK_ECS_AGNUS) {
                lol = (v & 0x0080) ? 1 : 0;
+               if (!islinetoggle ())
+                       lol = 0;
+       }
        if (lof_changed)
                return;
        vpos &= 0x00ff;
@@ -3521,7 +3550,6 @@ static void ADKCON (int hpos, uae_u16 v)
 {
        if (currprefs.produce_sound > 0)
                update_audio ();
-
        DISK_update_adkcon (hpos, v);
        setclr (&adkcon, v);
        audio_update_adkmasks ();
@@ -4926,7 +4954,7 @@ static void init_hardware_frame (void)
        ddffirstword_total = max_diwlastword;
        ddflastword_total = 0;
        plflastline_total = 0;
-       plffirstline_total = maxvpos;
+       plffirstline_total = current_maxvpos ();
        autoscale_bordercolors = 0;
        for (i = 0; i < MAX_SPRITES; i++)
                spr[i].ptxhpos = MAXHPOS;
@@ -5047,7 +5075,44 @@ static void fpscounter (void)
        }
 }
 
-static void vsync_handler (void)
+// vsync functions that are not hardware timing related
+static void vsync_handler_pre (void)
+{
+       if (bogusframe > 0)
+               bogusframe--;
+
+       handle_events ();
+
+#ifdef PICASSO96
+       picasso_handle_vsync ();
+#endif
+       audio_vsync ();
+       blkdev_vsync ();
+       DISK_vsync ();
+       CIA_vsync_prehandler ();
+
+       if (quit_program > 0) {
+               /* prevent possible infinite loop at wait_cycles().. */
+               framecnt = 0;
+               reset_decisions ();
+               return;
+       }
+
+       config_check_vsync ();
+       if (timehack_alive > 0)
+               timehack_alive--;
+
+       inputdevice_vsync ();
+
+       filesys_vsync ();
+
+       sampler_vsync ();
+
+       vsync_handle_redraw (lof_store, lof_changed);
+}
+
+// emulated hardware vsync
+static void vsync_handler_post (void)
 {
        fpscounter ();
 
@@ -5082,11 +5147,6 @@ static void vsync_handler (void)
                framewait ();
        }
 
-       if (bogusframe > 0)
-               bogusframe--;
-
-       handle_events ();
-
 #if CUSTOM_DEBUG > 1
        if ((intreq & 0x0020) && (intena & 0x0020))
                write_log (L"vblank interrupt not cleared\n");
@@ -5095,28 +5155,11 @@ static void vsync_handler (void)
                lof_store = lof_store ? 0 : 1;
        lof_current = lof_store;
 
-#ifdef PICASSO96
-       picasso_handle_vsync ();
-#endif
-       audio_vsync ();
-       blkdev_vsync ();
-
-       if (quit_program > 0) {
-               /* prevent possible infinite loop at wait_cycles().. */
-               framecnt = 0;
-               reset_decisions ();
-               return;
-       }
-
-       config_check_vsync ();
-
        if (debug_copper)
                record_copper_reset ();
        if (debug_dma)
                record_dma_reset ();
 
-       vsync_handle_redraw (lof_store, lof_changed);
-
        if (p96refresh_active) {
                vpos_count = p96refresh_active;
                vtotal = vpos_count;
@@ -5131,14 +5174,9 @@ static void vsync_handler (void)
 
        COPJMP (1, 1);
 
-       if (timehack_alive > 0)
-               timehack_alive--;
-       inputdevice_vsync ();
-       filesys_vsync ();
-       sampler_vsync ();
-
        init_hardware_frame ();
 
+       vsync_cycles = get_cycles ();
 }
 
 #ifdef JIT
@@ -5187,27 +5225,6 @@ static void copper_check (int n)
        }
 }
 
-static void CIA_vsync_prehandler (int dotod)
-{
-       CIA_vsync_handler (dotod);
-#if 0
-       if (input_recording > 0) {
-               inprec_rstart(INPREC_CIAVSYNC);
-               inprec_ru32(ciavsync_counter);
-               inprec_rend();
-       } else if (input_recording < 0) {
-               uae_u32 v = -1;
-               while (inprec_pstart(INPREC_CIAVSYNC)) {
-                       v = inprec_pu32();
-                       inprec_pend();
-               }
-               if (v != ciavsync_counter)
-                       write_log (L"INPREC: ciavsync sync error %d <> %d\n", v, ciavsync_counter);
-       }
-#endif
-       ciavsync_counter++;
-}
-
 /*
 
 0 0 -
@@ -5298,7 +5315,7 @@ static uae_u16 dmal, dmal_hpos;
 static void dmal_emu (uae_u32 v)
 {
        // Disk and Audio DMA bits are ignored by Agnus, Agnus only checks DMAL and master bit
-       if (!(dmacon & 0x200))
+       if (!(dmacon & DMA_MASTER))
                return;
        int hpos = current_hpos ();
        if (v >= 6) {
@@ -5391,13 +5408,34 @@ static void events_dmal_hsync (void)
        events_dmal (7);
 }
 
-static void hsync_handler (void)
+static bool is_vsync (void)
+{
+       int vp = vpos + 1;
+       int vpc = vpos_count + 1;
+       /* Agnus vpos counter keeps counting until it wraps around if VPOSW writes put it past maxvpos */
+       if (vp >= maxvpos_total)
+               vp = 0;
+       if (vp == maxvpos + lof_store || vp == maxvpos + lof_store + 1 || vpc >= MAXVPOS) {
+               // vpos_count >= MAXVPOS just to not crash if VPOSW writes prevent vsync completely
+               return true;
+       }
+       return false;
+}
+
+static void set_hpos (void)
+{
+       maxhpos = maxhpos_short + lol;
+       eventtab[ev_hsync].evtime = get_cycles () + HSYNCTIME;
+       eventtab[ev_hsync].oldcycles = get_cycles ();
+}
+
+// this finishes current line
+static void hsync_handler_pre (bool isvsync)
 {
        int hpos = current_hpos ();
 
        if (!nocustom ()) {
                sync_copper_with_cpu (maxhpos, 0);
-               last_copper_hpos = 0;
                finish_decisions ();
                if (thisline_decision.plfleft != -1) {
                        if (currprefs.collision_level > 1)
@@ -5416,7 +5454,11 @@ static void hsync_handler (void)
                        hpos_lpen = lightpen_cx;
                        lightpen_triggered = 1;
                }
+               hardware_line_completed (next_lineno);
+               if (doflickerfix () && interlace_seen)
+                       hsync_scandoubler ();
        }
+
 #ifdef A2065
        a2065_hsync_handler ();
 #endif
@@ -5427,46 +5469,79 @@ static void hsync_handler (void)
        CDTV_hsync_handler ();
 #endif
        decide_blitter (-1);
-       DISK_hsync ();
 
-#ifdef CPUEMU_12
-       if (currprefs.cpu_cycle_exact || currprefs.blitter_cycle_exact) {
-               memset (cycle_line, 0, sizeof cycle_line);
-       }
+#ifdef PICASSO96
+       picasso_handle_hsync ();
 #endif
+       {
+               void ahi_hsync (void);
+               ahi_hsync ();
+       }
+
+       DISK_hsync ();
+       if (currprefs.produce_sound)
+               audio_hsync ();
+       CIA_hsync_prehandler ();
+
+       hsync_counter++;
 
        if (islinetoggle ())
                lol ^= 1;
-       if (vpos == equ_vblank_endline + 1 && lof_current != lof_store) {
-               // argh, line=0 field decision was wrong, someone did
-               // something stupid and changed LOF
-               // lof_current = lof_store;
-               // don't really know what to do here exactly without corrupt display
+       else
+               lol = 0;
+
+       vpos++;
+       vpos_count++;
+       if (vpos >= maxvpos_total)
+               vpos = 0;
+       if (isvsync) {
+               vpos = 0;
+               vsync_counter++;
        }
+       set_hpos ();
+#if 0
+       static int ppp = 1;
+       if (input_record && hsync_counter == 50 * 313 + 1) {
+               ppp--;
+               if (ppp == 0)
+                       activate_debugger ();
+       }
+#endif
+}
 
-       maxhpos = maxhpos_short + lol;
-       eventtab[ev_hsync].evtime = get_cycles () + HSYNCTIME;
-       eventtab[ev_hsync].oldcycles = get_cycles ();
+// this prepares for new line
+static void hsync_handler_post (bool isvsync)
+{
+       last_copper_hpos = 0;
+#ifdef CPUEMU_12
+       if (currprefs.cpu_cycle_exact || currprefs.blitter_cycle_exact) {
+               memset (cycle_line, 0, sizeof cycle_line);
+       }
+#endif
 
-       CIA_hsync_handler (!(bplcon0 & 2) || ((bplcon0 & 2) && currprefs.genlock));
+       bool ciasyncs = !(bplcon0 & 2) || ((bplcon0 & 2) && currprefs.genlock);
+       CIA_hsync_posthandler (ciasyncs);
        if (currprefs.cs_ciaatod > 0) {
                static int cia_hsync;
                cia_hsync -= 256;
                if (cia_hsync <= 0) {
-                       CIA_vsync_prehandler (1);
+                       CIA_vsync_posthandler (1);
                        cia_hsync += ((MAXVPOS_PAL * MAXHPOS_PAL * 50 * 256) / (maxhpos * (currprefs.cs_ciaatod == 2 ? 60 : 50)));
                }
+       } else if (currprefs.cs_ciaatod == 0 && isvsync) {
+               CIA_vsync_posthandler (ciasyncs);
        }
 
 
-#ifdef PICASSO96
-       picasso_handle_hsync ();
-#endif
-       {
-               void ahi_hsync (void);
-               ahi_hsync ();
+       if (vpos == equ_vblank_endline + 1 && lof_current != lof_store) {
+               // argh, line=0 field decision was wrong, someone did
+               // something stupid and changed LOF
+               // lof_current = lof_store;
+               // don't really know what to do here exactly without corrupt display
        }
 
+       inputdevice_hsync ();
+
        last_custom_value1 = 0xffff; // refresh slots should set this to 0xffff
 
        if (!nocustom ()) {
@@ -5475,17 +5550,9 @@ static void hsync_handler (void)
                                cycle_diagram_total_cycles[fetchmode][GET_RES_AGNUS (bplcon0)][GET_PLANES_LIMIT (bplcon0)],
                                cycle_diagram_free_cycles[fetchmode][GET_RES_AGNUS (bplcon0)][GET_PLANES_LIMIT (bplcon0)]);
                }
-               hardware_line_completed (next_lineno);
-               if (doflickerfix () && interlace_seen)
-                       hsync_scandoubler ();
        }
 
-       /* Agnus vpos counter keeps counting until it wraps around if VPOSW writes put it past maxvpos */
-       vpos++;
-       vpos_count++;
-       if (vpos >= maxvpos_total)
-               vpos = 0;
-       if (vpos == maxvpos + lof_store || vpos == maxvpos + lof_store + 1 || vpos_count >= MAXVPOS) {
+       if (isvsync) {
                // vpos_count >= MAXVPOS just to not crash if VPOSW writes prevent vsync completely
                if ((bplcon0 & 8) && !lightpen_triggered) {
                        vpos_lpen = vpos - 1;
@@ -5493,26 +5560,8 @@ static void hsync_handler (void)
                        lightpen_triggered = 1;
                }
                vpos = 0;
-               vsync_handler ();
+               vsync_handler_post ();
                vpos_count = 0;
-#if 0
-               if (input_recording > 0) {
-                       inprec_rstart (INPREC_VSYNC);
-                       inprec_ru32 (vsync_counter);
-                       inprec_rend ();
-               } else if (input_recording < 0) {
-                       uae_u32 v = -1;
-                       while (inprec_pstart(INPREC_VSYNC)) {
-                               v = inprec_pu32();
-                               inprec_pend();
-                       }
-                       if (v != vsync_counter)
-                               write_log (L"INPREC: vsync sync error %d <> %d\n", v, vsync_counter);
-               }
-#endif
-               vsync_counter++;
-               if (currprefs.cs_ciaatod == 0)
-                       CIA_vsync_prehandler (!(bplcon0 & 2) || ((bplcon0 & 2) && currprefs.genlock));
        }
        // DIP Agnus (8361): vblank interrupt is triggered on line 1!
        if (currprefs.cs_dipagnus) {
@@ -5550,9 +5599,6 @@ static void hsync_handler (void)
 #endif
 
 
-       if (currprefs.produce_sound)
-               audio_hsync ();
-
        events_dmal_hsync ();
 
 #ifdef JIT
@@ -5630,27 +5676,9 @@ static void hsync_handler (void)
        do_sprites (0);
 #endif
 
-       while (input_recording < 0 && inprec_pstart (INPREC_KEY)) {
-               record_key_direct (inprec_pu8 ());
-               inprec_pend ();
-       }
-       while (input_recording < 0 && inprec_pstart (INPREC_DISKREMOVE)) {
-               disk_eject (inprec_pu8 ());
-               inprec_pend ();
-       }
-       while (input_recording < 0 && inprec_pstart (INPREC_DISKINSERT)) {
-               int drv = inprec_pu8 ();
-               inprec_pstr (currprefs.floppyslots[drv].df);
-               _tcscpy (changed_prefs.floppyslots[drv].df, currprefs.floppyslots[drv].df);
-               disk_insert_force (drv, currprefs.floppyslots[drv].df);
-               inprec_pend ();
-       }
-
-       inputdevice_hsync ();
        gayle_hsync ();
        scsi_hsync ();
 
-       hsync_counter++;
        //copper_check (2);
 
        if (GET_PLANES (bplcon0) > 0 && dmaen (DMA_BITPLANE)) {
@@ -5658,7 +5686,7 @@ static void hsync_handler (void)
                        last_planes_vpos = vpos;
                if (vpos >= minfirstline && first_planes_vpos == 0) {
                        first_planes_vpos = vpos;
-               } else if (vpos == maxvpos - 1) {
+               } else if (vpos == current_maxvpos () - 1) {
                        last_planes_vpos = vpos - 1;
                }
        }
@@ -5706,6 +5734,20 @@ static void hsync_handler (void)
 #endif
 }
 
+static void hsync_handler (void)
+{
+       bool vs = is_vsync ();
+       hsync_handler_pre (vs);
+       if (vs) {
+               vsync_handler_pre ();
+               if (savestate_check ()) {
+                       uae_reset (0);
+                       return;
+               }
+       }
+       hsync_handler_post (vs);
+}
+
 void event2_remevent (int no)
 {
        eventtab2[no].active = 0;
@@ -5716,10 +5758,9 @@ void init_eventtab (void)
        int i;
 
        nextevent = 0;
-       set_cycles (0);
        for (i = 0; i < ev_max; i++) {
                eventtab[i].active = 0;
-               eventtab[i].oldcycles = 0;
+               eventtab[i].oldcycles = get_cycles ();
        }
        for (i = 0; i < ev2_max; i++) {
                eventtab2[i].active = 0;
@@ -5738,7 +5779,13 @@ void init_eventtab (void)
        events_schedule ();
 }
 
-void customreset (int hardreset)
+void custom_prepare (void)
+{
+       set_hpos ();
+       hsync_handler_post (true);
+}
+
+void custom_reset (int hardreset)
 {
        int i;
        int zero = 0;
@@ -5748,13 +5795,13 @@ void customreset (int hardreset)
        write_log (L"Reset at %08X\n", M68K_GETPC);
        memory_map_dump ();
 
-       hsync_counter = 0;
-       vsync_counter = 0;
-       ciavsync_counter = 0;
        lightpen_x = lightpen_y = -1;
        lightpen_triggered = 0;
        lightpen_cx = lightpen_cy = -1;
        if (!savestate_state) {
+               extra_cycle = 0;
+               hsync_counter = 0;
+               vsync_counter = 0;
                currprefs.chipset_mask = changed_prefs.chipset_mask;
                update_mirrors ();
                if (!aga_mode) {
@@ -5797,6 +5844,8 @@ void customreset (int hardreset)
                setup_fmodes (0);
                sprite_width = GET_SPRITEWIDTH (fmode);
                beamcon0 = new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20;
+               bltstate = BLT_done;
+               lof_store = lof_current = 1;
        }
 
        gayle_reset (hardreset);
@@ -5833,17 +5882,15 @@ void customreset (int hardreset)
        memset (spixels, 0, 2 * MAX_SPR_PIXELS * sizeof *spixels);
        memset (&spixstate, 0, sizeof spixstate);
 
-       bltstate = BLT_done;
        cop_state.state = COP_stop;
        diwstate = DIW_waiting_start;
-       set_cycles (0);
 
        dmal = 0;
        init_hz ();
        vpos_lpen = -1;
 
        audio_reset ();
-       if (savestate_state != STATE_RESTORE) {
+       if (!isrestore ()) {
                /* must be called after audio_reset */
                adkcon = 0;
                serial_uartbreak (0);
@@ -5859,7 +5906,7 @@ void customreset (int hardreset)
 
        bogusframe = 1;
 
-       if (savestate_state == STATE_RESTORE) {
+       if (isrestore ()) {
                uae_u16 v;
                uae_u32 vv;
 
@@ -6166,10 +6213,13 @@ static uae_u32 REGPARAM2 custom_wget (uaecptr addr)
 
 static uae_u32 REGPARAM2 custom_bget (uaecptr addr)
 {
+       uae_u32 v;
 #ifdef JIT
        special_mem |= S_READ;
 #endif
-       return custom_wget2 (addr & ~1) >> (addr & 1 ? 0 : 8);
+       v = custom_wget2 (addr & ~1);
+       v >>= (addr & 1 ? 0 : 8);
+       return v;
 }
 
 static uae_u32 REGPARAM2 custom_lget (uaecptr addr)
@@ -6486,8 +6536,8 @@ uae_u8 *restore_custom (uae_u8 *src)
        RW;                                             /* 004 VPOSR */
        RW;                                             /* 006 VHPOSR */
        RW;                                             /* 008 DSKDATR (dummy register) */
-       RW;                                             /* 00A JOY0DAT */
-       RW;                                             /* 00C JOY1DAT */
+       JOYSET(0, RW);                  /* 00A JOY0DAT */
+       JOYSET(1, RW);                  /* 00C JOY1DAT */
        clxdat = RW;                    /* 00E CLXDAT */
        RW;                                             /* 010 ADKCONR */
        RW;                                             /* 012 POT0DAT* */
@@ -6639,100 +6689,100 @@ uae_u8 *save_custom (int *len, uae_u8 *dstptr, int full)
                dstbak = dst = xmalloc (uae_u8, 8 + 256 * 2);
 
        SL (currprefs.chipset_mask);
-       SW (0);                 /* 000 BLTDDAT */
-       SW (dmacon);            /* 002 DMACONR */
-       SW (VPOSR ());          /* 004 VPOSR */
-       SW (VHPOSR ());         /* 006 VHPOSR */
-       SW (0);                 /* 008 DSKDATR */
-       SW (JOY0DAT ());                /* 00A JOY0DAT */
-       SW (JOY1DAT ());                /* 00C JOY1DAT */
+       SW (0);                                 /* 000 BLTDDAT */
+       SW (dmacon);                    /* 002 DMACONR */
+       SW (VPOSR ());                  /* 004 VPOSR */
+       SW (VHPOSR ());                 /* 006 VHPOSR */
+       SW (0);                                 /* 008 DSKDATR */
+       SW (JOYGET (0));                /* 00A JOY0DAT */
+       SW (JOYGET (1));                /* 00C JOY1DAT */
        SW (clxdat | 0x8000);   /* 00E CLXDAT */
        SW (ADKCONR ());                /* 010 ADKCONR */
        SW (POT0DAT ());                /* 012 POT0DAT */
-       SW (POT0DAT ());                /* 014 POT1DAT */
-       SW (0)  ;               /* 016 POTINP * */
-       SW (0);                 /* 018 SERDATR * */
-       SW (dskbytr);           /* 01A DSKBYTR */
+       SW (POT1DAT ());                /* 014 POT1DAT */
+       SW (0)  ;                               /* 016 POTINP * */
+       SW (0);                                 /* 018 SERDATR * */
+       SW (dskbytr);                   /* 01A DSKBYTR */
        SW (INTENAR ());                /* 01C INTENAR */
        SW (INTREQR ());                /* 01E INTREQR */
-       SL (dskpt);                     /* 020-023 DSKPT */
-       SW (dsklen);            /* 024 DSKLEN */
-       SW (0);                 /* 026 DSKDAT */
-       SW (0);                 /* 028 REFPTR */
+       SL (dskpt);                             /* 020-023 DSKPT */
+       SW (dsklen);                    /* 024 DSKLEN */
+       SW (0);                                 /* 026 DSKDAT */
+       SW (0);                                 /* 028 REFPTR */
        SW ((lof_store ? 0x8001 : 0) | (lol ? 0x0080 : 0));/* 02A VPOSW */
-       SW (0);                 /* 02C VHPOSW */
-       SW (copcon);            /* 02E COPCON */
-       SW (serper);            /* 030 SERDAT * */
-       SW (serdat);            /* 032 SERPER * */
+       SW (0);                                 /* 02C VHPOSW */
+       SW (copcon);                    /* 02E COPCON */
+       SW (serper);                    /* 030 SERDAT * */
+       SW (serdat);                    /* 032 SERPER * */
        SW (potgo_value);               /* 034 POTGO */
-       SW (0);                 /* 036 JOYTEST * */
-       SW (0);                 /* 038 STREQU */
-       SW (0);                 /* 03A STRVBL */
-       SW (0);                 /* 03C STRHOR */
-       SW (0);                 /* 03E STRLONG */
-       SW (bltcon0);           /* 040 BLTCON0 */
-       SW (bltcon1);           /* 042 BLTCON1 */
+       SW (0);                                 /* 036 JOYTEST * */
+       SW (0);                                 /* 038 STREQU */
+       SW (0);                                 /* 03A STRVBL */
+       SW (0);                                 /* 03C STRHOR */
+       SW (0);                                 /* 03E STRLONG */
+       SW (bltcon0);                   /* 040 BLTCON0 */
+       SW (bltcon1);                   /* 042 BLTCON1 */
        SW (blt_info.bltafwm);  /* 044 BLTAFWM */
        SW (blt_info.bltalwm);  /* 046 BLTALWM */
-       SL (bltcpt);            /* 048-04B BLTCPT */
-       SL (bltbpt);            /* 04C-04F BLTCPT */
-       SL (bltapt);            /* 050-053 BLTCPT */
-       SL (bltdpt);            /* 054-057 BLTCPT */
-       SW (0);                 /* 058 BLTSIZE */
-       SW (0);                 /* 05A BLTCON0L (use BLTCON0 instead) */
-       SW (blt_info.vblitsize);        /* 05C BLTSIZV */
-       SW (blt_info.hblitsize);        /* 05E BLTSIZH */
+       SL (bltcpt);                    /* 048-04B BLTCPT */
+       SL (bltbpt);                    /* 04C-04F BLTCPT */
+       SL (bltapt);                    /* 050-053 BLTCPT */
+       SL (bltdpt);                    /* 054-057 BLTCPT */
+       SW (0);                                 /* 058 BLTSIZE */
+       SW (0);                                 /* 05A BLTCON0L (use BLTCON0 instead) */
+       SW (blt_info.vblitsize);/* 05C BLTSIZV */
+       SW (blt_info.hblitsize);/* 05E BLTSIZH */
        SW (blt_info.bltcmod);  /* 060 BLTCMOD */
        SW (blt_info.bltbmod);  /* 062 BLTBMOD */
        SW (blt_info.bltamod);  /* 064 BLTAMOD */
        SW (blt_info.bltdmod);  /* 066 BLTDMOD */
-       SW (0);                 /* 068 ? */
-       SW (0);                 /* 06A ? */
-       SW (0);                 /* 06C ? */
-       SW (0);                 /* 06E ? */
+       SW (0);                                 /* 068 ? */
+       SW (0);                                 /* 06A ? */
+       SW (0);                                 /* 06C ? */
+       SW (0);                                 /* 06E ? */
        SW (blt_info.bltcdat);  /* 070 BLTCDAT */
        SW (blt_info.bltbdat);  /* 072 BLTBDAT */
        SW (blt_info.bltadat);  /* 074 BLTADAT */
-       SW (0);                 /* 076 ? */
-       SW (0);                 /* 078 ? */
-       SW (0);                 /* 07A ? */
+       SW (0);                                 /* 076 ? */
+       SW (0);                                 /* 078 ? */
+       SW (0);                                 /* 07A ? */
        SW (DENISEID ());               /* 07C DENISEID/LISAID */
-       SW (dsksync);           /* 07E DSKSYNC */
-       SL (cop1lc);            /* 080-083 COP1LC */
-       SL (cop2lc);            /* 084-087 COP2LC */
-       SW (0);                 /* 088 ? */
-       SW (0);                 /* 08A ? */
-       SW (0);                 /* 08C ? */
-       SW (diwstrt);           /* 08E DIWSTRT */
-       SW (diwstop);           /* 090 DIWSTOP */
-       SW (ddfstrt);           /* 092 DDFSTRT */
-       SW (ddfstop);           /* 094 DDFSTOP */
-       SW (dmacon);            /* 096 DMACON */
-       SW (clxcon);            /* 098 CLXCON */
-       SW (intena);            /* 09A INTENA */
-       SW (intreq);            /* 09C INTREQ */
-       SW (adkcon);            /* 09E ADKCON */
+       SW (dsksync);                   /* 07E DSKSYNC */
+       SL (cop1lc);                    /* 080-083 COP1LC */
+       SL (cop2lc);                    /* 084-087 COP2LC */
+       SW (0);                                 /* 088 ? */
+       SW (0);                                 /* 08A ? */
+       SW (0);                                 /* 08C ? */
+       SW (diwstrt);                   /* 08E DIWSTRT */
+       SW (diwstop);                   /* 090 DIWSTOP */
+       SW (ddfstrt);                   /* 092 DDFSTRT */
+       SW (ddfstop);                   /* 094 DDFSTOP */
+       SW (dmacon);                    /* 096 DMACON */
+       SW (clxcon);                    /* 098 CLXCON */
+       SW (intena);                    /* 09A INTENA */
+       SW (intreq);                    /* 09C INTREQ */
+       SW (adkcon);                    /* 09E ADKCON */
        for (i = 0; full && i < 32; i++)
                SW (0);
        for (i = 0; i < 8; i++)
                SL (bplpt[i]);          /* 0E0-0FE BPLxPT */
-       SW (bplcon0);           /* 100 BPLCON0 */
-       SW (bplcon1);           /* 102 BPLCON1 */
-       SW (bplcon2);           /* 104 BPLCON2 */
-       SW (bplcon3);           /* 106 BPLCON3 */
-       SW (bpl1mod);           /* 108 BPL1MOD */
-       SW (bpl2mod);           /* 10A BPL2MOD */
-       SW (bplcon4);           /* 10C BPLCON4 */
-       SW (clxcon2);           /* 10E CLXCON2 */
+       SW (bplcon0);                   /* 100 BPLCON0 */
+       SW (bplcon1);                   /* 102 BPLCON1 */
+       SW (bplcon2);                   /* 104 BPLCON2 */
+       SW (bplcon3);                   /* 106 BPLCON3 */
+       SW (bpl1mod);                   /* 108 BPL1MOD */
+       SW (bpl2mod);                   /* 10A BPL2MOD */
+       SW (bplcon4);                   /* 10C BPLCON4 */
+       SW (clxcon2);                   /* 10E CLXCON2 */
        for (i = 0;i < 8; i++)
                SW (bplxdat[i]);        /* 110 BPLxDAT */
        if (full) {
                for (i = 0; i < 8; i++) {
-                       SL (spr[i].pt);     /* 120-13E SPRxPT */
-                       SW (sprpos[i]);     /* 1x0 SPRxPOS */
-                       SW (sprctl[i]);     /* 1x2 SPRxPOS */
-                       SW (sprdata[i][0]);         /* 1x4 SPRxDATA */
-                       SW (sprdatb[i][0]);         /* 1x6 SPRxDATB */
+                       SL (spr[i].pt); /* 120-13E SPRxPT */
+                       SW (sprpos[i]); /* 1x0 SPRxPOS */
+                       SW (sprctl[i]); /* 1x2 SPRxPOS */
+                       SW (sprdata[i][0]);     /* 1x4 SPRxDATA */
+                       SW (sprdatb[i][0]);     /* 1x6 SPRxDATB */
                }
        }
        for ( i = 0; i < 32; i++) {
@@ -6845,7 +6895,7 @@ uae_u8 *restore_custom_sprite (int num, uae_u8 *src)
        return src;
 }
 
-uae_u8 *save_custom_sprite(int num, int *len, uae_u8 *dstptr)
+uae_u8 *save_custom_sprite (int num, int *len, uae_u8 *dstptr)
 {
        uae_u8 *dstbak, *dst;
 
@@ -6871,9 +6921,11 @@ uae_u8 *save_custom_sprite(int num, int *len, uae_u8 *dstptr)
 
 uae_u8 *restore_custom_extra (uae_u8 *src)
 {
-       restore_u32 ();
+       uae_u32 v = restore_u32 ();
 
-       currprefs.cs_compatible = changed_prefs.cs_compatible = 0;
+       if (!(v & 1))
+               v = 0;
+       currprefs.cs_compatible = changed_prefs.cs_compatible = v >> 24;
 
        currprefs.genlock = changed_prefs.genlock = RBB;
        currprefs.cs_rtc = changed_prefs.cs_rtc = RB;
@@ -6925,7 +6977,7 @@ uae_u8 *save_custom_extra (int *len, uae_u8 *dstptr)
        else
                dstbak = dst = xmalloc (uae_u8, 1000);
 
-       SL (0);
+       SL ((currprefs.cs_compatible << 24) | 1);
        SB (currprefs.genlock ? 1 : 0);
        SB (currprefs.cs_rtc);
        SL (currprefs.cs_rtc_adjust);
@@ -6968,6 +7020,83 @@ uae_u8 *save_custom_extra (int *len, uae_u8 *dstptr)
        return dstbak;
 }
 
+uae_u8 *restore_custom_event_delay (uae_u8 *src)
+{
+       if (restore_u32 () != 1)
+               return src;
+       int cnt = restore_u8 ();
+       for (int i = 0; i < cnt; i++) {
+               uae_u8 type = restore_u8 ();
+               evt e = restore_u64 ();
+               uae_u32 data = restore_u32 ();
+               if (type == 1)
+                       event2_newevent_xx (-1, e, data, send_interrupt_do);
+       }
+       return src;
+}
+uae_u8 *save_custom_event_delay (int *len, uae_u8 *dstptr)
+{
+       uae_u8 *dstbak, *dst;
+       int cnt = 0;
+
+       for (int i = ev2_misc;  i < ev2_max; i++) {
+               struct ev2 *e = &eventtab2[i];
+               if (e->active && e->handler == send_interrupt_do) {
+                       cnt++;
+               }
+       }
+       if (cnt == 0)
+               return NULL;
+
+       if (dstptr)
+               dstbak = dst = dstptr;
+       else
+               dstbak = dst = xmalloc (uae_u8, 1000);
+
+       save_u32 (1);
+       save_u8 (cnt);
+       for (int i = ev2_misc;  i < ev2_max; i++) {
+               struct ev2 *e = &eventtab2[i];
+               if (e->active && e->handler == send_interrupt_do) {
+                       save_u8 (1);
+                       save_u64 (e->evtime - get_cycles ());
+                       save_u32 (e->data);
+               
+               }
+       }
+
+       *len = dst - dstbak;
+       return dstbak;
+}
+
+
+uae_u8 *save_cycles (int *len, uae_u8 *dstptr)
+{
+       uae_u8 *dstbak, *dst;
+       if (dstptr)
+               dstbak = dst = dstptr;
+       else
+               dstbak = dst = xmalloc (uae_u8, 1000);
+       save_u32 (1);
+       save_u32 (CYCLE_UNIT);
+       save_u64 (get_cycles ());
+       save_u32 (extra_cycle);
+       write_log (L"SAVECYCLES %08X\n", get_cycles ());
+       *len = dst - dstbak;
+       return dstbak;
+}
+
+uae_u8 *restore_cycles (uae_u8 *src)
+{
+       if (restore_u32 () != 1)
+               return src;
+       restore_u32 ();
+       start_cycles = restore_u64 ();
+       extra_cycle = restore_u32 ();
+       write_log (L"RESTORECYCLES %08X\n", start_cycles);
+       return src;
+}
+
 #endif /* SAVESTATE */
 
 void check_prefs_changed_custom (void)
@@ -7032,7 +7161,7 @@ STATIC_INLINE void sync_copper (int hpos)
 
 STATIC_INLINE void decide_fetch_ce (int hpos)
 {
-       if ((ddf_change == vpos || ddf_change + 1 == vpos) && vpos < maxvpos)
+       if ((ddf_change == vpos || ddf_change + 1 == vpos) && vpos < current_maxvpos ())
                decide_fetch (hpos);
 }
 
@@ -7042,10 +7171,13 @@ STATIC_INLINE void decide_fetch_ce (int hpos)
 // at least 4 cycles (all DMA cycles count, not just blitter cycles, even
 // blitter idle cycles do count!)
 
+extern int cpu_tracer;
 STATIC_INLINE int dma_cycle (void)
 {
        int hpos, hpos_old;
 
+       if (cpu_tracer < 0)
+               return current_hpos ();
        blitter_nasty = 1;
        for (;;) {
                int bpldma;
@@ -7089,7 +7221,7 @@ uae_u32 wait_cpu_cycle_read (uaecptr addr, int mode)
        struct dma_rec *dr;
 
        hpos = dma_cycle ();
-       do_cycles_ce (CYCLE_UNIT);
+       x_do_cycles_pre (CYCLE_UNIT);
 
 #ifdef DEBUGGER
        if (debug_dma) {
@@ -7116,7 +7248,7 @@ uae_u32 wait_cpu_cycle_read (uaecptr addr, int mode)
                dr->dat = v;
 #endif
 
-       do_cycles_ce (CYCLE_UNIT);
+       x_do_cycles_post (CYCLE_UNIT, v);
        return v;
 }
 
@@ -7127,7 +7259,7 @@ uae_u32 wait_cpu_cycle_read_ce020 (uaecptr addr, int mode)
        struct dma_rec *dr;
 
        hpos = dma_cycle ();
-       do_cycles_ce (CYCLE_UNIT);
+       x_do_cycles (CYCLE_UNIT);
 
 #ifdef DEBUGGER
        if (debug_dma) {
@@ -7163,7 +7295,7 @@ void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v)
        int hpos;
 
        hpos = dma_cycle ();
-       do_cycles_ce (CYCLE_UNIT);
+       x_do_cycles_pre (CYCLE_UNIT);
 
 #ifdef DEBUGGER
        if (debug_dma) {
@@ -7185,7 +7317,7 @@ void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v)
                put_word (addr, v);
        else if (mode == 0)
                put_byte (addr, v);
-       do_cycles_ce (CYCLE_UNIT);
+       x_do_cycles_post (CYCLE_UNIT, v);
 
 }
 
@@ -7194,7 +7326,7 @@ void wait_cpu_cycle_write_ce020 (uaecptr addr, int mode, uae_u32 v)
        int hpos;
 
        hpos = dma_cycle ();
-       do_cycles_ce (CYCLE_UNIT);
+       x_do_cycles (CYCLE_UNIT);
 
 #ifdef DEBUGGER
        if (debug_dma) {
@@ -7220,12 +7352,12 @@ void wait_cpu_cycle_write_ce020 (uaecptr addr, int mode, uae_u32 v)
        regs.ce020memcycles -= CYCLE_UNIT;
 }
 
-void do_cycles_ce (long cycles)
+void do_cycles_ce (unsigned long cycles)
 {
-       static int extra_cycle;
+       unsigned long c;
 
-       cycles += extra_cycle;
-       while (cycles >= CYCLE_UNIT) {
+       c = cycles + extra_cycle;
+       while (c >= CYCLE_UNIT) {
                int hpos = current_hpos () + 1;
                sync_copper (hpos);
                decide_line (hpos);
@@ -7233,9 +7365,9 @@ void do_cycles_ce (long cycles)
                if (bltstate != BLT_done)
                        decide_blitter (hpos);
                do_cycles (1 * CYCLE_UNIT);
-               cycles -= CYCLE_UNIT;
+               c -= CYCLE_UNIT;
        }
-       extra_cycle = cycles;
+       extra_cycle = c;
 }
 
 int is_cycle_ce (void)
index cbb05e5725bfb3e5307c5ff936e31828d356a829..0053316c58728596ebb7c545be38f75bcc287673 100644 (file)
--- a/debug.cpp
+++ b/debug.cpp
@@ -900,7 +900,7 @@ struct dma_rec *record_dma (uae_u16 reg, uae_u16 dat, uae_u32 addr, int hpos, in
 static void decode_dma_record (int hpos, int vpos, int toggle)
 {
        struct dma_rec *dr;
-       int h, i, maxh;
+       int h, i, maxh, cnt;
 
        if (!dma_record[0])
                return;
@@ -911,6 +911,7 @@ static void decode_dma_record (int hpos, int vpos, int toggle)
        maxh = hpos + 80;
        if (maxh > maxhpos)
                maxh = maxhpos;
+       cnt = 0;
        while (h < maxh) {
                int col = 9;
                int cols = 8;
@@ -918,6 +919,7 @@ static void decode_dma_record (int hpos, int vpos, int toggle)
                TCHAR l2[81];
                TCHAR l3[81];
                TCHAR l4[81];
+               TCHAR l5[81];
                for (i = 0; i < cols && h < maxh; i++, h++, dr++) {
                        int cl = i * col, cl2;
                        int r = dr->reg;
@@ -975,17 +977,21 @@ static void decode_dma_record (int hpos, int vpos, int toggle)
                                l3[cl2++] = 'I';
                        if (dr->evt & DMA_EVENT_INTREQ)
                                l3[cl2++] = 'i';
+                       _stprintf (l5 + cl, L"%08X", vsync_cycles + (vpos * maxhpos + (hpos + cnt)) * CYCLE_UNIT);
                        if (i < cols - 1 && h < maxh - 1) {
                                l1[cl + col - 1] = 32;
                                l2[cl + col - 1] = 32;
                                l3[cl + col - 1] = 32;
                                l4[cl + col - 1] = 32;
+                               l5[cl + col - 1] = 32;
                        }
+                       cnt++;
                }
                console_out_f (L"%s\n", l1);
                console_out_f (L"%s\n", l2);
                console_out_f (L"%s\n", l3);
                console_out_f (L"%s\n", l4);
+               console_out_f (L"%s\n", l5);
                console_out_f (L"\n");
        }
 }
@@ -1642,6 +1648,71 @@ static void smc_detector (uaecptr addr, int rwi, int size, uae_u32 *valp)
        }
 }
 
+uae_u8 *save_debug_memwatch (int *len, uae_u8 *dstptr)
+{
+       uae_u8 *dstbak, *dst;
+       int total;
+
+       total = 0;
+       for (int i = 0; i < MEMWATCH_TOTAL; i++) {
+               if (mwnodes[i].size > 0)
+                       total++;
+       }
+       if (!total)
+               return NULL;
+
+       if (dstptr)
+               dstbak = dst = dstptr;
+       else
+               dstbak = dst = xmalloc (uae_u8, 1000);
+       save_u32 (1);
+       save_u8 (total);
+       for (int i = 0; i < MEMWATCH_TOTAL; i++) {
+               struct memwatch_node *m = &mwnodes[i];
+               if (m->size <= 0)
+                       continue;
+               save_store_pos ();
+               save_u8 (i);
+               save_u8 (m->modval_written);
+               save_u8 (m->mustchange);
+               save_u8 (m->frozen);
+               save_u8 (m->val_enabled);
+               save_u8 (m->rwi);
+               save_u32 (m->addr);
+               save_u32 (m->size);
+               save_u32 (m->modval);
+               save_u32 (m->val_mask);
+               save_u32 (m->val_size);
+               save_store_size ();
+       }
+       *len = dst - dstbak;
+       return dstbak;
+}
+
+uae_u8 *restore_debug_memwatch (uae_u8 *src)
+{
+       if (restore_u32 () != 1)
+               return src;
+       int total = restore_u8 ();
+       for (int i = 0; i < total; i++) {
+               restore_store_pos ();
+               int idx = restore_u8 ();
+               struct memwatch_node *m = &mwnodes[idx];
+               m->modval_written = restore_u8 ();
+               m->mustchange = restore_u8 ();
+               m->frozen = restore_u8 ();
+               m->val_enabled = restore_u8 ();
+               m->rwi = restore_u8 ();
+               m->addr = restore_u32 ();
+               m->size = restore_u32 ();
+               m->modval = restore_u32 ();
+               m->val_mask = restore_u32 ();
+               m->val_size = restore_u32 ();
+               restore_store_size ();
+       }
+       return src;
+}
+
 static int memwatch_func (uaecptr addr, int rwi, int size, uae_u32 *valp)
 {
        int i, brk;
@@ -2650,6 +2721,7 @@ static void searchmem (TCHAR **cc)
 
 static int staterecorder (TCHAR **cc)
 {
+#if 0
        TCHAR nc;
 
        if (!more_params (cc)) {
@@ -2664,6 +2736,7 @@ static int staterecorder (TCHAR **cc)
                savestate_listrewind ();
                return 0;
        }
+#endif
        return 0;
 }
 
@@ -2970,7 +3043,7 @@ static void m68k_modify (TCHAR **inptr)
                regs.isp = v;
        } else if (!_tcscmp (parm, L"PC")) {
                m68k_setpc (v);
-               fill_prefetch_slow ();
+               fill_prefetch ();
        } else {
                for (i = 0; m2cregs[i].regname; i++) {
                        if (!_tcscmp (parm, m2cregs[i].regname))
@@ -3148,7 +3221,7 @@ static void debug_1 (void)
                case 'g':
                        if (more_params (&inptr)) {
                                m68k_setpc (readhex (&inptr));
-                               fill_prefetch_slow ();
+                               fill_prefetch ();
                        }
                        deactivate_debugger();
                        return;
@@ -3292,19 +3365,19 @@ static void debug_1 (void)
                        break;
                case 'U':
                        if (currprefs.cpu_model && more_params (&inptr)) {
-                               int super, data, i;
+                               int i;
                                uaecptr addrl = readhex (&inptr);
                                uaecptr addrp;
                                console_out_f (L"%08X translates to:\n", addrl);
                                for (i = 0; i < 4; i++) {
-                                       super = (i & 2) ? 1 : 0;
-                                       data = (i & 1) ? 1 : 0;
+                                       bool super = (i & 2) != 0;
+                                       bool data = (i & 1) != 0;
                                        console_out_f (L"S%dD%d=", super, data);
                                        TRY(prb) {
-                                               addrp = mmu_translate (addrl, super, data, 0);
+                                               addrp = mmu_translate (addrl, super, data, false);
                                                console_out_f (L"%08X", addrp);
                                                TRY(prb2) {
-                                                       addrp = mmu_translate (addrl, super, data, 1);
+                                                       addrp = mmu_translate (addrl, super, data, true);
                                                        console_out_f (L" RW");
                                                } CATCH(prb2) {
                                                        console_out_f (L" RO");
@@ -3576,7 +3649,7 @@ void mmu_do_hit (void)
        }
        MakeSR ();
        m68k_setpc (mmu_callback);
-       fill_prefetch_slow ();
+       fill_prefetch ();
 
        if (currprefs.cpu_model > 68000) {
                for (i = 0 ; i < 9; i++) {
index d4c2830a1540febad82099038d2716153bf87ded..a552b2e8b358f1a28f874509edf861adaf3d6d11 100644 (file)
--- a/disk.cpp
+++ b/disk.cpp
 #include "sysconfig.h"
 #include "sysdeps.h"
 
+int disk_debug_logging = 0;
+int disk_debug_mode = 0;
+int disk_debug_track = -1;
+
 #include "uae.h"
 #include "options.h"
 #include "memory.h"
@@ -38,7 +42,7 @@
 #include "caps/caps_win32.h"
 #endif
 #include "crc32.h"
-#include "inputdevice.h"
+#include "inputrecord.h"
 #include "amax.h"
 #ifdef RETROPLATFORM
 #include "rp.h"
@@ -88,8 +92,8 @@ static uae_u8 writebuffer[544 * MAX_SECTORS];
 #define DISK_WORDSYNC 2
 #define DISK_REVOLUTION 4 /* 8,16,32,64 */
 
-#define DSKREADY_TIME 4
-#define DSKREADY_DOWN_TIME 10
+#define DSKREADY_UP_TIME 20
+#define DSKREADY_DOWN_TIME 50
 
 static int dskdmaen, dsklength, dsklength2, dsklen;
 static uae_u16 dskbytr_val;
@@ -102,9 +106,12 @@ static uae_u16 word, dsksync;
 static unsigned long dsksync_cycles;
 #define WORDSYNC_TIME 11
 /* Always carried through to the next line.  */
-static int disk_hpos;
+int disk_hpos;
 static int disk_jitter;
 
+static uae_u8 prev_data;
+static int prev_step;
+
 typedef enum { TRACK_AMIGADOS, TRACK_RAW, TRACK_RAW1, TRACK_PCDOS, TRACK_DISKSPARE, TRACK_NONE } image_tracktype;
 typedef struct {
        uae_u16 len;
@@ -155,13 +162,12 @@ typedef struct {
        int revolutions;
        int prevtracklen;
        int trackspeed;
-       int dmalen;
        int num_tracks, write_num_tracks, num_secs;
        int hard_num_cyls;
        bool dskchange;
        int dskchange_time;
        bool dskready;
-       int dskready_time;
+       int dskready_up_time;
        int dskready_down_time;
        int writtento;
        int steplimit;
@@ -186,10 +192,6 @@ typedef struct {
 #endif
 } drive;
 
-int disk_debug_logging;
-int disk_debug_mode;
-int disk_debug_track = -1;
-
 #define MIN_STEPLIMIT_CYCLE (CYCLE_UNIT * 250)
 
 static uae_u16 bigmfmbufw[0x4000 * DDHDMULT];
@@ -576,7 +578,7 @@ static void drive_image_free (drive *drv)
        drv->writediskfile = 0;
 }
 
-static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR *fname);
+static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR *fname, bool fake);
 
 static void reset_drive_gui (int num)
 {
@@ -614,6 +616,9 @@ static void reset_drive (int num)
        drv->amax = 0;
        drive_image_free (drv);
        drv->motoroff = 1;
+       drv->idbit = 0;
+       drv->drive_id = 0;
+       drv->drive_id_scnt = 0;
        disabled &= ~(1 << num);
        if (currprefs.floppyslots[num].dfxtype < 0)
                disabled |= 1 << num;
@@ -626,13 +631,16 @@ static void reset_drive (int num)
        if (num == 0 && currprefs.floppyslots[num].dfxtype == 0)
                drv->indexhackmode = 1;
        drv->dskchange_time = 0;
+       drv->dskchange = 0;
+       drv->dskready_down_time = 0;
+       drv->dskready_up_time = 0;
        drv->buffered_cyl = -1;
        drv->buffered_side = -1;
        gui_led (num + LED_DF0, 0);
        drive_settype_id (drv);
        _tcscpy (currprefs.floppyslots[num].df, changed_prefs.floppyslots[num].df);
        drv->newname[0] = 0;
-       if (!drive_insert (drv, &currprefs, num, currprefs.floppyslots[num].df))
+       if (!drive_insert (drv, &currprefs, num, currprefs.floppyslots[num].df, false))
                disk_eject (num);
 }
 
@@ -666,7 +674,7 @@ int DISK_validate_filename (const TCHAR *fname, int leave_open, bool *wrprot, ua
                *zf = NULL;
        if (crc32)
                *crc32 = 0;
-       if (leave_open) {
+       if (leave_open || !zf) {
                struct zfile *f = zfile_fopen (fname, L"r+b", ZFD_NORMAL | ZFD_DISKHISTORY);
                if (f) {
                        if (wrprot)
@@ -875,7 +883,7 @@ static bool diskfile_iswriteprotect (const TCHAR *fname, int *needwritefile, dri
        return wrprot1;
 }
 
-static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR *fname)
+static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR *fname, bool fake)
 {
        uae_u8 buffer[2 + 2 + 4 + 4];
        trackid *tid;
@@ -902,7 +910,7 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR
        }
 
        if (!drv->motoroff) {
-               drv->dskready_time = DSKREADY_TIME;
+               drv->dskready_up_time = DSKREADY_UP_TIME;
                drv->dskready_down_time = 0;
        }
 
@@ -911,12 +919,8 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR
                return 0;
        }
 
-       if (input_recording > 0) {
-               inprec_rstart (INPREC_DISKINSERT);
-               inprec_ru8 (dnum);
-               inprec_rstr (fname);
-               inprec_rend ();
-       }
+       if (!fake)
+               inprec_recorddiskchange (dnum, fname, drv->wrprot);
 
        _tcsncpy (currprefs.floppyslots[dnum].df, fname, 255);
        currprefs.floppyslots[dnum].df[255] = 0;
@@ -1246,7 +1250,7 @@ static void motordelay_func (uae_u32 v)
 static void drive_motor (drive * drv, bool off)
 {
        if (drv->motoroff && !off) {
-               drv->dskready_time = DSKREADY_TIME;
+               drv->dskready_up_time = DSKREADY_UP_TIME;
                rand_shifter (drv);
 #ifdef DRIVESOUND
                driveclick_motor (drv - floppy, drv->dskready_down_time == 0 ? 2 : 1);
@@ -1273,7 +1277,9 @@ static void drive_motor (drive * drv, bool off)
        drv->motoroff = off;
        if (drv->motoroff) {
                drv->dskready = 0;
-               drv->dskready_time = 0;
+               drv->dskready_up_time = 0;
+       } else {
+               drv->dskready_down_time = 0;
        }
 #ifdef CATWEASEL
        if (drv->catweasel)
@@ -2019,17 +2025,13 @@ static void drive_eject (drive * drv)
        drv->ddhd = 1;
        drv->dskchange_time = 0;
        drv->dskready = 0;
-       drv->dskready_time = 0;
+       drv->dskready_up_time = 0;
        drv->dskready_down_time = 0;
        drv->crc32 = 0;
        drive_settype_id (drv); /* Back to 35 DD */
        if (disk_debug_logging > 0)
                write_log (L"eject drive %d\n", drv - &floppy[0]);
-       if (input_recording > 0) {
-               inprec_rstart (INPREC_DISKREMOVE);
-               inprec_ru8 (drv - floppy);
-               inprec_rend ();
-       }
+       inprec_recorddiskchange (drv - floppy, NULL, false);
 }
 
 /* We use this function if we have no Kickstart ROM.
@@ -2192,8 +2194,8 @@ static void setdskchangetime (drive *drv, int dsktime)
        if (drv->dskchange_time > 0)
                return;
        for (i = 0; i < MAX_FLOPPY_DRIVES; i++) {
-               if (&floppy[i] != drv && floppy[i].dskchange_time > 0 && floppy[i].dskchange_time + 5 >= dsktime) {
-                       dsktime = floppy[i].dskchange_time + 5;
+               if (&floppy[i] != drv && floppy[i].dskchange_time > 0 && floppy[i].dskchange_time + 1 >= dsktime) {
+                       dsktime = floppy[i].dskchange_time + 1;
                }
        }
        drv->dskchange_time = dsktime;
@@ -2204,7 +2206,7 @@ static void setdskchangetime (drive *drv, int dsktime)
 void DISK_reinsert (int num)
 {
        drive_eject (&floppy[num]);
-       setdskchangetime (&floppy[num], 20);
+       setdskchangetime (&floppy[num], 100);
 }
 
 int disk_setwriteprotect (int num, const TCHAR *name, bool writeprotected)
@@ -2320,7 +2322,7 @@ static void disk_insert_2 (int num, const TCHAR *name, int forced)
        drive *drv = floppy + num;
 
        if (forced) {
-               drive_insert (drv, &currprefs, num, name);
+               drive_insert (drv, &currprefs, num, name, false);
                return;
        }
        if (!_tcscmp (currprefs.floppyslots[num].df, name))
@@ -2336,7 +2338,7 @@ static void disk_insert_2 (int num, const TCHAR *name, int forced)
                * called from DISK_check_change() after 2 second delay
                * this makes sure that all programs detect disk change correctly
                */
-               setdskchangetime (drv, 20);
+               setdskchangetime (drv, 100);
        } else {
                setdskchangetime (drv, 1);
        }
@@ -2348,20 +2350,17 @@ void disk_insert (int num, const TCHAR *name)
        target_addtorecent (name, 0);
        disk_insert_2 (num, name, 0);
 }
-void disk_insert_force (int num, const TCHAR *name)
+void disk_insert_force (int num, const TCHAR *name, bool writeprotected)
 {
        disk_insert_2 (num, name, 1);
 }
 
-void DISK_check_change (void)
+static void DISK_check_change (void)
 {
-       int i;
-
        if (currprefs.floppy_speed != changed_prefs.floppy_speed)
                currprefs.floppy_speed = changed_prefs.floppy_speed;
-       for (i = 0; i < MAX_FLOPPY_DRIVES; i++) {
+       for (int i = 0; i < MAX_FLOPPY_DRIVES; i++) {
                drive *drv = floppy + i;
-               gui_lock ();
                if (currprefs.floppyslots[i].dfxtype != changed_prefs.floppyslots[i].dfxtype) {
                        currprefs.floppyslots[i].dfxtype = changed_prefs.floppyslots[i].dfxtype;
                        reset_drive (i);
@@ -2369,22 +2368,29 @@ void DISK_check_change (void)
                        rp_floppydrive_change (i, currprefs.floppyslots[i].dfxtype >= 0 ? 1 : 0);
 #endif
                }
+       }
+}
+
+void DISK_vsync (void)
+{
+       DISK_check_change ();
+       for (int i = 0; i < MAX_FLOPPY_DRIVES; i++) {
+               drive *drv = floppy + i;
                if (drv->dskchange_time == 0 && _tcscmp (currprefs.floppyslots[i].df, changed_prefs.floppyslots[i].df))
                        disk_insert (i, changed_prefs.floppyslots[i].df);
-               gui_unlock ();
                if (drv->dskready_down_time > 0)
                        drv->dskready_down_time--;
                /* emulate drive motor turn on time */
-               if (drv->dskready_time > 0 && !drive_empty(drv)) {
-                       drv->dskready_time--;
-                       if (drv->dskready_time == 0)
-                               drv->dskready = 1;
+               if (drv->dskready_up_time > 0 && !drive_empty(drv)) {
+                       drv->dskready_up_time--;
+                       if (drv->dskready_up_time == 0 && !drv->motoroff)
+                               drv->dskready = true;
                }
                /* delay until new disk image is inserted */
                if (drv->dskchange_time) {
                        drv->dskchange_time--;
                        if (drv->dskchange_time == 0) {
-                               drive_insert (drv, &currprefs, i, drv->newname);
+                               drive_insert (drv, &currprefs, i, drv->newname, false);
                                if (disk_debug_logging > 0)
                                        write_log (L"delayed insert, drive %d, image '%s'\n", i, drv->newname);
                                update_drive_gui (i);
@@ -2409,11 +2415,15 @@ static TCHAR *tobin (uae_u8 v)
        return buf;
 }
 
+void DISK_select_set (uae_u8 data)
+{
+       prev_data = data;
+       prev_step = 0;
+}
+
 void DISK_select (uae_u8 data)
 {
        int step_pulse, prev_selected, dr;
-       static uae_u8 prev_data;
-       static int prev_step;
 
        prev_selected = selected;
 
@@ -2590,18 +2600,21 @@ void dumpdisk (void)
                        console_out_f (L"Drive %d: motor %s cylinder %2d sel %s %s mfmpos %d/%d\n",
                                i, drv->motoroff ? L"off" : L" on", drv->cyl, (selected & (1 << i)) ? L"no" : L"yes",
                                drive_writeprotected(drv) ? L"ro" : L"rw", drv->mfmpos, drv->tracklen);
-                       w = word;
-                       for (j = 0; j < 15; j++) {
-                               console_out_f (L"%04X ", w);
-                               for (k = 0; k < 16; k++) {
-                                       w <<= 1;
-                                       w |= getonebit (drv->bigmfmbuf, drv->mfmpos + j * 16 + k);
+                       if (drv->motoroff == 0) {
+                               w = word;
+                               for (j = 0; j < 15; j++) {
+                                       console_out_f (L"%04X ", w);
+                                       for (k = 0; k < 16; k++) {
+                                               w <<= 1;
+                                               w |= getonebit (drv->bigmfmbuf, drv->mfmpos + j * 16 + k);
+                                       }
                                }
+                               console_out (L"\n");
                        }
-                       console_out (L"\n");
                }
        }
-       console_out_f (L"side %d, dma %d, bitoffset %d, word %04X, dskbytr %04X adkcon %04X dsksync %04X\n", side, dskdmaen, bitoffset, word, dskbytr_val, adkcon, dsksync);
+       console_out_f (L"side %d dma %d off %d word %04X pt %08X len %04X bytr %04X adk %04X sync %04X\n",
+               side, dskdmaen, bitoffset, word, dskpt, dsklen, dskbytr_val, adkcon, dsksync);
 }
 
 static void disk_dmafinished (void)
@@ -2776,7 +2789,7 @@ static void disk_doupdate_predict (int startcycle)
                                tword <<= 1;
                                if (!drive_empty (drv)) {
                                        if (unformatted (drv))
-                                               tword |= (uaerand() & 0x1000) ? 1 : 0;
+                                               tword |= (uaerand () & 0x1000) ? 1 : 0;
                                        else
                                                tword |= getonebit (drv->bigmfmbuf, mfmpos);
                                }
@@ -2857,7 +2870,7 @@ static void disk_doupdate_read_nothing (int floppybits)
 {
        int j = 0, k = 1, l = 0;
 
-       while (floppybits >= get_floppy_speed()) {
+       while (floppybits >= get_floppy_speed ()) {
                word <<= 1;
                doreaddma ();
                if ((bitoffset & 7) == 7) {
@@ -2866,7 +2879,7 @@ static void disk_doupdate_read_nothing (int floppybits)
                }
                bitoffset++;
                bitoffset &= 15;
-               floppybits -= get_floppy_speed();
+               floppybits -= get_floppy_speed ();
        }
 }
 
@@ -2898,7 +2911,7 @@ static void disk_doupdate_read (drive * drv, int floppybits)
                word <<= 1;
                if (!drive_empty (drv)) {
                        if (unformatted (drv))
-                               word |= (uaerand() & 0x1000) ? 1 : 0;
+                               word |= (uaerand () & 0x1000) ? 1 : 0;
                        else
                                word |= getonebit (drv->bigmfmbuf, drv->mfmpos);
                }
@@ -2933,6 +2946,7 @@ static void disk_doupdate_read (drive * drv, int floppybits)
                bitoffset++;
                bitoffset &= 15;
                floppybits -= drv->trackspeed;
+
        }
 }
 
@@ -2983,7 +2997,7 @@ static void DISK_start (void)
        int dr;
 
        for (int i = 0; i < 3; i++)
-               fifo_inuse[0] = 0;
+               fifo_inuse[i] = false;
        fifo_filled = 0;
        for (dr = 0; dr < MAX_FLOPPY_DRIVES; dr++) {
                drive *drv = &floppy[dr];
@@ -2999,8 +3013,10 @@ static void DISK_start (void)
                        }
                        /* Ugh.  A nasty hack.  Assume ADF_EXT1 tracks are always read
                        from the start.  */
-                       if (ti->type == TRACK_RAW1)
+                       if (ti->type == TRACK_RAW1) {
                                drv->mfmpos = 0;
+                               bitoffset = 0;
+                       }
                        if (drv->catweasel)
                                drive_fill_bigbuf (drv, 1);
                }
@@ -3034,6 +3050,11 @@ void DISK_update (int tohpos)
        int cycles;
        int startcycle = disk_hpos;
 
+       if (disk_hpos < 0) {
+               disk_hpos = - disk_hpos;
+               return;
+       }
+
        cycles = (tohpos << 8) - disk_hpos;
 #if 0
        if (tohpos == 228)
@@ -3074,6 +3095,7 @@ void DISK_update (int tohpos)
                        disk_doupdate_write (drv, drv->floppybitcounter);
                else
                        disk_doupdate_read (drv, drv->floppybitcounter);
+
                drv->floppybitcounter %= drv->trackspeed;
                didaccess = 1;
        }
@@ -3383,7 +3405,7 @@ void DISK_init (void)
                drive *drv = &floppy[dr];
                /* reset all drive types to 3.5 DD */
                drive_settype_id (drv);
-               if (!drive_insert (drv, &currprefs, dr, currprefs.floppyslots[dr].df))
+               if (!drive_insert (drv, &currprefs, dr, currprefs.floppyslots[dr].df, false))
                        disk_eject (dr);
        }
        if (disk_empty (0))
@@ -3420,7 +3442,7 @@ int DISK_examine_image (struct uae_prefs *p, int num, uae_u32 *crc32)
        drv->cyl = 0;
        side = 0;
        *crc32 = 0;
-       if (!drive_insert (drv, p, num, p->floppyslots[num].df))
+       if (!drive_insert (drv, p, num, p->floppyslots[num].df, true))
                return 1;
        if (!drv->diskfile)
                return 1;
@@ -3481,7 +3503,7 @@ void DISK_save_custom (uae_u32 *pdskpt, uae_u16 *pdsklength, uae_u16 *pdsksync,
        if (pdskpt)
                *pdskpt = dskpt;
        if (pdsklength)
-               *pdsklength = dsklength;
+               *pdsklength = dsklen;
        if (pdsksync)
                *pdsksync = dsksync;
        if (pdskbytr)
@@ -3490,18 +3512,41 @@ void DISK_save_custom (uae_u32 *pdskpt, uae_u16 *pdsklength, uae_u16 *pdsksync,
 
 #endif /* SAVESTATE || DEBUGGER */
 
+static uae_u32 getadfcrc (drive *drv)
+{
+       uae_u8 *b;
+       uae_u32 crc32;
+       int size;
+
+       if (!drv->diskfile)
+               return 0;
+       zfile_fseek (drv->diskfile, 0, SEEK_END);
+       size = zfile_ftell (drv->diskfile);
+       b = xmalloc (uae_u8, size);
+       if (!b)
+               return 0;
+       zfile_fseek (drv->diskfile, 0, SEEK_SET);
+       zfile_fread (b, 1, size, drv->diskfile);
+       crc32 = get_crc32 (b, size);
+       free (b);
+       return crc32;
+}
+
 #ifdef SAVESTATE
 
 void DISK_restore_custom (uae_u32 pdskpt, uae_u16 pdsklength, uae_u16 pdskbytr)
 {
        dskpt = pdskpt;
-       dsklength = pdsklength;
+       dsklen = pdsklength;
        dskbytr_val = pdskbytr;
 }
 
 void restore_disk_finish (void)
 {
-       setamax();
+       DISK_check_change ();
+       setamax ();
+       if (dskdmaen)
+               dumpdisk ();
 }
 
 uae_u8 *restore_disk (int num,uae_u8 *src)
@@ -3542,6 +3587,8 @@ uae_u8 *restore_disk (int num,uae_u8 *src)
                }
                changed_prefs.floppyslots[num].dfxtype = dfxtype;
        }
+       drv->dskchange = (state & 8) ? 1 : 0;
+       side = (state & 16) ? 1 : 0;
        drv->indexhackmode = 0;
        if (num == 0 && currprefs.floppyslots[num].dfxtype == 0)
                drv->indexhackmode = 1;
@@ -3550,8 +3597,7 @@ uae_u8 *restore_disk (int num,uae_u8 *src)
        drv->cyl = restore_u8 ();
        drv->dskready = restore_u8 () != 0;
        drv->drive_id_scnt = restore_u8 ();
-       drv->mfmpos = restore_u32 ();
-       drv->dskchange = 0;
+       int mfmpos = restore_u32 ();
        drv->dskchange_time = 0;
        restore_u32 ();
        s = restore_string ();
@@ -3560,62 +3606,105 @@ uae_u8 *restore_disk (int num,uae_u8 *src)
        xfree (s);
        newis = changed_prefs.floppyslots[num].df[0] ? 1 : 0;
        if (!(disabled & (1 << num))) {
-               if (!newis) {
-                       drv->dskchange = 1;
-               } else {
-                       drive_insert (floppy + num, &currprefs, num, changed_prefs.floppyslots[num].df);
+               if (!newis && old[0]) {
+                       *currprefs.floppyslots[num].df = *changed_prefs.floppyslots[num].df = 0;
+                       drv->dskchange = 0;
+               } else if (newis) {
+                       drive_insert (floppy + num, &currprefs, num, changed_prefs.floppyslots[num].df, false);
                        if (drive_empty (floppy + num)) {
                                if (newis && old[0]) {
                                        _tcscpy (changed_prefs.floppyslots[num].df, old);
-                                       drive_insert (floppy + num, &currprefs, num, changed_prefs.floppyslots[num].df);
+                                       drive_insert (floppy + num, &currprefs, num, changed_prefs.floppyslots[num].df, false);
                                        if (drive_empty (floppy + num))
                                                drv->dskchange = 1;
                                }
                        }
                }
        }
+       drv->mfmpos = mfmpos;
+       drv->prevtracklen = drv->tracklen;
        reset_drive_gui (num);
        return src;
 }
 
-static uae_u32 getadfcrc (drive *drv)
+uae_u8 *restore_disk2 (int num,uae_u8 *src)
 {
-       uae_u8 *b;
-       uae_u32 crc32;
-       int size;
-
-       if (!drv->diskfile)
-               return 0;
-       zfile_fseek (drv->diskfile, 0, SEEK_END);
-       size = zfile_ftell (drv->diskfile);
-       b = xmalloc (uae_u8, size);
-       if (!b)
-               return 0;
-       zfile_fseek (drv->diskfile, 0, SEEK_SET);
-       zfile_fread (b, 1, size, drv->diskfile);
-       crc32 = get_crc32 (b, size);
-       free (b);
-       return crc32;
+       drive *drv = &floppy[num];
+       uae_u32 m = restore_u32 ();
+       if (m) {
+               drv->floppybitcounter = restore_u16 ();
+               drv->tracklen = restore_u32 ();
+               drv->trackspeed = restore_u16 ();
+               drv->skipoffset = restore_u32 ();
+               drv->indexoffset = restore_u32 ();
+               drv->buffered_cyl = drv->cyl;
+               drv->buffered_side = side;
+               for (int j = 0; j < (drv->tracklen + 15) / 16; j++) {
+                       drv->bigmfmbuf[j] = restore_u16 ();
+                       if (m & 2)
+                               drv->tracktiming[j] = restore_u16 ();
+               }
+               drv->dskready_up_time = restore_u16 ();
+               drv->dskready_down_time = restore_u16 ();
+       }
+       return src;
 }
 
-uae_u8 *save_disk (int num, int *len, uae_u8 *dstptr)
+uae_u8 *save_disk (int num, int *len, uae_u8 *dstptr, bool usepath)
 {
        uae_u8 *dstbak,*dst;
-       drive *drv;
+       drive *drv = &floppy[num];
 
-       drv = &floppy[num];
        if (dstptr)
                dstbak = dst = dstptr;
        else
-               dstbak = dst = xmalloc (uae_u8, 2+1+1+1+1+4+4+256);
+               dstbak = dst = xmalloc (uae_u8, 2 + 1 + 1 + 1 + 1 + 4 + 4 + 256);
        save_u32 (drv->drive_id);           /* drive type ID */
-       save_u8 ((drv->motoroff ? 0:1) | ((disabled & (1 << num)) ? 2 : 0) | (drv->idbit ? 4 : 0) | (drv->dskchange ? 8 : 0));
-       save_u8 (drv->cyl);                 /* cylinder */
+       save_u8 ((drv->motoroff ? 0 : 1) | ((disabled & (1 << num)) ? 2 : 0) | (drv->idbit ? 4 : 0) | (drv->dskchange ? 8 : 0) | (side ? 16 : 0));
+       save_u8 (drv->cyl);                             /* cylinder */
        save_u8 (drv->dskready);            /* dskready */
        save_u8 (drv->drive_id_scnt);   /* id mode position */
-       save_u32 (drv->mfmpos);     /* disk position */
+       save_u32 (drv->mfmpos);                 /* disk position */
        save_u32 (getadfcrc (drv));         /* CRC of disk image */
-       save_string (currprefs.floppyslots[num].df);/* image name */
+       save_string (usepath ? currprefs.floppyslots[num].df : L"");/* image name */
+       *len = dst - dstbak;
+       return dstbak;
+}
+
+uae_u8 *save_disk2 (int num, int *len, uae_u8 *dstptr)
+{
+       uae_u8 *dstbak,*dst;
+       drive *drv = &floppy[num];
+
+       int m = 0;
+       int size = 0;
+       if (drv->motoroff == 0 && drv->buffered_side >= 0 && drv->tracklen > 0) {
+               m = 1;
+               if (drv->tracktiming[0])
+                       m |= 2;
+               size += ((drv->tracklen + 15) * 2) / 8;
+       }
+       if (!m)
+               return NULL;
+
+       if (dstptr)
+               dstbak = dst = dstptr;
+       else
+               dstbak = dst = xmalloc (uae_u8, 2 + 4 + 2 + 4 + 4 + size);
+
+       save_u32 (m);
+       save_u16 (drv->floppybitcounter);
+       save_u32 (drv->tracklen);
+       save_u16 (drv->trackspeed);
+       save_u32 (drv->skipoffset);
+       save_u32 (drv->indexoffset);
+       for (int j = 0; j < (drv->tracklen + 15) / 16; j++) {
+               save_u16 (drv->bigmfmbuf[j]);
+               if (drv->tracktiming[0])
+                       save_u16 (drv->tracktiming[j]);
+       }
+       save_u16 (drv->dskready_up_time);
+       save_u16 (drv->dskready_down_time);
 
        *len = dst - dstbak;
        return dstbak;
@@ -3628,39 +3717,38 @@ uae_u8 *restore_floppy (uae_u8 *src)
        word = restore_u16 ();
        bitoffset = restore_u8 ();
        dma_enable = restore_u8 ();
-       disk_hpos = restore_u8 () << 8;
+       disk_hpos = restore_u8 () & 0xff;
        dskdmaen = restore_u8 ();
        for (int i = 0; i < 3; i++) {
                fifo[i] = restore_u16 ();
-               fifo_inuse[i] = restore_u8 () != 0;
+               fifo_inuse[i] = restore_u8 ();
                if (dskdmaen == 0)
                        fifo_inuse[i] = false;
        }
+       fifo_filled = fifo_inuse[0] || fifo_inuse[1] || fifo_inuse[2];
+       dsklength = restore_u16 ();
        return src;
 }
 
-uae_u8 *save_floppy(int *len, uae_u8 *dstptr)
+uae_u8 *save_floppy (int *len, uae_u8 *dstptr)
 {
        uae_u8 *dstbak, *dst;
 
-       /* flush dma buffer before saving */
-#if 0
-       dodmafetch();
-#endif
        if (dstptr)
                dstbak = dst = dstptr;
        else
                dstbak = dst = xmalloc (uae_u8, 100);
+
        save_u16 (word);                        /* shift register */
        save_u8 (bitoffset);            /* dma bit offset */
        save_u8 (dma_enable);           /* disk sync found */
-       save_u8 (disk_hpos >> 8);       /* next bit read position */
+       save_u8 (disk_hpos & 0xff);     /* next bit read position */
        save_u8 (dskdmaen);                     /* dma status */
        for (int i = 0; i < 3; i++) {
                save_u16 (fifo[i]);
-               save_u8 (fifo_inuse[i] ? 1 : 0);
+               save_u8 (fifo_inuse[i]);
        }
-
+       save_u16 (dsklength);
        *len = dst - dstbak;
        return dstbak;
 }
@@ -3838,3 +3926,7 @@ int disk_prevnext (int drive, int dir)
 }
 
 
+int getdebug(void)
+{
+       return floppy[0].mfmpos;
+}
\ No newline at end of file
index ca65de573695edfed84060bd0b27b2fcd0434ef6..d414cbb2e315993bb9aa5886acb8c45fee12609d 100644 (file)
@@ -97,7 +97,7 @@ static int dblpf_ind1[256], dblpf_ind2[256];
 
 static int dblpf_2nd1[256], dblpf_2nd2[256];
 
-static int dblpfofs[] = { 0, 2, 4, 8, 16, 32, 64, 128 };
+static const int dblpfofs[] = { 0, 2, 4, 8, 16, 32, 64, 128 };
 
 static int sprite_offs[256];
 
@@ -212,7 +212,7 @@ static int bplres;
 static int plf1pri, plf2pri, bplxor;
 static uae_u32 plf_sprite_mask;
 static int sbasecol[2] = { 16, 16 };
-static int brdsprt, brdblank, brdblank_changed, hposendblank;
+static int brdsprt, brdblank, brdblank_changed, hposblank;
 
 bool picasso_requested_on;
 bool picasso_on;
@@ -677,10 +677,10 @@ STATIC_INLINE uae_u32 merge_2pixel32 (uae_u32 p1, uae_u32 p2)
 STATIC_INLINE xcolnr getbgc (void)
 {
 #if 0
-       if (hposendblank)
+       if (hposblank)
                return xcolors[0xf00];
 #endif
-       return (brdblank || hposendblank) ? 0 : colors_for_drawing.acolors[0];
+       return (brdblank || hposblank) ? 0 : colors_for_drawing.acolors[0];
 }
 
 static void fill_line_16 (uae_u8 *buf, unsigned int start, unsigned int stop)
@@ -773,11 +773,11 @@ STATIC_INLINE void fill_line2 (int startpos, int len)
 static void fill_line (void)
 {
        int hs = coord_hw_to_window_x (hsyncstartpos * 2);
-       if (hs > visible_left_border + gfxvidinfo.width || hposendblank) {
+       if (hs >= gfxvidinfo.width || hposblank) {
                fill_line2 (visible_left_border, gfxvidinfo.width);
        } else {
                fill_line2 (visible_left_border, hs);
-               hposendblank = 1;
+               hposblank = 1;
                fill_line2 (visible_left_border + hs, gfxvidinfo.width - hs);
        }
 }
@@ -1811,8 +1811,8 @@ static void pfield_expand_dp_bplcon (void)
        ecsshres = bplres == RES_SUPERHIRES && (currprefs.chipset_mask & CSMASK_ECS_DENISE) && !(currprefs.chipset_mask & CSMASK_AGA);
 #endif
 
-       if (bplres > 0)
-               frame_res = 1;
+       if (bplres > frame_res)
+               frame_res = bplres;
        if (bplres > 0)
                can_use_lores = 0;
 
@@ -1861,7 +1861,7 @@ static bool isham (uae_u16 bplcon0)
 static void pfield_expand_dp_bplconx (int regno, int v)
 {
        if (regno == 0xffff) {
-               hposendblank = 1;
+               hposblank = 1;
                return;
        }
        regno -= 0x1000;
@@ -2146,11 +2146,11 @@ static void pfield_draw_line (int lineno, int gfx_ypos, int follow_ypos)
 
        } else {
 
-               int tmp = hposendblank;
-               hposendblank = 1;
+               int tmp = hposblank;
+               hposblank = 1;
                fill_line ();
                do_flush_line (gfx_ypos);
-               hposendblank = tmp;
+               hposblank = tmp;
 
        }
 }
@@ -2187,7 +2187,7 @@ static void center_image (void)
                visible_left_border = max_diwlastword - gfxvidinfo.width;
        }
 
-       if (currprefs.gfx_xcenter_pos >= 0) {
+       if (currprefs.gfx_xcenter_pos >= 0 && !currprefs.gfx_filter_autoscale) {
                int val = currprefs.gfx_xcenter_pos >> RES_MAX;
 #if 0
                if (currprefs.gfx_xcenter_size > 0) {
@@ -2230,7 +2230,7 @@ static void center_image (void)
                                thisframe_y_adjust = prev_y_adjust;
                }
        }
-       if (currprefs.gfx_ycenter_pos >= 0) {
+       if (currprefs.gfx_ycenter_pos >= 0 && !currprefs.gfx_filter_autoscale) {
                thisframe_y_adjust = currprefs.gfx_ycenter_pos >> 1;
 #if 0
                if (currprefs.gfx_ycenter_size > 0) {
@@ -2267,7 +2267,7 @@ static void center_image (void)
        min_diwstart = 10000;
 }
 
-#define FRAMES_UNTIL_RES_SWITCH 5
+#define FRAMES_UNTIL_RES_SWITCH 1
 static int frame_res_cnt;
 static void init_drawing_frame (void)
 {
@@ -2275,44 +2275,45 @@ static void init_drawing_frame (void)
 #if 1
        static int frame_res_old;
 
-       if (FRAMES_UNTIL_RES_SWITCH > 0 && frame_res_old == frame_res * 2 + frame_res_lace) {
-               frame_res_cnt--;
-               if (frame_res_cnt == 0) {
-                       int ar = currprefs.gfx_autoresolution;
-                       int m = frame_res * 2 + frame_res_lace;
-                       struct wh *dst = currprefs.gfx_afullscreen ? &changed_prefs.gfx_size_fs : &changed_prefs.gfx_size_win;
-                       while (m < 4) {
-                               struct wh *src = currprefs.gfx_afullscreen ? &currprefs.gfx_size_fs_xtra[m] : &currprefs.gfx_size_win_xtra[m];
-                               if ((src->width > 0 && src->height > 0) || (ar && currprefs.gfx_filter > 0)) {
-                                       int nr = (m & 2) == 0 ? 0 : 1;
-                                       int nl = (m & 1) == 0 ? 0 : 1;
-                                       if (changed_prefs.gfx_resolution != nr || changed_prefs.gfx_vresolution != nl) {
-                                               changed_prefs.gfx_resolution = nr;
-                                               changed_prefs.gfx_vresolution = nl;
-                                               write_log (L"RES -> %d LINE -> %d\n", nr, nl);
-                                               config_changed = 1;
-                                               if (ar) {
-                                                       changed_prefs.gfx_filter_horiz_zoom_mult = (nr + 1) * 500;
-                                                       changed_prefs.gfx_filter_vert_zoom_mult = (nl + 1) * 500;
-                                               }
-                                       }
-                                       if (src->width > 0 && src->height > 0) {
-                                               if (memcmp (dst, src, sizeof *dst)) {
-                                                       *dst = *src;
+       if (currprefs.gfx_autoresolution && frame_res >= 0 && frame_res_lace >= 0) {
+               if (FRAMES_UNTIL_RES_SWITCH > 0 && frame_res_old == frame_res * 2 + frame_res_lace) {
+                       frame_res_cnt--;
+                       if (frame_res_cnt == 0) {
+                               int m = frame_res * 2 + frame_res_lace;
+                               struct wh *dst = currprefs.gfx_afullscreen ? &changed_prefs.gfx_size_fs : &changed_prefs.gfx_size_win;
+                               while (m < 6) {
+                                       struct wh *src = currprefs.gfx_afullscreen ? &currprefs.gfx_size_fs_xtra[m] : &currprefs.gfx_size_win_xtra[m];
+                                       if ((src->width > 0 && src->height > 0) || (currprefs.gfx_api || currprefs.gfx_filter > 0)) {
+                                               int nr = m >> 1;
+                                               int nl = (m & 1) == 0 ? 0 : 1;
+                                               if (nr > gfxvidinfo.gfx_resolution_reserved)
+                                                       nr = gfxvidinfo.gfx_resolution_reserved;
+                                               if (nl > gfxvidinfo.gfx_vresolution_reserved)
+                                                       nl = gfxvidinfo.gfx_vresolution_reserved;
+                                               if (changed_prefs.gfx_resolution != nr || changed_prefs.gfx_vresolution != nl) {
+                                                       changed_prefs.gfx_resolution = nr;
+                                                       changed_prefs.gfx_vresolution = nl;
+                                                       write_log (L"RES -> %d LINE -> %d\n", nr, nl);
                                                        config_changed = 1;
                                                }
+                                               if (src->width > 0 && src->height > 0) {
+                                                       if (memcmp (dst, src, sizeof *dst)) {
+                                                               *dst = *src;
+                                                               config_changed = 1;
+                                                       }
+                                               }
+                                               break;
                                        }
-                                       break;
+                                       m++;
                                }
-                               m++;
+                               frame_res_cnt = FRAMES_UNTIL_RES_SWITCH;
                        }
+               } else {
+                       frame_res_old = frame_res * 2 + frame_res_lace;
                        frame_res_cnt = FRAMES_UNTIL_RES_SWITCH;
                }
-       } else {
-               frame_res_old = frame_res * 2 + frame_res_lace;
-               frame_res_cnt = FRAMES_UNTIL_RES_SWITCH;
        }
-       frame_res = 0;
+       frame_res = -1;
        frame_res_lace = 0;
 
        if (can_use_lores > AUTO_LORES_FRAMES && 0) {
@@ -2364,21 +2365,7 @@ static void init_drawing_frame (void)
        seen_sprites = -1;
 }
 
-/*
-* Some code to put status information on the screen.
-*/
-
-static const char *numbers = { /* ugly  0123456789CHD%+- */
-       "+++++++--++++-+++++++++++++++++-++++++++++++++++++++++++++++++++++++++++++++-++++++-++++----++---+--------------"
-       "+xxxxx+--+xx+-+xxxxx++xxxxx++x+-+x++xxxxx++xxxxx++xxxxx++xxxxx++xxxxx++xxxx+-+x++x+-+xxx++-+xx+-+x---+----------"
-       "+x+++x+--++x+-+++++x++++++x++x+++x++x++++++x++++++++++x++x+++x++x+++x++x++++-+x++x+-+x++x+--+x++x+--+x+----+++--"
-       "+x+-+x+---+x+-+xxxxx++xxxxx++xxxxx++xxxxx++xxxxx+--++x+-+xxxxx++xxxxx++x+----+xxxx+-+x++x+----+x+--+xxx+--+xxx+-"
-       "+x+++x+---+x+-+x++++++++++x++++++x++++++x++x+++x+--+x+--+x+++x++++++x++x++++-+x++x+-+x++x+---+x+x+--+x+----+++--"
-       "+xxxxx+---+x+-+xxxxx++xxxxx+----+x++xxxxx++xxxxx+--+x+--+xxxxx++xxxxx++xxxx+-+x++x+-+xxx+---+x++xx--------------"
-       "+++++++---+++-++++++++++++++----+++++++++++++++++--+++--++++++++++++++++++++-++++++-++++------------------------"
-};
-
-STATIC_INLINE void putpixel (uae_u8 *buf, int bpp, int x, xcolnr c8, int opaq)
+void putpixel (uae_u8 *buf, int bpp, int x, xcolnr c8, int opaq)
 {
        if (x <= 0)
                return;
@@ -2417,192 +2404,6 @@ STATIC_INLINE void putpixel (uae_u8 *buf, int bpp, int x, xcolnr c8, int opaq)
        }
 }
 
-STATIC_INLINE uae_u32 ledcolor (uae_u32 c, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc, uae_u32 *a)
-{
-       uae_u32 v = rc[(c >> 16) & 0xff] | gc[(c >> 8) & 0xff] | bc[(c >> 0) & 0xff];
-       if (a)
-               v |= a[255 - ((c >> 24) & 0xff)];
-       return v;
-}
-
-static void write_tdnumber (uae_u8 *buf, int bpp, int x, int y, int num, uae_u32 c1, uae_u32 c2)
-{
-       int j;
-       const char *numptr;
-
-       numptr = numbers + num * TD_NUM_WIDTH + NUMBERS_NUM * TD_NUM_WIDTH * y;
-       for (j = 0; j < TD_NUM_WIDTH; j++) {
-               if (*numptr == 'x')
-                       putpixel (buf, bpp, x + j, c1, 1);
-               else if (*numptr == '+')
-                       putpixel (buf, bpp, x + j, c2, 0);
-               numptr++;
-       }
-}
-
-void draw_status_line_single (uae_u8 *buf, int bpp, int y, int totalwidth, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc, uae_u32 *alpha)
-{
-       int x_start, j, led, border;
-       uae_u32 c1, c2, cb;
-
-       c1 = ledcolor (0x00ffffff, rc, gc, bc, alpha);
-       c2 = ledcolor (0x00000000, rc, gc, bc, alpha);
-       cb = ledcolor (TD_BORDER, rc, gc, bc, alpha);
-
-       if (td_pos & TD_RIGHT)
-               x_start = totalwidth - TD_PADX - VISIBLE_LEDS * TD_WIDTH;
-       else
-               x_start = TD_PADX;
-
-       for (led = 0; led < LED_MAX; led++) {
-               int side, pos, num1 = -1, num2 = -1, num3 = -1, num4 = -1;
-               int x, c, on = 0, am = 2;
-               xcolnr on_rgb, on_rgb2, off_rgb, pen_rgb;
-               int half = 0;
-
-               pen_rgb = c1;
-               if (led >= LED_DF0 && led <= LED_DF3) {
-                       int pled = led - LED_DF0;
-                       int track = gui_data.drive_track[pled];
-                       pos = 6 + pled;
-                       on_rgb = 0x00cc00;
-                       on_rgb2 = 0x006600;
-                       off_rgb = 0x003300;
-                       if (!gui_data.drive_disabled[pled]) {
-                               num1 = -1;
-                               num2 = track / 10;
-                               num3 = track % 10;
-                               on = gui_data.drive_motor[pled];
-                               if (gui_data.drive_writing[pled]) {
-                                       on_rgb = 0xcc0000;
-                                       on_rgb2 = 0x880000;
-                               }
-                               half = gui_data.drive_side ? 1 : -1;
-                               if (gui_data.df[pled][0] == 0)
-                                       pen_rgb = ledcolor (0x00aaaaaa, rc, gc, bc, alpha);
-                       }
-                       side = gui_data.drive_side;
-               } else if (led == LED_POWER) {
-                       pos = 3;
-                       on_rgb = ((gui_data.powerled_brightness * 10 / 16) + 0x33) << 16;
-                       on = 1;
-                       off_rgb = 0x330000;
-               } else if (led == LED_CD) {
-                       pos = 5;
-                       on = gui_data.cd & (LED_CD_AUDIO | LED_CD_ACTIVE);
-                       on_rgb = (on & LED_CD_AUDIO) ? 0x00cc00 : 0x0000cc;
-                       if ((gui_data.cd & LED_CD_ACTIVE2) && !(gui_data.cd & LED_CD_AUDIO)) {
-                               on_rgb &= 0xfefefe;
-                               on_rgb >>= 1;
-                       }
-                       off_rgb = 0x000033;
-                       num1 = -1;
-                       num2 = 10;
-                       num3 = 12;
-               } else if (led == LED_HD) {
-                       pos = 4;
-                       on = gui_data.hd;
-                       on_rgb = on == 2 ? 0xcc0000 : 0x0000cc;
-                       off_rgb = 0x000033;
-                       num1 = -1;
-                       num2 = 11;
-                       num3 = 12;
-               } else if (led == LED_FPS) {
-                       int fps = (gui_data.fps + 5) / 10;
-                       pos = 2;
-                       on_rgb = 0x000000;
-                       off_rgb = 0x000000;
-                       if (fps > 999)
-                               fps = 999;
-                       num1 = fps / 100;
-                       num2 = (fps - num1 * 100) / 10;
-                       num3 = fps % 10;
-                       am = 3;
-                       if (num1 == 0)
-                               am = 2;
-               } else if (led == LED_CPU) {
-                       int idle = (gui_data.idle + 5) / 10;
-                       pos = 1;
-                       on = framecnt && !picasso_on;
-                       on_rgb = 0xcc0000;
-                       off_rgb = 0x000000;
-                       num1 = idle / 100;
-                       num2 = (idle - num1 * 100) / 10;
-                       num3 = idle % 10;
-                       num4 = num1 == 0 ? 13 : -1;
-                       am = 3;
-               } else if (led == LED_SND) {
-                       int snd = abs(gui_data.sndbuf + 5) / 10;
-                       if (snd > 99)
-                               snd = 99;
-                       pos = 0;
-                       on = gui_data.sndbuf_status;
-                       if (on < 3) {
-                               num1 = gui_data.sndbuf < 0 ? 15 : 14;
-                               num2 = snd / 10;
-                               num3 = snd % 10;
-                       }
-                       on_rgb = 0x000000;
-                       if (on < 0)
-                               on_rgb = 0xcccc00; // underflow
-                       else if (on == 2)
-                               on_rgb = 0xcc0000; // really big overflow
-                       else if (on == 1)
-                               on_rgb = 0x0000cc; // "normal" overflow
-                       off_rgb = 0x000000;
-                       am = 3;
-               } else if (led == LED_MD && gui_data.drive_disabled[3]) {
-                       // DF3 reused as internal non-volatile ram led (cd32/cdtv)
-                       pos = 6 + 3;
-                       on = gui_data.md;
-                       on_rgb = on == 2 ? 0xcc0000 : 0x00cc00;
-                       off_rgb = 0x003300;
-                       num1 = -1;
-                       num2 = -1;
-                       num3 = -1;
-               } else
-                       return;
-               on_rgb |= 0x33000000;
-               off_rgb |= 0x33000000;
-               if (half > 0) {
-                       c = ledcolor (on ? (y >= TD_TOTAL_HEIGHT / 2 ? on_rgb2 : on_rgb) : off_rgb, rc, gc, bc, alpha);
-               } else if (half < 0) {
-                       c = ledcolor (on ? (y < TD_TOTAL_HEIGHT / 2 ? on_rgb2 : on_rgb) : off_rgb, rc, gc, bc, alpha);
-               } else {
-                       c = ledcolor (on ? on_rgb : off_rgb, rc, gc, bc, alpha);
-               }
-               border = 0;
-               if (y == 0 || y == TD_TOTAL_HEIGHT - 1) {
-                       c = ledcolor (TD_BORDER, rc, gc, bc, alpha);
-                       border = 1;
-               }
-
-               x = x_start + pos * TD_WIDTH;
-               if (!border)
-                       putpixel (buf, bpp, x - 1, cb, 0);
-               for (j = 0; j < TD_LED_WIDTH; j++)
-                       putpixel (buf, bpp, x + j, c, 0);
-               if (!border)
-                       putpixel (buf, bpp, x + j, cb, 0);
-
-               if (y >= TD_PADY && y - TD_PADY < TD_NUM_HEIGHT) {
-                       if (num3 >= 0) {
-                               x += (TD_LED_WIDTH - am * TD_NUM_WIDTH) / 2;
-                               if (num1 > 0) {
-                                       write_tdnumber (buf, bpp, x, y - TD_PADY, num1, pen_rgb, c2);
-                                       x += TD_NUM_WIDTH;
-                               }
-                               write_tdnumber (buf, bpp, x, y - TD_PADY, num2, pen_rgb, c2);
-                               x += TD_NUM_WIDTH;
-                               write_tdnumber (buf, bpp, x, y - TD_PADY, num3, pen_rgb, c2);
-                               x += TD_NUM_WIDTH;
-                               if (num4 > 0)
-                                       write_tdnumber (buf, bpp, x, y - TD_PADY, num4, pen_rgb, c2);
-                       }
-               }
-       }
-}
-
 static void draw_status_line (int line)
 {
        int bpp, y;
@@ -2660,7 +2461,7 @@ static void draw_lightpen_cursor (int x, int y, int line, int onscreen)
        for (i = 0; i < LIGHTPEN_WIDTH; i++) {
                int xx = x + i - LIGHTPEN_WIDTH / 2;
                if (*p != '-' && xx >= 0 && xx < gfxvidinfo.width)
-                       putpixel(xlinebuffer, gfxvidinfo.pixbytes, xx, *p == 'x' ? xcolors[color1] : xcolors[color2], 1);
+                       putpixel (xlinebuffer, gfxvidinfo.pixbytes, xx, *p == 'x' ? xcolors[color1] : xcolors[color2], 1);
                p++;
        }
 }
@@ -2737,7 +2538,7 @@ void finish_drawing_frame (void)
                if (where2 < 0)
                        continue;
 
-               hposendblank = 0;
+               hposblank = 0;
                pfield_draw_line (line, where2, amiga2aspect_line_map[i1 + 1]);
        }
 
@@ -2753,7 +2554,7 @@ void finish_drawing_frame (void)
                if (where2 < 0)
                        continue;
 
-               hposendblank = i >= last_max_ypos + 16;
+               hposblank = i >= last_max_ypos + 16;
 
                xlinebuffer = gfxvidinfo.linemem;
                if (xlinebuffer == 0)
@@ -2859,40 +2660,21 @@ void vsync_handle_redraw (int long_frame, int lof_changed)
                                notice_screen_contents_lost ();
                }
 
-               /* At this point, we have finished both the hardware and the
-               * drawing frame. Essentially, we are outside of all loops and
-               * can do some things which would cause confusion if they were
-               * done at other times.
-               */
-
-#ifdef SAVESTATE
-               if (savestate_state == STATE_DORESTORE) {
-                       savestate_state = STATE_RESTORE;
-                       reset_drawing ();
-                       uae_reset (0);
-               } else if (savestate_state == STATE_DOREWIND) {
-                       savestate_state = STATE_REWIND;
-                       reset_drawing ();
-                       uae_reset (0);
-               }
-#endif
-
                if (quit_program < 0) {
+#ifdef SAVESTATE
                        if (!savestate_state) {
                                if (currprefs.quitstatefile[0]) {
-                                       savestate_initsave (currprefs.quitstatefile, 1, 1); 
+                                       savestate_initsave (currprefs.quitstatefile, 1, 1, true); 
                                        save_state (currprefs.quitstatefile, L"");
                                }
                        }
+#endif
                        quit_program = -quit_program;
                        set_inhibit_frame (IHF_QUIT_PROGRAM);
                        set_special (SPCFLAG_BRK);
                        return;
                }
 
-#ifdef SAVESTATE
-               savestate_capture (0);
-#endif
                count_frame ();
                check_picasso ();
 
@@ -3047,7 +2829,7 @@ void drawing_init (void)
 
        uae_sem_init (&gui_sem, 0, 1);
 #ifdef PICASSO96
-       if (savestate_state != STATE_RESTORE) {
+       if (!isrestore ()) {
                InitPicasso96 ();
                picasso_on = 0;
                picasso_requested_on = 0;
index fdb9297ec9f1f6785f067ecf99303744398f2332..471f8e8801af376ea9763870d4722ac331a0d2a1 100644 (file)
@@ -195,14 +195,14 @@ static void ersatz_init (void)
                disk_eject (0);
 
                m68k_setpc (0xFC0002);
-               fill_prefetch_slow ();
+               fill_prefetch ();
                uae_reset (0);
                ersatzkickfile = 0;
                return;
        }
 
        m68k_setpc (0x400C);
-       fill_prefetch_slow ();
+       fill_prefetch ();
 
        /* Init the hardware */
        put_long (0x3000, 0xFFFFFFFEul);
index 87dad465340e153d3d5d447507b62bd7f677f597..581569d22ccd2289f0474adeddaf75244526ef24 100644 (file)
@@ -983,7 +983,7 @@ static void expamem_init_filesys (void)
 
        expamem_write (0x08, no_shutup);
 
-       expamem_write (0x04, 2);
+       expamem_write (0x04, 82);
        expamem_write (0x10, uae_id >> 8);
        expamem_write (0x14, uae_id & 0xff);
 
@@ -1063,7 +1063,7 @@ static void expamem_init_z3fastmem_2 (addrbank *bank, uae_u32 start, uae_u32 siz
 
        expamem_write (0x08, care_addr | no_shutup | force_z3 | (allocated > 0x800000 ? ext_size : Z3_MEM_AUTO));
 
-       expamem_write (0x04, 3);
+       expamem_write (0x04, 83);
 
        expamem_write (0x10, uae_id >> 8);
        expamem_write (0x14, uae_id & 0xff);
index 69b0d35863038f5de0f12d321d3c4ac464f8feee..458af87ab8c0dd0b50ff1ed353ed4a368ac2d89d 100644 (file)
@@ -704,60 +704,57 @@ struct hardfiledata *get_hardfile_data (int nr)
 #define MAXFILESIZE32 (0x7fffffff)
 
 /* Passed as type to Lock() */
-#define SHARED_LOCK    -2  /* File is readable by others */
-#define ACCESS_READ    -2  /* Synonym */
+#define SHARED_LOCK            -2  /* File is readable by others */
+#define ACCESS_READ            -2  /* Synonym */
 #define EXCLUSIVE_LOCK -1  /* No other access allowed  */
 #define ACCESS_WRITE   -1  /* Synonym */
 
 /* packet types */
-#define ACTION_CURRENT_VOLUME  7
-#define ACTION_LOCATE_OBJECT   8
-#define ACTION_RENAME_DISK     9
-#define ACTION_FREE_LOCK       15
+#define ACTION_CURRENT_VOLUME   7
+#define ACTION_LOCATE_OBJECT    8
+#define ACTION_RENAME_DISK              9
+#define ACTION_FREE_LOCK               15
 #define ACTION_DELETE_OBJECT   16
 #define ACTION_RENAME_OBJECT   17
-#define ACTION_MORE_CACHE      18
-#define ACTION_COPY_DIR                19
-#define ACTION_SET_PROTECT     21
-#define ACTION_CREATE_DIR      22
+#define ACTION_MORE_CACHE              18
+#define ACTION_COPY_DIR                        19
+#define ACTION_SET_PROTECT             21
+#define ACTION_CREATE_DIR              22
 #define ACTION_EXAMINE_OBJECT  23
-#define ACTION_EXAMINE_NEXT    24
-#define ACTION_DISK_INFO       25
-#define ACTION_INFO            26
-#define ACTION_FLUSH           27
-#define ACTION_SET_COMMENT     28
-#define ACTION_PARENT          29
-#define ACTION_SET_DATE                34
-#define ACTION_FIND_WRITE      1004
-#define ACTION_FIND_INPUT      1005
-#define ACTION_FIND_OUTPUT     1006
-#define ACTION_END             1007
-#define ACTION_SEEK            1008
+#define ACTION_EXAMINE_NEXT            24
+#define ACTION_DISK_INFO               25
+#define ACTION_INFO                            26
+#define ACTION_FLUSH                   27
+#define ACTION_SET_COMMENT             28
+#define ACTION_PARENT                  29
+#define ACTION_SET_DATE                        34
+#define ACTION_FIND_WRITE              1004
+#define ACTION_FIND_INPUT              1005
+#define ACTION_FIND_OUTPUT             1006
+#define ACTION_END                             1007
+#define ACTION_SEEK                            1008
 #define ACTION_WRITE_PROTECT   1023
 #define ACTION_IS_FILESYSTEM   1027
-#define ACTION_READ            'R'
-#define ACTION_WRITE           'W'
+#define ACTION_READ                             'R'
+#define ACTION_WRITE                    'W'
 
 /* 2.0+ packet types */
-#define ACTION_INHIBIT         31
+#define ACTION_INHIBIT                   31
 #define ACTION_SET_FILE_SIZE   1022
-#define ACTION_LOCK_RECORD     2008
-#define ACTION_FREE_RECORD     2009
-#define ACTION_SAME_LOCK       40
-#define ACTION_CHANGE_MODE     1028
-#define ACTION_FH_FROM_LOCK    1026
-#define ACTION_COPY_DIR_FH     1030
-#define ACTION_PARENT_FH       1031
-#define ACTION_EXAMINE_ALL     1033
-#define ACTION_EXAMINE_FH      1034
+#define ACTION_LOCK_RECORD             2008
+#define ACTION_FREE_RECORD             2009
+#define ACTION_SAME_LOCK                 40
+#define ACTION_CHANGE_MODE             1028
+#define ACTION_FH_FROM_LOCK            1026
+#define ACTION_COPY_DIR_FH             1030
+#define ACTION_PARENT_FH               1031
+#define ACTION_EXAMINE_ALL             1033
+#define ACTION_EXAMINE_FH              1034
 #define ACTION_EXAMINE_ALL_END 1035
 
-#define ACTION_MAKE_LINK       1021
-#define ACTION_READ_LINK       1024
-
-#define ACTION_FORMAT          1020
+#define ACTION_FORMAT                  1020
 #define ACTION_IS_FILESYSTEM   1027
-#define ACTION_ADD_NOTIFY      4097
+#define ACTION_ADD_NOTIFY              4097
 #define ACTION_REMOVE_NOTIFY   4098
 
 #define ACTION_CHANGE_FILE_POSITION64  8001
@@ -765,7 +762,11 @@ struct hardfiledata *get_hardfile_data (int nr)
 #define ACTION_CHANGE_FILE_SIZE64      8003
 #define ACTION_GET_FILE_SIZE64         8004
 
-#define DISK_TYPE              0x444f5301 /* DOS\1 */
+/* not supported */
+#define ACTION_MAKE_LINK               1021
+#define ACTION_READ_LINK               1024
+
+#define DISK_TYPE 0x444f5301 /* DOS\1 */
 
 typedef struct {
        uae_u32 uniq;
@@ -775,6 +776,17 @@ typedef struct {
        a_inode *curr_file;
 } ExamineKey;
 
+struct lockrecord
+{
+       struct lockrecord *next;
+       uae_u32 packet;
+       uae_u32 pos;
+       uae_u32 len;
+       uae_u32 mode;
+       uae_u32 timeout;
+       uae_u32 msg;
+};
+
 typedef struct key {
        struct key *next;
        a_inode *aino;
@@ -784,6 +796,7 @@ typedef struct key {
        int dosmode;
        int createmode;
        int notifyactive;
+       struct lockrecord *record;
 } Key;
 
 typedef struct notify {
@@ -843,6 +856,8 @@ typedef struct _unit {
        /* Keys */
        struct key *keys;
 
+       struct lockrecord *waitingrecords;
+
        a_inode rootnode;
        unsigned long aino_cache_size;
        a_inode *aino_hash[MAX_AINO_HASH];
@@ -1128,23 +1143,6 @@ int filesys_eject (int nr)
        return 1;
 }
 
-void filesys_vsync (void)
-{
-       Unit *u;
-
-       for (u = units; u; u = u->next) {
-               if (u->reinsertdelay > 0) {
-                       u->reinsertdelay--;
-                       if (u->reinsertdelay == 0) {
-                               filesys_insert (u->unit, u->newvolume, u->newrootdir, u->newreadonly, u->newflags);
-                               xfree (u->newvolume);
-                               u->newvolume = NULL;
-                               xfree (u->newrootdir);
-                               u->newrootdir = NULL;
-                       }
-               }
-       }
-}
 static void filesys_delayed_change (Unit *u, int frames, const TCHAR *rootdir, const TCHAR *volume, bool readonly, int flags)
 {
        u->reinsertdelay = 50;
@@ -2116,7 +2114,7 @@ static void filesys_start_thread (UnitInfo *ui, int nr)
        ui->unit_pipe = 0;
        ui->back_pipe = 0;
        ui->reset_state = FS_STARTUP;
-       if (savestate_state != STATE_RESTORE) {
+       if (!isrestore ()) {
                ui->startup = 0;
                ui->self = 0;
        }
@@ -2129,7 +2127,7 @@ static void filesys_start_thread (UnitInfo *ui, int nr)
                uae_start_thread (L"filesys", filesys_thread, (void *)ui, &ui->tid);
        }
 #endif
-       if (savestate_state == STATE_RESTORE)
+       if (isrestore ())
                startup_update_unit (ui->self, ui);
 }
 
@@ -2291,6 +2289,12 @@ static void free_key (Unit *unit, Key *k)
                prev = k1;
        }
 
+       for (struct lockrecord *lr = k->record; lr;) {
+               struct lockrecord *next = lr->next;
+               xfree (lr);
+               lr = next;
+       }
+
        if (k->fd != NULL)
                fs_close (k->fd);
 
@@ -2883,6 +2887,189 @@ int get_native_path (uae_u32 lock, TCHAR *out)
        return -1;
 }
 
+
+#define REC_EXCLUSIVE 0
+#define REC_EXCLUSIVE_IMMED 1
+#define REC_SHARED 2
+#define REC_SHARED_IMMED 3
+
+static struct lockrecord *new_record (uae_u32 packet, uae_u32 pos, uae_u32 len, uae_u32 mode, uae_u32 timeout, uae_u32 msg)
+{
+       struct lockrecord *lr = xcalloc (struct lockrecord, 1);
+       lr->packet = packet;
+       lr->pos = pos;
+       lr->len = len;
+       lr->mode = mode;
+       lr->timeout = timeout * vblank_hz / 50;
+       lr->msg = msg;
+       return lr;
+}
+
+static bool record_hit (Unit *unit, Key *k, uae_u32 pos, uae_u32 len, uae_u32 mode)
+{
+       bool exclusive = mode == REC_EXCLUSIVE || mode == REC_EXCLUSIVE_IMMED;
+       for (Key *k2 = unit->keys; k2; k2 = k2->next) {
+               if (k2->aino->uniq == k->aino->uniq) {
+                       if (k2 == k)
+                               continue;
+                       for (struct lockrecord *lr = k2->record; lr; lr = lr->next) {
+                               bool exclusive2 = lr->mode == REC_EXCLUSIVE || lr->mode == REC_EXCLUSIVE_IMMED;
+                               if (exclusive || exclusive2) {
+                                       uae_u32 a1 = pos;
+                                       uae_u32 a2 = pos + len;
+                                       uae_u32 b1 = lr->pos;
+                                       uae_u32 b2 = lr->pos + lr->len;
+                                       if (len && lr->len) {
+                                               bool hit = (a1 >= b1 && a1 < b2) || (a2 > b1 && a2 < b2) || (b1 >= a1 && b1 < a2) || (b2 > a1 && b2 < a2);
+                                               if (hit)
+                                                       return true;
+                                       }
+                               }
+                       }
+               }
+       }
+       return false;
+}
+
+static void record_timeout (Unit *unit)
+{
+       bool retry = true;
+       while (retry) {
+               retry = false;
+               struct lockrecord *prev = NULL;
+               for (struct lockrecord *lr = unit->waitingrecords; lr; lr = lr->next) {
+                       lr->timeout--;
+                       if (lr->timeout == 0) {
+                               Key *k = lookup_key (unit, GET_PCK_ARG1 (lr->packet));
+                               PUT_PCK_RES1 (lr->packet, DOS_FALSE);
+                               PUT_PCK_RES2 (lr->packet, ERROR_LOCK_TIMEOUT);
+                               // mark packet as complete
+                               put_long (lr->msg + 4, 0xfffffffe);
+                               uae_Signal (get_long (unit->volume + 176 - 32), 1 << 13);
+                               if (prev)
+                                       prev->next = lr->next;
+                               else
+                                       unit->waitingrecords = lr->next;
+                               write_log (L"queued record timed out '%s',%d,%d,%d,%d\n", k ? k->aino->nname : L"NULL", lr->pos, lr->len, lr->mode, lr->timeout);
+                               xfree (lr);
+                               retry = true;
+                               break;
+                       }
+                       prev = lr;
+               }
+       }
+}
+
+static void record_check_waiting (Unit *unit)
+{
+       bool retry = true;
+       while (retry) {
+               retry = false;
+               struct lockrecord *prev = NULL;
+               for (struct lockrecord *lr = unit->waitingrecords; lr; lr = lr->next) {
+                       Key *k = lookup_key (unit, GET_PCK_ARG1 (lr->packet));
+                       if (!k || !record_hit (unit, k, lr->pos, lr->len, lr->mode)) {
+                               if (prev)
+                                       prev->next = lr->next;
+                               else
+                                       unit->waitingrecords = lr->next;
+                               write_log (L"queued record released '%s',%d,%d,%d,%d\n", k->aino->nname, lr->pos, lr->len, lr->mode, lr->timeout);
+                               // mark packet as complete
+                               put_long (lr->msg + 4, 0xffffffff);
+                               xfree (lr);
+                               retry = true;
+                               break;
+                       }
+                       prev = lr;
+               }
+       }
+}
+
+static int action_lock_record (Unit *unit, dpacket packet, uae_u32 msg)
+{
+       Key *k = lookup_key (unit, GET_PCK_ARG1 (packet));
+       uae_u32 pos = GET_PCK_ARG2 (packet);
+       uae_u32 len = GET_PCK_ARG3 (packet);
+       uae_u32 mode = GET_PCK_ARG4 (packet);
+       uae_u32 timeout = GET_PCK_ARG5 (packet);
+
+       bool exclusive = mode == REC_EXCLUSIVE || mode == REC_EXCLUSIVE_IMMED;
+
+       write_log (L"action_lock_record('%s',%d,%d,%d,%d)\n", k ? k->aino->nname : L"null", pos, len, mode, timeout);
+
+       if (!k || mode > REC_SHARED_IMMED) {
+               PUT_PCK_RES1 (packet, DOS_FALSE);
+               PUT_PCK_RES2 (packet, ERROR_OBJECT_WRONG_TYPE);
+               return 1;
+       }
+
+       if (mode == REC_EXCLUSIVE_IMMED || mode == REC_SHARED_IMMED)
+               timeout = 0;
+
+       if (record_hit (unit, k, pos, len, mode)) {
+               if (timeout && msg) {
+                       // queue it and do not reply
+                       struct lockrecord *lr = new_record (packet, pos, len, mode, timeout, msg);
+                       if (unit->waitingrecords) {
+                               lr->next = unit->waitingrecords;
+                               unit->waitingrecords = lr;
+                       } else {
+                               unit->waitingrecords = lr;
+                       }
+                       write_log (L"-> collision, timeout queued\n");
+                       return -1;
+               }
+               PUT_PCK_RES1 (packet, DOS_FALSE);
+               PUT_PCK_RES2 (packet, ERROR_LOCK_COLLISION);
+               write_log (L"-> ERROR_LOCK_COLLISION\n");
+               return 1;
+       }
+
+       struct lockrecord *lr = new_record (GET_PCK_ARG1 (packet), pos, len, mode, timeout, 0);
+       if (k->record) {
+               lr->next = k->record;
+               k->record = lr;
+       } else {
+               k->record = lr;
+       }
+       PUT_PCK_RES1 (packet, DOS_TRUE);
+       write_log (L"-> OK\n");
+       return 1;
+}
+
+static void action_free_record (Unit *unit, dpacket packet)
+{
+       Key *k = lookup_key (unit, GET_PCK_ARG1 (packet));
+       uae_u32 pos = GET_PCK_ARG2 (packet);
+       uae_u32 len = GET_PCK_ARG3 (packet);
+
+       write_log (L"action_free_record('%s',%d,%d)\n", k ? k->aino->nname : L"null", pos, len);
+
+       if (!k) {
+               PUT_PCK_RES1 (packet, DOS_FALSE);
+               PUT_PCK_RES2 (packet, ERROR_OBJECT_WRONG_TYPE);
+               return;
+       }
+
+       struct lockrecord *prev = NULL;
+       for (struct lockrecord *lr = k->record; lr; lr = lr->next) {
+               if (lr->pos == pos && lr->len == len) {
+                       if (prev)
+                               prev->next = lr->next;
+                       else
+                               k->record = lr->next;
+                       xfree (lr);
+                       write_log (L"->OK\n");
+                       record_check_waiting (unit);
+                       PUT_PCK_RES1 (packet, DOS_TRUE);
+                       return;
+               }
+       }
+       write_log (L"-> ERROR_RECORD_NOT_LOCKED\n");
+       PUT_PCK_RES1 (packet, DOS_FALSE);
+       PUT_PCK_RES2 (packet, ERROR_RECORD_NOT_LOCKED);
+}
+
 #define EXALL_DEBUG 0
 #define EXALL_END 0xde1111ad
 
@@ -4824,12 +5011,12 @@ static uae_u32 REGPARAM2 exter_int_helper (TrapContext *context)
        return 0;
 }
 
-static int handle_packet (Unit *unit, dpacket pck)
+static int handle_packet (Unit *unit, dpacket pck, uae_u32 msg)
 {
        uae_s32 type = GET_PCK_TYPE (pck);
        PUT_PCK_RES2 (pck, 0);
 
-       if (unit->inhibited && filesys_isvolume(unit)
+       if (unit->inhibited && filesys_isvolume (unit)
                && type != ACTION_INHIBIT && type != ACTION_MORE_CACHE
                && type != ACTION_DISK_INFO) {
                        PUT_PCK_RES1 (pck, DOS_FALSE);
@@ -4839,7 +5026,7 @@ static int handle_packet (Unit *unit, dpacket pck)
        if (type != ACTION_INHIBIT && type != ACTION_CURRENT_VOLUME
                && type != ACTION_IS_FILESYSTEM && type != ACTION_MORE_CACHE
                && type != ACTION_WRITE_PROTECT
-               && !filesys_isvolume(unit)) {
+               && !filesys_isvolume (unit)) {
                        PUT_PCK_RES1 (pck, DOS_FALSE);
                        PUT_PCK_RES2 (pck, ERROR_NO_DISK);
                        return 1;
@@ -4887,6 +5074,8 @@ static int handle_packet (Unit *unit, dpacket pck)
        case ACTION_REMOVE_NOTIFY: action_remove_notify (unit, pck); break;
        case ACTION_EXAMINE_ALL: return action_examine_all (unit, pck);
        case ACTION_EXAMINE_ALL_END: return action_examine_all_end (unit, pck);
+       case ACTION_LOCK_RECORD: return action_lock_record (unit, pck, msg); break;
+       case ACTION_FREE_RECORD: action_free_record (unit, pck); break;
 
                /* OS4+ packet types */
        case ACTION_CHANGE_FILE_POSITION64: action_change_file_position64 (unit, pck); break;
@@ -4895,8 +5084,6 @@ static int handle_packet (Unit *unit, dpacket pck)
        case ACTION_GET_FILE_SIZE64: action_get_file_size64 (unit, pck); break;
 
                /* unsupported packets */
-       case ACTION_LOCK_RECORD:
-       case ACTION_FREE_RECORD:
        case ACTION_MAKE_LINK:
        case ACTION_READ_LINK:
        case ACTION_FORMAT:
@@ -4934,18 +5121,19 @@ static void *filesys_thread (void *unit_v)
 
                put_long (get_long (morelocks), get_long (ui->self->locklist));
                put_long (ui->self->locklist, morelocks);
-               if (! handle_packet (ui->self, pck)) {
+               int ret = handle_packet (ui->self, pck, msg);
+               if (!ret) {
                        PUT_PCK_RES1 (pck, DOS_FALSE);
                        PUT_PCK_RES2 (pck, ERROR_ACTION_NOT_KNOWN);
                }
-               /* Mark the packet as processed for the list scan in the assembly code. */
-               put_long (msg + 4, 0xffffffff);
-               /* Acquire the message lock, so that we know we can safely send the
-               * message. */
+               if (ret >= 0) {
+                       /* Mark the packet as processed for the list scan in the assembly code. */
+                       put_long (msg + 4, 0xffffffff);
+               }
+               /* Acquire the message lock, so that we know we can safely send the message. */
                ui->self->cmds_sent++;
-               /* The message is sent by our interrupt handler, so make sure an interrupt
-               * happens. */
-               do_uae_int_requested();
+               /* The message is sent by our interrupt handler, so make sure an interrupt happens. */
+               do_uae_int_requested ();
                /* Send back the locks. */
                if (get_long (ui->self->locklist) != 0)
                        write_comm_pipe_int (ui->back_pipe, (int)(get_long (ui->self->locklist)), 0);
@@ -4992,7 +5180,7 @@ static uae_u32 REGPARAM2 filesys_handler (TrapContext *context)
        }
 #endif
 
-       if (! handle_packet (unit, packet_addr)) {
+       if (! handle_packet (unit, packet_addr, 0)) {
 error:
                PUT_PCK_RES1 (packet_addr, DOS_FALSE);
                PUT_PCK_RES2 (packet_addr, ERROR_ACTION_NOT_KNOWN);
@@ -5045,6 +5233,12 @@ void filesys_free_handles (void)
                        xfree (k1);
                }
                u->keys = NULL;
+               struct lockrecord *lrnext;
+               for (struct lockrecord *lr = u->waitingrecords; lr; lr = lrnext) {
+                       lrnext = lr->next;
+                       xfree (lr);
+               }
+               u->waitingrecords = NULL;
                free_all_ainos (u, &u->rootnode);
                u->rootnode.next = u->rootnode.prev = &u->rootnode;
                u->aino_cache_size = 0;
@@ -5073,7 +5267,7 @@ static void filesys_reset2 (void)
 
 void filesys_reset (void)
 {
-       if (savestate_state == STATE_RESTORE)
+       if (isrestore ())
                return;
        filesys_reset2 ();
        initialize_mountinfo ();
@@ -5114,7 +5308,7 @@ static void filesys_prepare_reset2 (void)
 
 void filesys_prepare_reset (void)
 {
-       if (savestate_state == STATE_RESTORE)
+       if (isrestore ())
                return;
        filesys_prepare_reset2 ();
 }
@@ -5819,6 +6013,25 @@ static uae_u32 REGPARAM2 mousehack_done (TrapContext *context)
        return 1;
 }
 
+void filesys_vsync (void)
+{
+       Unit *u;
+
+       for (u = units; u; u = u->next) {
+               if (u->reinsertdelay > 0) {
+                       u->reinsertdelay--;
+                       if (u->reinsertdelay == 0) {
+                               filesys_insert (u->unit, u->newvolume, u->newrootdir, u->newreadonly, u->newflags);
+                               xfree (u->newvolume);
+                               u->newvolume = NULL;
+                               xfree (u->newrootdir);
+                               u->newrootdir = NULL;
+                       }
+               }
+               record_timeout (u);
+       }
+}
+
 void filesys_install (void)
 {
        uaecptr loop;
index bdf3d7eacac6206fdb611994d93b022dccc7b3a5..e43ae2accbfa4f10e21b652ba2f095e955353962 100644 (file)
@@ -2,8 +2,8 @@
  db(0x00); db(0x00); db(0x00); db(0x09); db(0x60); db(0x00); db(0x0a); db(0x4a);
  db(0x00); db(0x00); db(0x08); db(0x2c); db(0x00); db(0x00); db(0x00); db(0xd0);
  db(0x00); db(0x00); db(0x02); db(0x54); db(0x00); db(0x00); db(0x00); db(0x24);
- db(0x00); db(0x00); db(0x03); db(0x10); db(0x00); db(0x00); db(0x0e); db(0x1c);
- db(0x00); db(0x00); db(0x12); db(0xac); db(0x43); db(0xfa); db(0x17); db(0x86);
+ db(0x00); db(0x00); db(0x03); db(0x10); db(0x00); db(0x00); db(0x0e); db(0x26);
+ db(0x00); db(0x00); db(0x12); db(0xb6); db(0x43); db(0xfa); db(0x17); db(0x8e);
  db(0x4e); db(0xae); db(0xff); db(0xa0); db(0x20); db(0x40); db(0x20); db(0x28);
  db(0x00); db(0x16); db(0x20); db(0x40); db(0x4e); db(0x90); db(0x4e); db(0x75);
  db(0x48); db(0xe7); db(0xe0); db(0xe2); db(0x2c); db(0x78); db(0x00); db(0x04);
  db(0x20); db(0x68); db(0x00); db(0x02); db(0x2f); db(0x08); db(0x4e); db(0x90);
  db(0x20); db(0x5f); db(0x58); db(0x8f); db(0x48); db(0xe7); db(0xff); db(0x7e);
  db(0x22); db(0x4e); db(0x20); db(0x08); db(0x30); db(0x7c); db(0xff); db(0xb8);
- db(0x4e); db(0xae); db(0xfe); db(0x5c); db(0x61); db(0x00); db(0x11); db(0xfe);
- db(0x61); db(0x00); db(0x15); db(0xb4); db(0x4c); db(0xdf); db(0x7e); db(0xff);
+ db(0x4e); db(0xae); db(0xfe); db(0x5c); db(0x61); db(0x00); db(0x12); db(0x08);
+ db(0x61); db(0x00); db(0x15); db(0xbc); db(0x4c); db(0xdf); db(0x7e); db(0xff);
  db(0x4e); db(0x75); db(0x00); db(0x00); db(0x08); db(0x00); db(0x00); db(0x02);
  db(0x67); db(0x06); db(0x4e); db(0xb9); db(0x00); db(0xf0); db(0x00); db(0x00);
  db(0x4e); db(0xf9); db(0x00); db(0xf0); db(0x00); db(0x00); db(0x00); db(0x00);
  db(0x48); db(0xe7); db(0xff); db(0xfe); db(0x2c); db(0x78); db(0x00); db(0x04);
- db(0x30); db(0x3c); db(0xff); db(0xfc); db(0x61); db(0x00); db(0x0b); db(0xaa);
- db(0x2a); db(0x50); db(0x43); db(0xfa); db(0x16); db(0xf7); db(0x70); db(0x24);
+ db(0x30); db(0x3c); db(0xff); db(0xfc); db(0x61); db(0x00); db(0x0b); db(0xb4);
+ db(0x2a); db(0x50); db(0x43); db(0xfa); db(0x16); db(0xff); db(0x70); db(0x24);
  db(0x7a); db(0x01); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x4a); db(0x80);
- db(0x66); db(0x0c); db(0x43); db(0xfa); db(0x16); db(0xe7); db(0x70); db(0x00);
+ db(0x66); db(0x0c); db(0x43); db(0xfa); db(0x16); db(0xef); db(0x70); db(0x00);
  db(0x7a); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x28); db(0x40);
  db(0x4a); db(0xad); db(0x01); db(0x0c); db(0x67); db(0x5a); db(0x20); db(0x3c);
  db(0x00); db(0x00); db(0x02); db(0x2c); db(0x22); db(0x3c); db(0x00); db(0x01);
  db(0x2c); db(0x78); db(0x00); db(0x04); db(0x22); db(0x4c); db(0x4e); db(0xae);
  db(0xfe); db(0x62); db(0x78); db(0x03); db(0x0c); db(0x6e); db(0x00); db(0x24);
  db(0x00); db(0x14); db(0x65); db(0x04); db(0x00); db(0x44); db(0x01); db(0x00);
- db(0x30); db(0x3c); db(0xff); db(0x80); db(0x61); db(0x00); db(0x0b); db(0x0a);
+ db(0x30); db(0x3c); db(0xff); db(0x80); db(0x61); db(0x00); db(0x0b); db(0x14);
  db(0x4e); db(0x90); db(0x22); db(0x04); db(0x74); db(0xf6); db(0x20); db(0x7c);
  db(0x00); db(0x20); db(0x00); db(0x00); db(0x90); db(0x88); db(0x65); db(0x08);
  db(0x67); db(0x06); db(0x93); db(0xc9); db(0x4e); db(0xae); db(0xfd); db(0x96);
- db(0x30); db(0x3c); db(0xff); db(0x80); db(0x61); db(0x00); db(0x0a); db(0xea);
+ db(0x30); db(0x3c); db(0xff); db(0x80); db(0x61); db(0x00); db(0x0a); db(0xf4);
  db(0x4e); db(0x90); db(0x20); db(0x49); db(0x20); db(0x01); db(0x67); db(0x0c);
- db(0x22); db(0x04); db(0x74); db(0xfb); db(0x43); db(0xfa); db(0x16); db(0x53);
- db(0x4e); db(0xae); db(0xfd); db(0x96); db(0x41); db(0xfa); db(0x15); db(0xca);
+ db(0x22); db(0x04); db(0x74); db(0xfb); db(0x43); db(0xfa); db(0x16); db(0x5b);
+ db(0x4e); db(0xae); db(0xfd); db(0x96); db(0x41); db(0xfa); db(0x15); db(0xd2);
  db(0x43); db(0xfa); db(0x00); db(0x54); db(0x70); db(0x0a); db(0x61); db(0x00);
- db(0x0b); db(0xa4); db(0x22); db(0x40); db(0x72); db(0x01); db(0x30); db(0x3c);
- db(0xff); db(0x48); db(0x61); db(0x00); db(0x0a); db(0xbc); db(0x4e); db(0x90);
+ db(0x0b); db(0xae); db(0x22); db(0x40); db(0x72); db(0x01); db(0x30); db(0x3c);
+ db(0xff); db(0x48); db(0x61); db(0x00); db(0x0a); db(0xc6); db(0x4e); db(0x90);
  db(0x4c); db(0xdf); db(0x7f); db(0xff); db(0x4e); db(0x75); db(0x48); db(0xe7);
  db(0x38); db(0x22); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x24); db(0x00);
  db(0x28); db(0x01); db(0x26); db(0x09); db(0x24); db(0x48); db(0x43); db(0xfa);
- db(0x15); db(0xc4); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
+ db(0x15); db(0xcc); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
  db(0x4a); db(0x80); db(0x67); db(0x14); db(0x2c); db(0x40); db(0x22); db(0x0a);
  db(0xe4); db(0x8b); db(0x4e); db(0xae); db(0xff); db(0x76); db(0x22); db(0x4e);
  db(0x2c); db(0x78); db(0x00); db(0x04); db(0x4e); db(0xae); db(0xfe); db(0x62);
  db(0x4c); db(0xdf); db(0x44); db(0x1c); db(0x4e); db(0x75); db(0x2c); db(0x78);
  db(0x00); db(0x04); db(0x70); db(0x00); db(0x08); db(0xc0); db(0x00); db(0x0d);
- db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x41); db(0xfa); db(0x15); db(0x75);
+ db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x41); db(0xfa); db(0x15); db(0x7d);
  db(0x43); db(0xfa); db(0x00); db(0x16); db(0x70); db(0x0f); db(0x22); db(0x3c);
  db(0x00); db(0x00); db(0x1f); db(0x40); db(0x61); db(0x00); db(0xff); db(0xa8);
  db(0x60); db(0xdc); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x10);
  db(0x00); db(0x00); db(0x00); db(0x00); db(0x72); db(0x02); db(0x30); db(0x3c);
- db(0xff); db(0x48); db(0x61); db(0x00); db(0x0a); db(0x44); db(0x4e); db(0x90);
+ db(0xff); db(0x48); db(0x61); db(0x00); db(0x0a); db(0x4e); db(0x4e); db(0x90);
  db(0x22); db(0x00); db(0x6b); db(0x04); db(0x61); db(0x00); db(0x07); db(0x8a);
  db(0x70); db(0x00); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x00); db(0x20);
- db(0x30); db(0x3c); db(0xff); db(0x50); db(0x61); db(0x00); db(0x0a); db(0x2a);
+ db(0x30); db(0x3c); db(0xff); db(0x50); db(0x61); db(0x00); db(0x0a); db(0x34);
  db(0x70); db(0x00); db(0x4e); db(0x90); db(0x4a); db(0x80); db(0x67); db(0x00);
  db(0x00); db(0xa2); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x30); db(0x3c);
- db(0xff); db(0x50); db(0x61); db(0x00); db(0x0a); db(0x14); db(0x70); db(0x02);
+ db(0xff); db(0x50); db(0x61); db(0x00); db(0x0a); db(0x1e); db(0x70); db(0x02);
  db(0x4e); db(0x90); db(0x0c); db(0x40); db(0x00); db(0x01); db(0x6d); db(0x00);
  db(0x00); db(0x7c); db(0x6e); db(0x06); db(0x4e); db(0xae); db(0xfe); db(0x92);
  db(0x60); db(0xe4); db(0x0c); db(0x40); db(0x00); db(0x02); db(0x6e); db(0x08);
  db(0x00); db(0x18); db(0x25); db(0x49); db(0x00); db(0x1a); db(0x20); db(0x69);
  db(0x00); db(0x10); db(0x22); db(0x4a); db(0x4e); db(0xae); db(0xfe); db(0x92);
  db(0x60); db(0x00); db(0xff); db(0x74); db(0x30); db(0x3c); db(0xff); db(0x50);
- db(0x61); db(0x00); db(0x09); db(0x86); db(0x70); db(0x04); db(0x4e); db(0x90);
+ db(0x61); db(0x00); db(0x09); db(0x90); db(0x70); db(0x04); db(0x4e); db(0x90);
  db(0x70); db(0x01); db(0x4c); db(0xdf); db(0x04); db(0x00); db(0x4e); db(0x75);
  db(0x48); db(0xe7); db(0xc0); db(0xc0); db(0x61); db(0x00); db(0xfd); db(0x22);
  db(0x70); db(0x1a); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
  db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x22); db(0x40); db(0x41); db(0xfa);
- db(0x14); db(0x49); db(0x23); db(0x48); db(0x00); db(0x0a); db(0x41); db(0xfa);
+ db(0x14); db(0x51); db(0x23); db(0x48); db(0x00); db(0x0a); db(0x41); db(0xfa);
  db(0xff); db(0x24); db(0x23); db(0x48); db(0x00); db(0x0e); db(0x41); db(0xfa);
  db(0xff); db(0x1c); db(0x23); db(0x48); db(0x00); db(0x12); db(0x33); db(0x7c);
  db(0x02); db(0x14); db(0x00); db(0x08); db(0x70); db(0x03); db(0x4e); db(0xae);
- db(0xff); db(0x58); db(0x30); db(0x3a); db(0x0a); db(0xd0); db(0x67); db(0x04);
- db(0x61); db(0x00); db(0x0a); db(0x6e); db(0x4c); db(0xdf); db(0x03); db(0x03);
+ db(0xff); db(0x58); db(0x30); db(0x3a); db(0x0a); db(0xda); db(0x67); db(0x04);
+ db(0x61); db(0x00); db(0x0a); db(0x78); db(0x4c); db(0xdf); db(0x03); db(0x03);
  db(0x4e); db(0x75); db(0x48); db(0xe7); db(0xc0); db(0xf2); db(0x2c); db(0x78);
  db(0x00); db(0x04); db(0x24); db(0x48); db(0x26); db(0x49); db(0x20); db(0x3c);
  db(0x00); db(0x00); db(0x00); db(0xbe); db(0x22); db(0x3c); db(0x00); db(0x01);
  db(0x00); db(0x00); db(0x00); db(0x0e); db(0x52); db(0x40); db(0x0c); db(0x40);
  db(0x00); db(0x8c); db(0x66); db(0xf2); db(0x20); db(0x0a); db(0xe4); db(0x88);
  db(0x21); db(0x40); db(0x00); db(0x36); db(0x22); db(0x48); db(0x41); db(0xfa);
- db(0x13); db(0xd9); db(0x23); db(0x48); db(0x00); db(0x0a); db(0x20); db(0x6b);
+ db(0x13); db(0xe1); db(0x23); db(0x48); db(0x00); db(0x0a); db(0x20); db(0x6b);
  db(0x01); db(0x98); db(0x41); db(0xe8); db(0x00); db(0x12); db(0x4e); db(0xae);
  db(0xff); db(0x10); db(0x4c); db(0xdf); db(0x4f); db(0x03); db(0x4e); db(0x75);
  db(0x48); db(0xe7); db(0x7f); db(0x7e); db(0x2c); db(0x78); db(0x00); db(0x04);
  db(0x60); db(0xf4); db(0x48); db(0xe7); db(0x40); db(0xe2); db(0x2c); db(0x78);
  db(0x00); db(0x04); db(0x41); db(0xee); db(0x01); db(0x50); db(0x20); db(0x50);
  db(0x4a); db(0x90); db(0x67); db(0x1a); db(0x22); db(0x68); db(0x00); db(0x0a);
- db(0x45); db(0xfa); db(0x13); db(0x2b); db(0x10); db(0x19); db(0x12); db(0x1a);
+ db(0x45); db(0xfa); db(0x13); db(0x33); db(0x10); db(0x19); db(0x12); db(0x1a);
  db(0xb0); db(0x01); db(0x66); db(0x06); db(0x4a); db(0x00); db(0x67); db(0x42);
  db(0x60); db(0xf2); db(0x20); db(0x50); db(0x60); db(0xe2); db(0x70); db(0x20);
  db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae);
  db(0xff); db(0x3a); db(0x24); db(0x40); db(0x15); db(0x7c); db(0x00); db(0x08);
- db(0x00); db(0x08); db(0x41); db(0xfa); db(0x13); db(0x01); db(0x25); db(0x48);
- db(0x00); db(0x0a); db(0x41); db(0xfa); db(0x12); db(0x7d); db(0x25); db(0x48);
+ db(0x00); db(0x08); db(0x41); db(0xfa); db(0x13); db(0x09); db(0x25); db(0x48);
+ db(0x00); db(0x0a); db(0x41); db(0xfa); db(0x12); db(0x85); db(0x25); db(0x48);
  db(0x00); db(0x0e); db(0x41); db(0xea); db(0x00); db(0x12); db(0x20); db(0x88);
  db(0x58); db(0x90); db(0x21); db(0x48); db(0x00); db(0x08); db(0x41); db(0xee);
  db(0x01); db(0x50); db(0x22); db(0x4a); db(0x4e); db(0xae); db(0xff); db(0x0a);
  db(0x4c); db(0xdf); db(0x7c); db(0xfc); db(0x20); db(0x6c); db(0x00); db(0x24);
  db(0x4a); db(0x90); db(0x4e); db(0x75); db(0x61); db(0x00); db(0xfc); db(0x7c);
  db(0x21); db(0x40); db(0x01); db(0x98); db(0x2f); db(0x08); db(0x30); db(0x3c);
- db(0xff); db(0xfc); db(0x61); db(0x00); db(0x04); db(0x4c); db(0x2a); db(0x50);
- db(0x30); db(0x3c); db(0xff); db(0x28); db(0x61); db(0x00); db(0x04); db(0x42);
+ db(0xff); db(0xfc); db(0x61); db(0x00); db(0x04); db(0x56); db(0x2a); db(0x50);
+ db(0x30); db(0x3c); db(0xff); db(0x28); db(0x61); db(0x00); db(0x04); db(0x4c);
  db(0x22); db(0x48); db(0x20); db(0x5f); db(0x42); db(0xa8); db(0x01); db(0x90);
  db(0x42); db(0xa8); db(0x01); db(0x94); db(0x4e); db(0x91); db(0x26); db(0x00);
  db(0x0c); db(0x43); db(0xff); db(0xfe); db(0x67); db(0x00); db(0xf9); db(0x76);
  db(0x2f); db(0x08); db(0x72); db(0x01); db(0x2c); db(0x78); db(0x00); db(0x04);
  db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x20); db(0x5f); db(0x21); db(0x40);
  db(0x01); db(0x94); db(0x4a); db(0x83); db(0x6a); db(0x0e); db(0x22); db(0x48);
- db(0x30); db(0x3c); db(0xff); db(0x20); db(0x61); db(0x00); db(0x04); db(0x02);
+ db(0x30); db(0x3c); db(0xff); db(0x20); db(0x61); db(0x00); db(0x04); db(0x0c);
  db(0x4e); db(0x90); db(0x60); db(0x26); db(0x2c); db(0x4c); db(0x2f); db(0x08);
  db(0x4e); db(0xae); db(0xff); db(0x70); db(0x20); db(0x5f); db(0x22); db(0x48);
  db(0x26); db(0x40); db(0x30); db(0x3c); db(0xff); db(0x20); db(0x61); db(0x00);
- db(0x03); db(0xe8); db(0x4e); db(0x90); db(0x70); db(0x00); db(0x27); db(0x40);
+ db(0x03); db(0xf2); db(0x4e); db(0x90); db(0x70); db(0x00); db(0x27); db(0x40);
  db(0x00); db(0x08); db(0x27); db(0x40); db(0x00); db(0x10); db(0x27); db(0x40);
  db(0x00); db(0x20); db(0x4a); db(0xa9); db(0x01); db(0x94); db(0x67); db(0x28);
  db(0x20); db(0x69); db(0x01); db(0x94); db(0x61); db(0x00); db(0xfa); db(0xf2);
  db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x4c); db(0xdf); db(0x03); db(0x01);
  db(0x4a); db(0x80); db(0x67); db(0x04); db(0x61); db(0x00); db(0xfa); db(0x7c);
  db(0x4a); db(0x83); db(0x6b); db(0x00); db(0xf8); db(0xf0); db(0x30); db(0x3c);
- db(0xff); db(0x18); db(0x61); db(0x00); db(0x03); db(0x9c); db(0x4e); db(0x90);
+ db(0xff); db(0x18); db(0x61); db(0x00); db(0x03); db(0xa6); db(0x4e); db(0x90);
  db(0x20); db(0x03); db(0x16); db(0x29); db(0x00); db(0x4f); db(0x4a); db(0x80);
  db(0x66); db(0x1a); db(0x27); db(0x7c); db(0x00); db(0x00); db(0x17); db(0x70);
  db(0x00); db(0x14); db(0x41); db(0xfa); db(0xf6); db(0xf8); db(0x20); db(0x08);
  db(0x67); db(0x3a); db(0x20); db(0x52); db(0x24); db(0x40); db(0x22); db(0x4a);
  db(0x12); db(0xd8); db(0x66); db(0xfc); db(0x13); db(0x7c); db(0x00); db(0x3a);
  db(0xff); db(0xff); db(0x42); db(0x11); db(0x2c); db(0x78); db(0x00); db(0x04);
- db(0x43); db(0xfa); db(0x0d); db(0xfa); db(0x70); db(0x00); db(0x4e); db(0xae);
+ db(0x43); db(0xfa); db(0x0e); db(0x02); db(0x70); db(0x00); db(0x4e); db(0xae);
  db(0xfd); db(0xd8); db(0x2c); db(0x40); db(0x22); db(0x0a); db(0x4e); db(0xae);
  db(0xff); db(0x52); db(0x22); db(0x4e); db(0x2c); db(0x78); db(0x00); db(0x04);
  db(0x4e); db(0xae); db(0xfe); db(0x62); db(0x22); db(0x4a); db(0x20); db(0x02);
  db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x70); db(0x00); db(0x4e); db(0x75);
  db(0x48); db(0xe7); db(0x3f); db(0x3e); db(0x2c); db(0x01); db(0x7e); db(0x06);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x43); db(0xfa); db(0x0d); db(0xf5);
+ db(0x2c); db(0x78); db(0x00); db(0x04); db(0x43); db(0xfa); db(0x0d); db(0xfd);
  db(0x70); db(0x24); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x4a); db(0x80);
  db(0x66); db(0x0e); db(0x08); db(0x87); db(0x00); db(0x02); db(0x43); db(0xfa);
- db(0x0d); db(0xe3); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
+ db(0x0d); db(0xeb); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
  db(0x28); db(0x40); db(0x20); db(0x3c); db(0x00); db(0x00); db(0x02); db(0x2c);
  db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae);
  db(0xff); db(0x3a); db(0x20); db(0x40); db(0x4a); db(0x80); db(0x67); db(0x2c);
  db(0xfe); db(0x62); db(0x4c); db(0xdf); db(0x7c); db(0xfc); db(0x4e); db(0x75);
  db(0x2c); db(0x78); db(0x00); db(0x04); db(0x93); db(0xc9); db(0x4e); db(0xae);
  db(0xfe); db(0xda); db(0x20); db(0x40); db(0x4b); db(0xe8); db(0x00); db(0x5c);
- db(0x43); db(0xfa); db(0x0d); db(0x4a); db(0x70); db(0x00); db(0x4e); db(0xae);
+ db(0x43); db(0xfa); db(0x0d); db(0x52); db(0x70); db(0x00); db(0x4e); db(0xae);
  db(0xfd); db(0xd8); db(0x24); db(0x40); db(0x20); db(0x3c); db(0x00); db(0x00);
  db(0x00); db(0xb9); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
  db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x26); db(0x40); db(0x7c); db(0x00);
  db(0x26); db(0x86); db(0x27); db(0x46); db(0x00); db(0x04); db(0x27); db(0x46);
  db(0x00); db(0x08); db(0x27); db(0x4a); db(0x00); db(0xa0); db(0x50); db(0xeb);
  db(0x00); db(0x9e); db(0x93); db(0xc9); db(0x4e); db(0xae); db(0xfe); db(0xda);
- db(0x27); db(0x40); db(0x00); db(0xb0); db(0x41); db(0xfa); db(0x0c); db(0x32);
- db(0x70); db(0x00); db(0x72); db(0x00); db(0x61); db(0x00); db(0x02); db(0x84);
- db(0x27); db(0x40); db(0x00); db(0xa4); db(0x41); db(0xfa); db(0x0c); db(0x2f);
- db(0x70); db(0x00); db(0x72); db(0x00); db(0x61); db(0x00); db(0x02); db(0x74);
+ db(0x27); db(0x40); db(0x00); db(0xb0); db(0x41); db(0xfa); db(0x0c); db(0x3a);
+ db(0x70); db(0x00); db(0x72); db(0x00); db(0x61); db(0x00); db(0x02); db(0x8e);
+ db(0x27); db(0x40); db(0x00); db(0xa4); db(0x41); db(0xfa); db(0x0c); db(0x37);
+ db(0x70); db(0x00); db(0x72); db(0x00); db(0x61); db(0x00); db(0x02); db(0x7e);
  db(0x27); db(0x40); db(0x00); db(0xa8); db(0x7a); db(0x00); db(0x20); db(0x4d);
  db(0x4e); db(0xae); db(0xfe); db(0x80); db(0x20); db(0x4d); db(0x4e); db(0xae);
  db(0xfe); db(0x8c); db(0x28); db(0x40); db(0x26); db(0x2c); db(0x00); db(0x0a);
- db(0x30); db(0x3c); db(0xff); db(0x40); db(0x61); db(0x00); db(0x01); db(0xb2);
+ db(0x30); db(0x3c); db(0xff); db(0x40); db(0x61); db(0x00); db(0x01); db(0xbc);
  db(0x70); db(0x00); db(0x4e); db(0x90); db(0x24); db(0x00); db(0x70); db(0x01);
  db(0x61); db(0x00); db(0xfa); db(0x38); db(0x08); db(0x02); db(0x00); db(0x01);
  db(0x67); db(0x06); db(0x70); db(0x01); db(0x61); db(0x00); db(0xfb); db(0xa0);
- db(0x60); db(0x00); db(0x00); db(0xf8); db(0x20); db(0x4d); db(0x4e); db(0xae);
+ db(0x60); db(0x00); db(0x01); db(0x02); db(0x20); db(0x4d); db(0x4e); db(0xae);
  db(0xfe); db(0x8c); db(0x28); db(0x40); db(0x4a); db(0x80); db(0x66); db(0x10);
  db(0x70); db(0x00); db(0x12); db(0x2d); db(0x00); db(0x0f); db(0x03); db(0xc0);
  db(0x08); db(0xc0); db(0x00); db(0x0d); db(0x4e); db(0xae); db(0xfe); db(0xc2);
  db(0x4a); db(0x2b); db(0x00); db(0xac); db(0x67); db(0x08); db(0x61); db(0x00);
  db(0xfc); db(0x4c); db(0x42); db(0x2b); db(0x00); db(0xac); db(0x20); db(0x0c);
- db(0x67); db(0xd2); db(0x0c); db(0x6c); db(0x00); db(0x26); db(0x00); db(0x12);
+ db(0x67); db(0x54); db(0x0c); db(0x6c); db(0x00); db(0x26); db(0x00); db(0x12);
  db(0x66); db(0x4c); db(0x0c); db(0xac); db(0x40); db(0x00); db(0x00); db(0x00);
  db(0x00); db(0x14); db(0x66); db(0x42); db(0x0c); db(0x6c); db(0x12); db(0x34);
  db(0x00); db(0x18); db(0x66); db(0x3a); db(0x20); db(0x6c); db(0x00); db(0x1a);
  db(0x00); db(0x0c); db(0x20); db(0x68); db(0x00); db(0x10); db(0x22); db(0x4c);
  db(0x12); db(0xbc); db(0x00); db(0x08); db(0x4e); db(0xae); db(0xfe); db(0x92);
  db(0x60); db(0x8a); db(0x22); db(0x4c); db(0x70); db(0x26); db(0x4e); db(0xae);
- db(0xff); db(0x2e); db(0x60); db(0x00); db(0xff); db(0x80); db(0x26); db(0x2c);
- db(0x00); db(0x0a); db(0x66); db(0x3e); db(0x30); db(0x3c); db(0xff); db(0x50);
- db(0x61); db(0x00); db(0x01); db(0x06); db(0x70); db(0x01); db(0x4e); db(0x90);
+ db(0xff); db(0x2e); db(0x60); db(0x00); db(0xff); db(0x80); db(0x74); db(0xfe);
+ db(0x20); db(0x0c); db(0x67); db(0x14); db(0x26); db(0x2c); db(0x00); db(0x0a);
+ db(0x66); db(0x42); db(0x74); db(0xff); db(0x30); db(0x3c); db(0xff); db(0x50);
+ db(0x61); db(0x00); db(0x01); db(0x08); db(0x70); db(0x01); db(0x4e); db(0x90);
  db(0x45); db(0xeb); db(0x00); db(0x04); db(0x20); db(0x52); db(0x20); db(0x08);
- db(0x67); db(0x00); db(0xff); db(0x62); db(0x22); db(0x50); db(0x20); db(0x40);
- db(0x20); db(0x28); db(0x00); db(0x04); db(0x6a); db(0x16); db(0x48); db(0xe7);
- db(0x00); db(0xc0); db(0x28); db(0x68); db(0x00); db(0x0a); db(0x61); db(0x4a);
- db(0x53); db(0x85); db(0x4c); db(0xdf); db(0x03); db(0x00); db(0x24); db(0x89);
- db(0x20); db(0x49); db(0x60); db(0xda); db(0x24); db(0x48); db(0x20); db(0x49);
- db(0x60); db(0xd4); db(0x0c); db(0x85); db(0x00); db(0x00); db(0x00); db(0x14);
- db(0x65); db(0x00); db(0x00); db(0x0a); db(0x70); db(0x01); db(0x29); db(0x40);
- db(0x00); db(0x04); db(0x60); db(0x12); db(0x61); db(0x5c); db(0x30); db(0x3c);
- db(0xff); db(0x30); db(0x61); db(0x00); db(0x00); db(0xb4); db(0x4e); db(0x90);
- db(0x4a); db(0x80); db(0x67); db(0x0e); db(0x52); db(0x85); db(0x28); db(0xab);
- db(0x00); db(0x04); db(0x27); db(0x4c); db(0x00); db(0x04); db(0x60); db(0x00);
- db(0xff); db(0x0c); db(0x28); db(0x43); db(0x61); db(0x04); db(0x60); db(0x00);
- db(0xff); db(0x04); db(0x0c); db(0xac); db(0x00); db(0x00); db(0x00); db(0x1f);
- db(0x00); db(0x08); db(0x66); db(0x04); db(0x61); db(0x00); db(0xfb); db(0x4c);
- db(0x0c); db(0xac); db(0x00); db(0x00); db(0x04); db(0x09); db(0x00); db(0x08);
- db(0x66); db(0x12); db(0x61); db(0x00); db(0xfb); db(0x7a); db(0x66); db(0x0c);
- db(0x30); db(0x3c); db(0xff); db(0x58); db(0x61); db(0x00); db(0x00); db(0x72);
- db(0x4e); db(0x90); db(0x60); db(0xee); db(0x22); db(0x54); db(0x20); db(0x6c);
- db(0x00); db(0x04); db(0x29); db(0x4d); db(0x00); db(0x04); db(0x4e); db(0xee);
- db(0xfe); db(0x92); db(0x2f); db(0x05); db(0x7a); db(0xfc); db(0x24); db(0x53);
- db(0x2e); db(0x0a); db(0x22); db(0x0a); db(0x67); db(0x00); db(0x00); db(0x0c);
- db(0x52); db(0x85); db(0x67); db(0x1e); db(0x22); db(0x4a); db(0x24); db(0x52);
- db(0x60); db(0xf0); db(0x52); db(0x85); db(0x67); db(0x3c); db(0x24); db(0x47);
- db(0x70); db(0x18); db(0x72); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a);
- db(0x52); db(0x46); db(0x24); db(0x40); db(0x24); db(0x87); db(0x2e); db(0x0a);
- db(0x60); db(0xe8); db(0x20); db(0x12); db(0x67); db(0x24); db(0x20); db(0x40);
- db(0x20); db(0x10); db(0x67); db(0x1e); db(0x20); db(0x40); db(0x20); db(0x10);
- db(0x67); db(0x18); db(0x70); db(0x00); db(0x22); db(0x80); db(0x22); db(0x4a);
- db(0x24); db(0x51); db(0x70); db(0x18); db(0x4e); db(0xae); db(0xff); db(0x2e);
- db(0x06); db(0x86); db(0x00); db(0x01); db(0x00); db(0x00); db(0x20); db(0x0a);
- db(0x66); db(0xec); db(0x26); db(0x87); db(0x2a); db(0x1f); db(0x4e); db(0x75);
- db(0x41); db(0xfa); db(0xf3); db(0x6a); db(0x02); db(0x80); db(0x00); db(0x00);
- db(0xff); db(0xff); db(0xd1); db(0xc0); db(0x4e); db(0x75); db(0x20); db(0x88);
- db(0x58); db(0x90); db(0x42); db(0xa8); db(0x00); db(0x04); db(0x21); db(0x48);
- db(0x00); db(0x08); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x20); db(0x22);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x70); db(0xff); db(0x4e); db(0xae);
- db(0xfe); db(0xb6); db(0x91); db(0xc8); db(0x24); db(0x00); db(0x6b); db(0x32);
- db(0x70); db(0x22); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
- db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x91); db(0xc8); db(0x24); db(0x40);
- db(0x4a); db(0x80); db(0x67); db(0x1e); db(0x15); db(0x7c); db(0x00); db(0x04);
- db(0x00); db(0x08); db(0x15); db(0x42); db(0x00); db(0x0f); db(0x93); db(0xc9);
- db(0x4e); db(0xae); db(0xfe); db(0xda); db(0x25); db(0x40); db(0x00); db(0x10);
- db(0x41); db(0xea); db(0x00); db(0x14); db(0x61); db(0x00); db(0xff); db(0xb0);
- db(0x20); db(0x4a); db(0x20); db(0x08); db(0x4c); db(0xdf); db(0x44); db(0x04);
- db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x20); db(0x22); db(0x2c); db(0x78);
- db(0x00); db(0x04); db(0x4a); db(0x80); db(0x67); db(0x24); db(0x24); db(0x40);
- db(0x24); db(0x01); db(0x66); db(0x02); db(0x74); db(0x30); db(0x20); db(0x02);
- db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae);
- db(0xff); db(0x3a); db(0x20); db(0x40); db(0x11); db(0x7c); db(0x00); db(0x0a);
- db(0x00); db(0x08); db(0x31); db(0x42); db(0x00); db(0x12); db(0x21); db(0x4a);
- db(0x00); db(0x0e); db(0x4a); db(0x80); db(0x4c); db(0xdf); db(0x44); db(0x04);
- db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x30); db(0x22); db(0x24); db(0x48);
- db(0x24); db(0x00); db(0x26); db(0x01); db(0x2c); db(0x78); db(0x00); db(0x04);
- db(0x61); db(0x00); db(0xff); db(0x6a); db(0x22); db(0x03); db(0x61); db(0x00);
- db(0xff); db(0xb2); db(0x67); db(0x18); db(0x20); db(0x4a); db(0x22); db(0x40);
- db(0x24); db(0x40); db(0x20); db(0x02); db(0x72); db(0x00); db(0x4e); db(0xae);
- db(0xfe); db(0x44); db(0x22); db(0x00); db(0x70); db(0x00); db(0x4a); db(0x81);
- db(0x66); db(0x02); db(0x20); db(0x0a); db(0x4a); db(0x80); db(0x4c); db(0xdf);
- db(0x44); db(0x0c); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x38); db(0x32);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x28); db(0x00); db(0x24); db(0x08);
- db(0x26); db(0x09); db(0x20); db(0x3c); db(0x00); db(0x00); db(0x08); db(0x5c);
- db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01); db(0x4e); db(0xae);
- db(0xff); db(0x3a); db(0x4a); db(0x80); db(0x67); db(0x00); db(0x00); db(0x34);
- db(0x24); db(0x40); db(0x15); db(0x7c); db(0x00); db(0x01); db(0x00); db(0x08);
- db(0x15); db(0x44); db(0x00); db(0x09); db(0x25); db(0x42); db(0x00); db(0x0a);
- db(0x47); db(0xea); db(0x00); db(0x5c); db(0x25); db(0x4b); db(0x00); db(0x3a);
- db(0x47); db(0xeb); db(0x08); db(0x00); db(0x25); db(0x4b); db(0x00); db(0x3e);
- db(0x25); db(0x4b); db(0x00); db(0x36); db(0x22); db(0x4a); db(0x24); db(0x43);
- db(0x97); db(0xcb); db(0x24); db(0x09); db(0x4e); db(0xae); db(0xfe); db(0xe6);
- db(0x20); db(0x02); db(0x4c); db(0xdf); db(0x4c); db(0x1c); db(0x4e); db(0x75);
- db(0x41); db(0xfa); db(0x09); db(0x9e); db(0x43); db(0xfa); db(0x01); db(0x5c);
- db(0x70); db(0x13); db(0x61); db(0x00); db(0xff); db(0x98); db(0x4e); db(0x75);
- db(0x22); db(0x6d); db(0x02); db(0x0c); db(0x33); db(0x7c); db(0x00); db(0x0a);
- db(0x00); db(0x1c); db(0x13); db(0x7c); db(0x00); db(0x01); db(0x00); db(0x1e);
- db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x22); db(0x6d); db(0x02); db(0x0c);
- db(0x25); db(0x69); db(0x00); db(0x20); db(0x00); db(0x0e); db(0x25); db(0x69);
- db(0x00); db(0x24); db(0x00); db(0x12); db(0x22); db(0x6d); db(0x02); db(0x08);
- db(0x13); db(0x7c); db(0x00); db(0x01); db(0x00); db(0x1e); db(0x4e); db(0xae);
- db(0xfe); db(0x38); db(0x4e); db(0x75); db(0x42); db(0xaa); db(0x00); db(0x0e);
- db(0x42); db(0xaa); db(0x00); db(0x12); db(0x22); db(0x6d); db(0x02); db(0x08);
- db(0x13); db(0x7c); db(0x00); db(0x01); db(0x00); db(0x1e); db(0x4e); db(0xae);
- db(0xfe); db(0x38); db(0x4e); db(0x75); db(0x00); db(0x00); db(0xff); db(0xff);
- db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00);
+ db(0x67); db(0x00); db(0xff); db(0x5a); db(0x22); db(0x50); db(0x20); db(0x40);
+ db(0x20); db(0x28); db(0x00); db(0x04); db(0xb4); db(0x80); db(0x66); db(0x16);
+ db(0x48); db(0xe7); db(0x00); db(0xc0); db(0x28); db(0x68); db(0x00); db(0x0a);
+ db(0x61); db(0x4a); db(0x53); db(0x85); db(0x4c); db(0xdf); db(0x03); db(0x00);
+ db(0x24); db(0x89); db(0x20); db(0x49); db(0x60); db(0xd8); db(0x24); db(0x48);
+ db(0x20); db(0x49); db(0x60); db(0xd2); db(0x0c); db(0x85); db(0x00); db(0x00);
+ db(0x00); db(0x14); db(0x65); db(0x00); db(0x00); db(0x0a); db(0x70); db(0x01);
+ db(0x29); db(0x40); db(0x00); db(0x04); db(0x60); db(0x12); db(0x61); db(0x5c);
+ db(0x30); db(0x3c); db(0xff); db(0x30); db(0x61); db(0x00); db(0x00); db(0xb4);
+ db(0x4e); db(0x90); db(0x4a); db(0x80); db(0x67); db(0x0e); db(0x52); db(0x85);
+ db(0x28); db(0xab); db(0x00); db(0x04); db(0x27); db(0x4c); db(0x00); db(0x04);
+ db(0x60); db(0x00); db(0xff); db(0x02); db(0x28); db(0x43); db(0x61); db(0x04);
+ db(0x60); db(0x00); db(0xfe); db(0xfa); db(0x0c); db(0xac); db(0x00); db(0x00);
+ db(0x00); db(0x1f); db(0x00); db(0x08); db(0x66); db(0x04); db(0x61); db(0x00);
+ db(0xfb); db(0x42); db(0x0c); db(0xac); db(0x00); db(0x00); db(0x04); db(0x09);
+ db(0x00); db(0x08); db(0x66); db(0x12); db(0x61); db(0x00); db(0xfb); db(0x70);
+ db(0x66); db(0x0c); db(0x30); db(0x3c); db(0xff); db(0x58); db(0x61); db(0x00);
+ db(0x00); db(0x72); db(0x4e); db(0x90); db(0x60); db(0xee); db(0x22); db(0x54);
+ db(0x20); db(0x6c); db(0x00); db(0x04); db(0x29); db(0x4d); db(0x00); db(0x04);
+ db(0x4e); db(0xee); db(0xfe); db(0x92); db(0x2f); db(0x05); db(0x7a); db(0xfc);
+ db(0x24); db(0x53); db(0x2e); db(0x0a); db(0x22); db(0x0a); db(0x67); db(0x00);
+ db(0x00); db(0x0c); db(0x52); db(0x85); db(0x67); db(0x1e); db(0x22); db(0x4a);
+ db(0x24); db(0x52); db(0x60); db(0xf0); db(0x52); db(0x85); db(0x67); db(0x3c);
+ db(0x24); db(0x47); db(0x70); db(0x18); db(0x72); db(0x01); db(0x4e); db(0xae);
+ db(0xff); db(0x3a); db(0x52); db(0x46); db(0x24); db(0x40); db(0x24); db(0x87);
+ db(0x2e); db(0x0a); db(0x60); db(0xe8); db(0x20); db(0x12); db(0x67); db(0x24);
+ db(0x20); db(0x40); db(0x20); db(0x10); db(0x67); db(0x1e); db(0x20); db(0x40);
+ db(0x20); db(0x10); db(0x67); db(0x18); db(0x70); db(0x00); db(0x22); db(0x80);
+ db(0x22); db(0x4a); db(0x24); db(0x51); db(0x70); db(0x18); db(0x4e); db(0xae);
+ db(0xff); db(0x2e); db(0x06); db(0x86); db(0x00); db(0x01); db(0x00); db(0x00);
+ db(0x20); db(0x0a); db(0x66); db(0xec); db(0x26); db(0x87); db(0x2a); db(0x1f);
+ db(0x4e); db(0x75); db(0x41); db(0xfa); db(0xf3); db(0x60); db(0x02); db(0x80);
+ db(0x00); db(0x00); db(0xff); db(0xff); db(0xd1); db(0xc0); db(0x4e); db(0x75);
+ db(0x20); db(0x88); db(0x58); db(0x90); db(0x42); db(0xa8); db(0x00); db(0x04);
+ db(0x21); db(0x48); db(0x00); db(0x08); db(0x4e); db(0x75); db(0x48); db(0xe7);
+ db(0x20); db(0x22); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x70); db(0xff);
+ db(0x4e); db(0xae); db(0xfe); db(0xb6); db(0x91); db(0xc8); db(0x24); db(0x00);
+ db(0x6b); db(0x32); db(0x70); db(0x22); db(0x22); db(0x3c); db(0x00); db(0x01);
+ db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x91); db(0xc8);
+ db(0x24); db(0x40); db(0x4a); db(0x80); db(0x67); db(0x1e); db(0x15); db(0x7c);
+ db(0x00); db(0x04); db(0x00); db(0x08); db(0x15); db(0x42); db(0x00); db(0x0f);
+ db(0x93); db(0xc9); db(0x4e); db(0xae); db(0xfe); db(0xda); db(0x25); db(0x40);
+ db(0x00); db(0x10); db(0x41); db(0xea); db(0x00); db(0x14); db(0x61); db(0x00);
+ db(0xff); db(0xb0); db(0x20); db(0x4a); db(0x20); db(0x08); db(0x4c); db(0xdf);
+ db(0x44); db(0x04); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x20); db(0x22);
+ db(0x2c); db(0x78); db(0x00); db(0x04); db(0x4a); db(0x80); db(0x67); db(0x24);
+ db(0x24); db(0x40); db(0x24); db(0x01); db(0x66); db(0x02); db(0x74); db(0x30);
+ db(0x20); db(0x02); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x20); db(0x40); db(0x11); db(0x7c);
+ db(0x00); db(0x0a); db(0x00); db(0x08); db(0x31); db(0x42); db(0x00); db(0x12);
+ db(0x21); db(0x4a); db(0x00); db(0x0e); db(0x4a); db(0x80); db(0x4c); db(0xdf);
+ db(0x44); db(0x04); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x30); db(0x22);
+ db(0x24); db(0x48); db(0x24); db(0x00); db(0x26); db(0x01); db(0x2c); db(0x78);
+ db(0x00); db(0x04); db(0x61); db(0x00); db(0xff); db(0x6a); db(0x22); db(0x03);
+ db(0x61); db(0x00); db(0xff); db(0xb2); db(0x67); db(0x18); db(0x20); db(0x4a);
+ db(0x22); db(0x40); db(0x24); db(0x40); db(0x20); db(0x02); db(0x72); db(0x00);
+ db(0x4e); db(0xae); db(0xfe); db(0x44); db(0x22); db(0x00); db(0x70); db(0x00);
+ db(0x4a); db(0x81); db(0x66); db(0x02); db(0x20); db(0x0a); db(0x4a); db(0x80);
+ db(0x4c); db(0xdf); db(0x44); db(0x0c); db(0x4e); db(0x75); db(0x48); db(0xe7);
+ db(0x38); db(0x32); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x28); db(0x00);
+ db(0x24); db(0x08); db(0x26); db(0x09); db(0x20); db(0x3c); db(0x00); db(0x00);
+ db(0x08); db(0x5c); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
+ db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x4a); db(0x80); db(0x67); db(0x00);
+ db(0x00); db(0x34); db(0x24); db(0x40); db(0x15); db(0x7c); db(0x00); db(0x01);
+ db(0x00); db(0x08); db(0x15); db(0x44); db(0x00); db(0x09); db(0x25); db(0x42);
+ db(0x00); db(0x0a); db(0x47); db(0xea); db(0x00); db(0x5c); db(0x25); db(0x4b);
+ db(0x00); db(0x3a); db(0x47); db(0xeb); db(0x08); db(0x00); db(0x25); db(0x4b);
+ db(0x00); db(0x3e); db(0x25); db(0x4b); db(0x00); db(0x36); db(0x22); db(0x4a);
+ db(0x24); db(0x43); db(0x97); db(0xcb); db(0x24); db(0x09); db(0x4e); db(0xae);
+ db(0xfe); db(0xe6); db(0x20); db(0x02); db(0x4c); db(0xdf); db(0x4c); db(0x1c);
+ db(0x4e); db(0x75); db(0x41); db(0xfa); db(0x09); db(0x9c); db(0x43); db(0xfa);
+ db(0x01); db(0x5c); db(0x70); db(0x13); db(0x61); db(0x00); db(0xff); db(0x98);
+ db(0x4e); db(0x75); db(0x22); db(0x6d); db(0x02); db(0x0c); db(0x33); db(0x7c);
+ db(0x00); db(0x0a); db(0x00); db(0x1c); db(0x13); db(0x7c); db(0x00); db(0x01);
+ db(0x00); db(0x1e); db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x22); db(0x6d);
+ db(0x02); db(0x0c); db(0x25); db(0x69); db(0x00); db(0x20); db(0x00); db(0x0e);
+ db(0x25); db(0x69); db(0x00); db(0x24); db(0x00); db(0x12); db(0x22); db(0x6d);
+ db(0x02); db(0x08); db(0x13); db(0x7c); db(0x00); db(0x01); db(0x00); db(0x1e);
+ db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x4e); db(0x75); db(0x42); db(0xaa);
+ db(0x00); db(0x0e); db(0x42); db(0xaa); db(0x00); db(0x12); db(0x22); db(0x6d);
+ db(0x02); db(0x08); db(0x13); db(0x7c); db(0x00); db(0x01); db(0x00); db(0x1e);
+ db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x4e); db(0x75); db(0x00); db(0x00);
+ db(0xff); db(0xff); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00);
  db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00);
  db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00);
  db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00);
  db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00);
- db(0x48); db(0xe7); db(0xf8); db(0xfe); db(0x2a); db(0x48); db(0x95); db(0xca);
- db(0x97); db(0xcb); db(0x99); db(0xcc); db(0x78); db(0x00); db(0x2c); db(0x6d);
- db(0x00); db(0x18); db(0x20); db(0x6d); db(0x00); db(0x14); db(0x20); db(0x28);
- db(0x00); db(0x3c); db(0x67); db(0x5c); db(0x20); db(0x40); db(0x41); db(0xe8);
- db(0x00); db(0x2c); db(0x28); db(0x48); db(0x4e); db(0xae); db(0xfc); db(0xe8);
- db(0x72); db(0xff); db(0x74); db(0xff); db(0xb2); db(0x80); db(0x67); db(0x48);
- db(0x26); db(0x00); db(0x2c); db(0x6d); db(0x00); db(0x14); db(0x41); db(0xed);
- db(0x00); db(0xc0); db(0x70); db(0x66); db(0x4e); db(0xae); db(0xff); db(0x7c);
- db(0x41); db(0xed); db(0x00); db(0xc0); db(0x38); db(0x28); db(0x00); db(0x64);
- db(0x2c); db(0x6d); db(0x00); db(0x18); db(0x91); db(0xc8); db(0x43); db(0xed);
- db(0x00); db(0x38); db(0x70); db(0x00); db(0x30); db(0x3c); db(0x00); db(0x58);
- db(0x22); db(0x3c); db(0x80); db(0x00); db(0x10); db(0x00); db(0x24); db(0x03);
- db(0x4e); db(0xae); db(0xfd); db(0x0c); db(0x72); db(0xff); db(0x74); db(0xff);
- db(0x4a); db(0x80); db(0x6b); db(0x0c); db(0x45); db(0xed); db(0x00); db(0x38);
- db(0x22); db(0x2a); db(0x00); db(0x32); db(0x24); db(0x2a); db(0x00); db(0x36);
- db(0x20); db(0x2c); db(0x00); db(0x1c); db(0xb8); db(0x6d); db(0x00); db(0x2c);
- db(0x66); db(0x12); db(0xb0); db(0xad); db(0x00); db(0x28); db(0x66); db(0x0c);
- db(0xb2); db(0xad); db(0x00); db(0x20); db(0x66); db(0x06); db(0xb4); db(0xad);
- db(0x00); db(0x24); db(0x67); db(0x40); db(0x2b); db(0x40); db(0x00); db(0x28);
- db(0x2b); db(0x41); db(0x00); db(0x20); db(0x2b); db(0x42); db(0x00); db(0x24);
- db(0x3b); db(0x44); db(0x00); db(0x2c); db(0x91); db(0xc8); db(0x43); db(0xed);
- db(0x00); db(0x90); db(0x70); db(0x00); db(0x30); db(0x3c); db(0x00); db(0x58);
- db(0x22); db(0x3c); db(0x80); db(0x00); db(0x00); db(0x00); db(0x24); db(0x03);
- db(0x4e); db(0xae); db(0xfd); db(0x0c); db(0x4a); db(0x80); db(0x6b); db(0x04);
- db(0x47); db(0xed); db(0x00); db(0x90); db(0x34); db(0x2d); db(0x00); db(0x2c);
- db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x01); db(0x61); db(0x00);
- db(0xfd); db(0x70); db(0x4e); db(0x90); db(0x4c); db(0xdf); db(0x7f); db(0x1f);
- db(0x4e); db(0x75); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x3e); db(0x2e);
- db(0x00); db(0x14); db(0x70); db(0xff); db(0x4e); db(0xae); db(0xfe); db(0xb6);
- db(0x7c); db(0x00); db(0x01); db(0xc6); db(0x93); db(0xc9); db(0x4e); db(0xae);
- db(0xfe); db(0xda); db(0x28); db(0x40); db(0x70); db(0x14); db(0x22); db(0x4c);
- db(0x4e); db(0xae); db(0xfe); db(0xd4); db(0x70); db(0x00); db(0x30); db(0x3c);
- db(0x02); db(0x10); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
- db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x2a); db(0x40); db(0x47); db(0xed);
- db(0x00); db(0x16); db(0x27); db(0x4e); db(0x00); db(0x10); db(0x27); db(0x4c);
- db(0x00); db(0x08); db(0x27); db(0x46); db(0x00); db(0x0c); db(0x70); db(0xff);
- db(0x37); db(0x40); db(0x00); db(0x00); db(0x43); db(0xed); db(0x00); db(0x00);
- db(0x13); db(0x7c); db(0x00); db(0x02); db(0x00); db(0x08); db(0x13); db(0x7c);
- db(0x00); db(0x05); db(0x00); db(0x09); db(0x41); db(0xfa); db(0x07); db(0xe2);
- db(0x23); db(0x48); db(0x00); db(0x0a); db(0x41); db(0xfa); db(0x02); db(0xda);
- db(0x23); db(0x48); db(0x00); db(0x12); db(0x23); db(0x4d); db(0x00); db(0x0e);
- db(0x70); db(0x05); db(0x4e); db(0xae); db(0xff); db(0x58); db(0x20); db(0x06);
- db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x70); db(0x00); db(0x53); db(0xab);
- db(0x00); db(0x1c); db(0x6a); db(0x06); db(0x70); db(0x0a); db(0x27); db(0x40);
- db(0x00); db(0x1c); db(0x4a); db(0xab); db(0x00); db(0x14); db(0x66); db(0x16);
- db(0x4a); db(0xab); db(0x00); db(0x1c); db(0x66); db(0xe0); db(0x43); db(0xfa);
- db(0x08); db(0x00); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
- db(0x27); db(0x40); db(0x00); db(0x14); db(0x67); db(0xd0); db(0x4a); db(0xab);
- db(0x00); db(0x18); db(0x66); db(0x18); db(0x4a); db(0xab); db(0x00); db(0x1c);
- db(0x66); db(0xc4); db(0x43); db(0xfa); db(0x07); db(0xf6); db(0x70); db(0x00);
- db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x27); db(0x40); db(0x00); db(0x18);
- db(0x67); db(0x00); db(0xff); db(0xb4); db(0x4a); db(0xad); db(0x02); db(0x08);
- db(0x66); db(0x38); db(0x4a); db(0xab); db(0x00); db(0x1c); db(0x66); db(0xa6);
- db(0x4e); db(0xae); db(0xff); db(0x7c); db(0x41); db(0xee); db(0x01); db(0x5e);
- db(0x43); db(0xfa); db(0x06); db(0xd6); db(0x4e); db(0xae); db(0xfe); db(0xec);
- db(0x24); db(0x00); db(0x4e); db(0xae); db(0xff); db(0x76); db(0x4a); db(0x82);
- db(0x67); db(0x8c); db(0x41); db(0xfa); db(0x06); db(0xc4); db(0x70); db(0x00);
- db(0x72); db(0x00); db(0x61); db(0x00); db(0xfd); db(0x16); db(0x2b); db(0x40);
- db(0x02); db(0x08); db(0x67); db(0x00); db(0x02); db(0x42); db(0x60); db(0x00);
- db(0xff); db(0x76); db(0x4a); db(0xad); db(0x02); db(0x0c); db(0x66); db(0x48);
- db(0x4a); db(0xab); db(0x00); db(0x1c); db(0x66); db(0x00); db(0xff); db(0x68);
- db(0x4e); db(0xae); db(0xff); db(0x7c); db(0x41); db(0xee); db(0x01); db(0x5e);
- db(0x43); db(0xfa); db(0x06); db(0xa3); db(0x4e); db(0xae); db(0xfe); db(0xec);
- db(0x24); db(0x00); db(0x4e); db(0xae); db(0xff); db(0x76); db(0x4a); db(0x82);
- db(0x67); db(0x00); db(0xff); db(0x4c); db(0x41); db(0xfa); db(0x06); db(0x8f);
- db(0x70); db(0x00); db(0x72); db(0x00); db(0x61); db(0x00); db(0xfc); db(0xd4);
- db(0x2b); db(0x40); db(0x02); db(0x0c); db(0x67); db(0x00); db(0x02); db(0x00);
- db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x00); db(0x61); db(0x00);
- db(0xfc); db(0x20); db(0x4e); db(0x90); db(0x60); db(0x00); db(0xff); db(0x28);
- db(0x0c); db(0x47); db(0x00); db(0x24); db(0x65); db(0x12); db(0x53); db(0xab);
- db(0x00); db(0x34); db(0x6a); db(0x0c); db(0x20); db(0x4b); db(0x61); db(0x00);
- db(0xfd); db(0xc8); db(0x70); db(0x32); db(0x27); db(0x40); db(0x00); db(0x34);
- db(0x22); db(0x6d); db(0x02); db(0x08); db(0x45); db(0xed); db(0x01); db(0x3c);
- db(0x33); db(0x7c); db(0x00); db(0x0b); db(0x00); db(0x1c); db(0x23); db(0x7c);
- db(0x00); db(0x00); db(0x00); db(0x16); db(0x00); db(0x24); db(0x23); db(0x4a);
- db(0x00); db(0x28); db(0x10); db(0x3a); db(0xfd); db(0x78); db(0x0c); db(0x47);
- db(0x00); db(0x27); db(0x65); db(0x00); db(0x01); db(0x62); db(0x08); db(0x00);
- db(0x00); db(0x01); db(0x67); db(0x00); db(0x01); db(0x5a); db(0x41); db(0xed);
- db(0x01); db(0x68); db(0x25); db(0x48); db(0x00); db(0x0a); db(0x15); db(0x7c);
- db(0x00); db(0x13); db(0x00); db(0x04); db(0x15); db(0x7c); db(0x00); db(0x03);
- db(0x00); db(0x05); db(0x42); db(0x90); db(0x42); db(0xa8); db(0x00); db(0x04);
- db(0x42); db(0x6a); db(0x00); db(0x06); db(0x42); db(0xa8); db(0x00); db(0x08);
- db(0x42); db(0x68); db(0x00); db(0x0c); db(0x22); db(0x3a); db(0xfd); db(0x60);
- db(0x02); db(0x41); db(0x00); db(0x07); db(0x70); db(0x07); db(0x90); db(0x41);
- db(0xe1); db(0x48); db(0xe9); db(0x48); db(0x35); db(0x40); db(0x00); db(0x08);
- db(0x31); db(0x7a); db(0xfd); db(0x34); db(0x00); db(0x0e); db(0x42); db(0x68);
- db(0x00); db(0x10); db(0x31); db(0x7a); db(0xfd); db(0x2c); db(0x00); db(0x12);
- db(0x42); db(0x68); db(0x00); db(0x14); db(0x31); db(0x7a); db(0xfd); db(0x1a);
- db(0x00); db(0x16); db(0x42); db(0x68); db(0x00); db(0x18); db(0x31); db(0x7a);
- db(0xfd); db(0x12); db(0x00); db(0x1a); db(0x43); db(0xed); db(0x01); db(0x88);
- db(0x21); db(0x49); db(0x00); db(0x1c); db(0x22); db(0xfc); db(0x80); db(0x03);
- db(0xa0); db(0x06); db(0x30); db(0x3a); db(0xfd); db(0x18); db(0x48); db(0xc0);
- db(0xe1); db(0x80); db(0x22); db(0xc0); db(0x22); db(0xfc); db(0x80); db(0x03);
- db(0xa0); db(0x07); db(0x22); db(0xfa); db(0xfd); db(0x0a); db(0x70); db(0x00);
- db(0x30); db(0x3a); db(0xfc); db(0xf2); db(0x6b); db(0x08); db(0x22); db(0xfc);
- db(0x80); db(0x03); db(0xa0); db(0x09); db(0x22); db(0xc0); db(0x30); db(0x3a);
- db(0xfc); db(0xe6); db(0x6b); db(0x08); db(0x22); db(0xfc); db(0x80); db(0x03);
- db(0xa0); db(0x0a); db(0x22); db(0xc0); db(0x30); db(0x3a); db(0xfc); db(0xce);
- db(0x6b); db(0x14); db(0x22); db(0xfc); db(0x80); db(0x03); db(0xa0); db(0x02);
- db(0x22); db(0xc0); db(0x30); db(0x3a); db(0xfc); db(0xc6); db(0x22); db(0xfc);
- db(0x80); db(0x03); db(0xa0); db(0x01); db(0x22); db(0xc0); db(0x30); db(0x3a);
- db(0xfc); db(0xc0); db(0x6b); db(0x10); db(0x22); db(0xfc); db(0x80); db(0x03);
- db(0xa0); db(0x03); db(0x30); db(0x3a); db(0xfc); db(0xba); db(0x48); db(0xc0);
- db(0xe1); db(0x80); db(0x22); db(0xc0); db(0x30); db(0x3a); db(0xfc); db(0xac);
- db(0x6b); db(0x10); db(0x22); db(0xfc); db(0x80); db(0x03); db(0xa0); db(0x04);
- db(0x30); db(0x3a); db(0xfc); db(0xa6); db(0x48); db(0xc0); db(0xe1); db(0x80);
- db(0x22); db(0xc0); db(0x30); db(0x3a); db(0xfc); db(0x98); db(0x6b); db(0x10);
- db(0x22); db(0xfc); db(0x80); db(0x03); db(0xa0); db(0x05); db(0x30); db(0x3a);
- db(0xfc); db(0x92); db(0x48); db(0xc0); db(0xe1); db(0x80); db(0x22); db(0xc0);
- db(0x70); db(0x00); db(0x30); db(0x3a); db(0xfc); db(0x8e); db(0x6b); db(0x08);
- db(0x22); db(0xfc); db(0x80); db(0x03); db(0xa0); db(0x08); db(0x22); db(0xc0);
- db(0x42); db(0x91); db(0x61); db(0x00); db(0xfc); db(0x40); db(0x36); db(0x3c);
- db(0x00); db(0x68); db(0x74); db(0x01); db(0x28); db(0x3a); db(0xfc); db(0x70);
- db(0x20); db(0x04); db(0xc0); db(0x82); db(0x22); db(0x2b); db(0x00); db(0x04);
- db(0xc2); db(0x82); db(0xb2); db(0x80); db(0x67); db(0x22); db(0x42); db(0x92);
- db(0x35); db(0x7c); db(0x02); db(0x00); db(0x00); db(0x04); db(0x42); db(0xaa);
- db(0x00); db(0x0a); db(0x32); db(0x03); db(0x4a); db(0x00); db(0x66); db(0x04);
- db(0x08); db(0xc1); db(0x00); db(0x07); db(0x35); db(0x41); db(0x00); db(0x06);
- db(0x42); db(0x6a); db(0x00); db(0x08); db(0x61); db(0x00); db(0xfc); db(0x06);
- db(0x52); db(0x43); db(0xd4); db(0x42); db(0x0c); db(0x42); db(0x00); db(0x08);
- db(0x66); db(0xc6); db(0x27); db(0x44); db(0x00); db(0x04); db(0x10); db(0x3a);
- db(0xfc); db(0x0c); db(0x08); db(0x00); db(0x00); db(0x00); db(0x67); db(0x00);
- db(0xfd); db(0x7e); db(0x42); db(0x92); db(0x35); db(0x7c); db(0x04); db(0x00);
- db(0x00); db(0x04); db(0x42); db(0x6a); db(0x00); db(0x06); db(0x42); db(0x6a);
- db(0x00); db(0x08); db(0x20); db(0x6b); db(0x00); db(0x14); db(0x30); db(0x3a);
- db(0xfc); db(0x14); db(0x32); db(0x28); db(0x00); db(0x30); db(0xd2); db(0x41);
- db(0x90); db(0x41); db(0x6a); db(0x02); db(0x70); db(0x00); db(0x35); db(0x40);
- db(0x00); db(0x0a); db(0x30); db(0x3a); db(0xfc); db(0x02); db(0x32); db(0x28);
- db(0x00); db(0x2e); db(0xd2); db(0x41); db(0x90); db(0x41); db(0x6a); db(0x02);
- db(0x70); db(0x00); db(0x35); db(0x40); db(0x00); db(0x0c); db(0x61); db(0x00);
- db(0xfb); db(0x78); db(0x60); db(0x00); db(0xfd); db(0x3a); db(0x4e); db(0x75);
- db(0x4a); db(0xa9); db(0x02); db(0x08); db(0x67); db(0x14); db(0x4a); db(0xa9);
- db(0x02); db(0x0c); db(0x67); db(0x0e); db(0x30); db(0x3a); db(0xfb); db(0xb0);
- db(0xb0); db(0x69); db(0x00); db(0x16); db(0x67); db(0x14); db(0x33); db(0x40);
- db(0x00); db(0x16); db(0x2c); db(0x69); db(0x00); db(0x26); db(0x20); db(0x29);
- db(0x00); db(0x22); db(0x22); db(0x69); db(0x00); db(0x1e); db(0x4e); db(0xae);
- db(0xfe); db(0xbc); db(0x53); db(0x69); db(0x00); db(0x46); db(0x6a); db(0x12);
- db(0x33); db(0x7c); db(0x00); db(0x32); db(0x00); db(0x46); db(0x30); db(0x3c);
- db(0xff); db(0x38); db(0x72); db(0x02); db(0x61); db(0x00); db(0xf9); db(0xea);
- db(0x4e); db(0x90); db(0x41); db(0xf9); db(0x00); db(0xdf); db(0xf0); db(0x00);
- db(0x70); db(0x00); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x00); db(0x06);
- db(0x2c); db(0x78); db(0x00); db(0x04); db(0x20); db(0x3c); db(0x00); db(0x00);
- db(0x00); db(0x88); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01);
- db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x4a); db(0x80); db(0x67); db(0x00);
- db(0x00); db(0x40); db(0x2a); db(0x40); db(0x2b); db(0x4e); db(0x00); db(0x14);
- db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x0e); db(0x61); db(0x00);
- db(0xf9); db(0xb0); db(0x20); db(0x0d); db(0x4e); db(0x90); db(0x41); db(0xfa);
- db(0x04); db(0x6a); db(0x43); db(0xfa); db(0x01); db(0x14); db(0x70); db(0xf6);
- db(0x22); db(0x3c); db(0x00); db(0x00); db(0x27); db(0x10); db(0x61); db(0x00);
- db(0xee); db(0xe6); db(0x70); db(0x00); db(0x4c); db(0xdf); db(0x60); db(0x00);
- db(0x4e); db(0x75); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x0a);
- db(0x61); db(0x00); db(0xf9); db(0x86); db(0x4e); db(0x90); db(0x4e); db(0x75);
- db(0x61); db(0xf0); db(0x20); db(0x0d); db(0x67); db(0x1c); db(0x2c); db(0x6d);
- db(0x00); db(0x14); db(0x20); db(0x2d); db(0x00); db(0x18); db(0x67); db(0x06);
- db(0x22); db(0x40); db(0x4e); db(0xae); db(0xfe); db(0x62); db(0x22); db(0x4d);
- db(0x20); db(0x3c); db(0x00); db(0x00); db(0x00); db(0x88); db(0x4e); db(0xae);
- db(0xff); db(0x2e); db(0x70); db(0x00); db(0x4e); db(0x75); db(0x48); db(0xe7);
- db(0x38); db(0x3e); db(0x2c); db(0x6d); db(0x00); db(0x18); db(0x41); db(0xfa);
- db(0x03); db(0xf8); db(0x22); db(0x08); db(0x24); db(0x3c); db(0x00); db(0x00);
- db(0x03); db(0xed); db(0x4e); db(0xae); db(0xff); db(0xe2); db(0x28); db(0x00);
- db(0x67); db(0x4c); db(0x45); db(0xed); db(0x00); db(0x68); db(0x42); db(0x92);
- db(0x34); db(0xaa); db(0x00); db(0x02); db(0x24); db(0x0a); db(0x54); db(0x82);
- db(0x76); db(0x02); db(0x22); db(0x04); db(0x4e); db(0xae); db(0xff); db(0xd6);
- db(0xb6); db(0x80); db(0x66); db(0x32); db(0x0c); db(0x92); db(0x50); db(0x4e);
- db(0x54); db(0x52); db(0x66); db(0xe4); db(0x24); db(0x0a); db(0x76); db(0x04);
- db(0x22); db(0x04); db(0x4e); db(0xae); db(0xff); db(0xd6); db(0x24); db(0x0a);
- db(0x76); db(0x20); db(0x22); db(0x04); db(0x4e); db(0xae); db(0xff); db(0xd6);
- db(0xb6); db(0x80); db(0x66); db(0x12); db(0x4a); db(0x6a); db(0x00); db(0x10);
- db(0x66); db(0xc4); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x10);
- db(0x61); db(0x00); db(0xf8); db(0xf6); db(0x4e); db(0x90); db(0x22); db(0x04);
- db(0x67); db(0x04); db(0x4e); db(0xae); db(0xff); db(0xdc); db(0x4c); db(0xdf);
- db(0x7c); db(0x1c); db(0x4e); db(0x75); db(0x2c); db(0x6d); db(0x00); db(0x18);
- db(0x41); db(0xfa); db(0x03); db(0x70); db(0x22); db(0x08); db(0x74); db(0xfe);
- db(0x4e); db(0xae); db(0xff); db(0xac); db(0x22); db(0x00); db(0x67); db(0x34);
- db(0x4e); db(0xae); db(0xff); db(0xa6); db(0x2c); db(0x6d); db(0x00); db(0x14);
- db(0x45); db(0xed); db(0x00); db(0x38); db(0x70); db(0xff); db(0x4e); db(0xae);
- db(0xfe); db(0xb6); db(0x15); db(0x40); db(0x00); db(0x14); db(0x41); db(0xfa);
- db(0x03); db(0x60); db(0x24); db(0x88); db(0x25); db(0x7c); db(0x00); db(0x00);
- db(0x00); db(0x12); db(0x00); db(0x0c); db(0x25); db(0x6d); db(0x00); db(0x08);
- db(0x00); db(0x10); db(0x2c); db(0x6d); db(0x00); db(0x18); db(0x22); db(0x0a);
- db(0x4e); db(0xae); db(0xfc); db(0x88); db(0x2c); db(0x6d); db(0x00); db(0x14);
- db(0x4e); db(0x75); db(0x00); db(0x00); db(0x00); db(0x00); db(0x00); db(0x10);
+ db(0x00); db(0x00); db(0x48); db(0xe7); db(0xf8); db(0xfe); db(0x2a); db(0x48);
+ db(0x95); db(0xca); db(0x97); db(0xcb); db(0x99); db(0xcc); db(0x78); db(0x00);
+ db(0x2c); db(0x6d); db(0x00); db(0x18); db(0x20); db(0x6d); db(0x00); db(0x14);
+ db(0x20); db(0x28); db(0x00); db(0x3c); db(0x67); db(0x5c); db(0x20); db(0x40);
+ db(0x41); db(0xe8); db(0x00); db(0x2c); db(0x28); db(0x48); db(0x4e); db(0xae);
+ db(0xfc); db(0xe8); db(0x72); db(0xff); db(0x74); db(0xff); db(0xb2); db(0x80);
+ db(0x67); db(0x48); db(0x26); db(0x00); db(0x2c); db(0x6d); db(0x00); db(0x14);
+ db(0x41); db(0xed); db(0x00); db(0xc0); db(0x70); db(0x66); db(0x4e); db(0xae);
+ db(0xff); db(0x7c); db(0x41); db(0xed); db(0x00); db(0xc0); db(0x38); db(0x28);
+ db(0x00); db(0x64); db(0x2c); db(0x6d); db(0x00); db(0x18); db(0x91); db(0xc8);
+ db(0x43); db(0xed); db(0x00); db(0x38); db(0x70); db(0x00); db(0x30); db(0x3c);
+ db(0x00); db(0x58); db(0x22); db(0x3c); db(0x80); db(0x00); db(0x10); db(0x00);
+ db(0x24); db(0x03); db(0x4e); db(0xae); db(0xfd); db(0x0c); db(0x72); db(0xff);
+ db(0x74); db(0xff); db(0x4a); db(0x80); db(0x6b); db(0x0c); db(0x45); db(0xed);
+ db(0x00); db(0x38); db(0x22); db(0x2a); db(0x00); db(0x32); db(0x24); db(0x2a);
+ db(0x00); db(0x36); db(0x20); db(0x2c); db(0x00); db(0x1c); db(0xb8); db(0x6d);
+ db(0x00); db(0x2c); db(0x66); db(0x12); db(0xb0); db(0xad); db(0x00); db(0x28);
+ db(0x66); db(0x0c); db(0xb2); db(0xad); db(0x00); db(0x20); db(0x66); db(0x06);
+ db(0xb4); db(0xad); db(0x00); db(0x24); db(0x67); db(0x40); db(0x2b); db(0x40);
+ db(0x00); db(0x28); db(0x2b); db(0x41); db(0x00); db(0x20); db(0x2b); db(0x42);
+ db(0x00); db(0x24); db(0x3b); db(0x44); db(0x00); db(0x2c); db(0x91); db(0xc8);
+ db(0x43); db(0xed); db(0x00); db(0x90); db(0x70); db(0x00); db(0x30); db(0x3c);
+ db(0x00); db(0x58); db(0x22); db(0x3c); db(0x80); db(0x00); db(0x00); db(0x00);
+ db(0x24); db(0x03); db(0x4e); db(0xae); db(0xfd); db(0x0c); db(0x4a); db(0x80);
+ db(0x6b); db(0x04); db(0x47); db(0xed); db(0x00); db(0x90); db(0x34); db(0x2d);
+ db(0x00); db(0x2c); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x01);
+ db(0x61); db(0x00); db(0xfd); db(0x70); db(0x4e); db(0x90); db(0x4c); db(0xdf);
+ db(0x7f); db(0x1f); db(0x4e); db(0x75); db(0x2c); db(0x78); db(0x00); db(0x04);
+ db(0x3e); db(0x2e); db(0x00); db(0x14); db(0x70); db(0xff); db(0x4e); db(0xae);
+ db(0xfe); db(0xb6); db(0x7c); db(0x00); db(0x01); db(0xc6); db(0x93); db(0xc9);
+ db(0x4e); db(0xae); db(0xfe); db(0xda); db(0x28); db(0x40); db(0x70); db(0x14);
+ db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0xd4); db(0x70); db(0x00);
+ db(0x30); db(0x3c); db(0x02); db(0x10); db(0x22); db(0x3c); db(0x00); db(0x01);
+ db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x2a); db(0x40);
+ db(0x47); db(0xed); db(0x00); db(0x16); db(0x27); db(0x4e); db(0x00); db(0x10);
+ db(0x27); db(0x4c); db(0x00); db(0x08); db(0x27); db(0x46); db(0x00); db(0x0c);
+ db(0x70); db(0xff); db(0x37); db(0x40); db(0x00); db(0x00); db(0x43); db(0xed);
+ db(0x00); db(0x00); db(0x13); db(0x7c); db(0x00); db(0x02); db(0x00); db(0x08);
+ db(0x13); db(0x7c); db(0x00); db(0x05); db(0x00); db(0x09); db(0x41); db(0xfa);
+ db(0x07); db(0xe0); db(0x23); db(0x48); db(0x00); db(0x0a); db(0x41); db(0xfa);
+ db(0x02); db(0xda); db(0x23); db(0x48); db(0x00); db(0x12); db(0x23); db(0x4d);
+ db(0x00); db(0x0e); db(0x70); db(0x05); db(0x4e); db(0xae); db(0xff); db(0x58);
+ db(0x20); db(0x06); db(0x4e); db(0xae); db(0xfe); db(0xc2); db(0x70); db(0x00);
+ db(0x53); db(0xab); db(0x00); db(0x1c); db(0x6a); db(0x06); db(0x70); db(0x0a);
+ db(0x27); db(0x40); db(0x00); db(0x1c); db(0x4a); db(0xab); db(0x00); db(0x14);
+ db(0x66); db(0x16); db(0x4a); db(0xab); db(0x00); db(0x1c); db(0x66); db(0xe0);
+ db(0x43); db(0xfa); db(0x07); db(0xfe); db(0x70); db(0x00); db(0x4e); db(0xae);
+ db(0xfd); db(0xd8); db(0x27); db(0x40); db(0x00); db(0x14); db(0x67); db(0xd0);
+ db(0x4a); db(0xab); db(0x00); db(0x18); db(0x66); db(0x18); db(0x4a); db(0xab);
+ db(0x00); db(0x1c); db(0x66); db(0xc4); db(0x43); db(0xfa); db(0x07); db(0xf4);
+ db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8); db(0x27); db(0x40);
+ db(0x00); db(0x18); db(0x67); db(0x00); db(0xff); db(0xb4); db(0x4a); db(0xad);
+ db(0x02); db(0x08); db(0x66); db(0x38); db(0x4a); db(0xab); db(0x00); db(0x1c);
+ db(0x66); db(0xa6); db(0x4e); db(0xae); db(0xff); db(0x7c); db(0x41); db(0xee);
+ db(0x01); db(0x5e); db(0x43); db(0xfa); db(0x06); db(0xd4); db(0x4e); db(0xae);
+ db(0xfe); db(0xec); db(0x24); db(0x00); db(0x4e); db(0xae); db(0xff); db(0x76);
+ db(0x4a); db(0x82); db(0x67); db(0x8c); db(0x41); db(0xfa); db(0x06); db(0xc2);
+ db(0x70); db(0x00); db(0x72); db(0x00); db(0x61); db(0x00); db(0xfd); db(0x16);
+ db(0x2b); db(0x40); db(0x02); db(0x08); db(0x67); db(0x00); db(0x02); db(0x42);
+ db(0x60); db(0x00); db(0xff); db(0x76); db(0x4a); db(0xad); db(0x02); db(0x0c);
+ db(0x66); db(0x48); db(0x4a); db(0xab); db(0x00); db(0x1c); db(0x66); db(0x00);
+ db(0xff); db(0x68); db(0x4e); db(0xae); db(0xff); db(0x7c); db(0x41); db(0xee);
+ db(0x01); db(0x5e); db(0x43); db(0xfa); db(0x06); db(0xa1); db(0x4e); db(0xae);
+ db(0xfe); db(0xec); db(0x24); db(0x00); db(0x4e); db(0xae); db(0xff); db(0x76);
+ db(0x4a); db(0x82); db(0x67); db(0x00); db(0xff); db(0x4c); db(0x41); db(0xfa);
+ db(0x06); db(0x8d); db(0x70); db(0x00); db(0x72); db(0x00); db(0x61); db(0x00);
+ db(0xfc); db(0xd4); db(0x2b); db(0x40); db(0x02); db(0x0c); db(0x67); db(0x00);
+ db(0x02); db(0x00); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x00);
+ db(0x61); db(0x00); db(0xfc); db(0x20); db(0x4e); db(0x90); db(0x60); db(0x00);
+ db(0xff); db(0x28); db(0x0c); db(0x47); db(0x00); db(0x24); db(0x65); db(0x12);
+ db(0x53); db(0xab); db(0x00); db(0x34); db(0x6a); db(0x0c); db(0x20); db(0x4b);
+ db(0x61); db(0x00); db(0xfd); db(0xc8); db(0x70); db(0x32); db(0x27); db(0x40);
+ db(0x00); db(0x34); db(0x22); db(0x6d); db(0x02); db(0x08); db(0x45); db(0xed);
+ db(0x01); db(0x3c); db(0x33); db(0x7c); db(0x00); db(0x0b); db(0x00); db(0x1c);
+ db(0x23); db(0x7c); db(0x00); db(0x00); db(0x00); db(0x16); db(0x00); db(0x24);
+ db(0x23); db(0x4a); db(0x00); db(0x28); db(0x10); db(0x3a); db(0xfd); db(0x78);
+ db(0x0c); db(0x47); db(0x00); db(0x27); db(0x65); db(0x00); db(0x01); db(0x62);
+ db(0x08); db(0x00); db(0x00); db(0x01); db(0x67); db(0x00); db(0x01); db(0x5a);
+ db(0x41); db(0xed); db(0x01); db(0x68); db(0x25); db(0x48); db(0x00); db(0x0a);
+ db(0x15); db(0x7c); db(0x00); db(0x13); db(0x00); db(0x04); db(0x15); db(0x7c);
+ db(0x00); db(0x03); db(0x00); db(0x05); db(0x42); db(0x90); db(0x42); db(0xa8);
+ db(0x00); db(0x04); db(0x42); db(0x6a); db(0x00); db(0x06); db(0x42); db(0xa8);
+ db(0x00); db(0x08); db(0x42); db(0x68); db(0x00); db(0x0c); db(0x22); db(0x3a);
+ db(0xfd); db(0x60); db(0x02); db(0x41); db(0x00); db(0x07); db(0x70); db(0x07);
+ db(0x90); db(0x41); db(0xe1); db(0x48); db(0xe9); db(0x48); db(0x35); db(0x40);
+ db(0x00); db(0x08); db(0x31); db(0x7a); db(0xfd); db(0x34); db(0x00); db(0x0e);
+ db(0x42); db(0x68); db(0x00); db(0x10); db(0x31); db(0x7a); db(0xfd); db(0x2c);
+ db(0x00); db(0x12); db(0x42); db(0x68); db(0x00); db(0x14); db(0x31); db(0x7a);
+ db(0xfd); db(0x1a); db(0x00); db(0x16); db(0x42); db(0x68); db(0x00); db(0x18);
+ db(0x31); db(0x7a); db(0xfd); db(0x12); db(0x00); db(0x1a); db(0x43); db(0xed);
+ db(0x01); db(0x88); db(0x21); db(0x49); db(0x00); db(0x1c); db(0x22); db(0xfc);
+ db(0x80); db(0x03); db(0xa0); db(0x06); db(0x30); db(0x3a); db(0xfd); db(0x18);
+ db(0x48); db(0xc0); db(0xe1); db(0x80); db(0x22); db(0xc0); db(0x22); db(0xfc);
+ db(0x80); db(0x03); db(0xa0); db(0x07); db(0x22); db(0xfa); db(0xfd); db(0x0a);
+ db(0x70); db(0x00); db(0x30); db(0x3a); db(0xfc); db(0xf2); db(0x6b); db(0x08);
+ db(0x22); db(0xfc); db(0x80); db(0x03); db(0xa0); db(0x09); db(0x22); db(0xc0);
+ db(0x30); db(0x3a); db(0xfc); db(0xe6); db(0x6b); db(0x08); db(0x22); db(0xfc);
+ db(0x80); db(0x03); db(0xa0); db(0x0a); db(0x22); db(0xc0); db(0x30); db(0x3a);
+ db(0xfc); db(0xce); db(0x6b); db(0x14); db(0x22); db(0xfc); db(0x80); db(0x03);
+ db(0xa0); db(0x02); db(0x22); db(0xc0); db(0x30); db(0x3a); db(0xfc); db(0xc6);
+ db(0x22); db(0xfc); db(0x80); db(0x03); db(0xa0); db(0x01); db(0x22); db(0xc0);
+ db(0x30); db(0x3a); db(0xfc); db(0xc0); db(0x6b); db(0x10); db(0x22); db(0xfc);
+ db(0x80); db(0x03); db(0xa0); db(0x03); db(0x30); db(0x3a); db(0xfc); db(0xba);
+ db(0x48); db(0xc0); db(0xe1); db(0x80); db(0x22); db(0xc0); db(0x30); db(0x3a);
+ db(0xfc); db(0xac); db(0x6b); db(0x10); db(0x22); db(0xfc); db(0x80); db(0x03);
+ db(0xa0); db(0x04); db(0x30); db(0x3a); db(0xfc); db(0xa6); db(0x48); db(0xc0);
+ db(0xe1); db(0x80); db(0x22); db(0xc0); db(0x30); db(0x3a); db(0xfc); db(0x98);
+ db(0x6b); db(0x10); db(0x22); db(0xfc); db(0x80); db(0x03); db(0xa0); db(0x05);
+ db(0x30); db(0x3a); db(0xfc); db(0x92); db(0x48); db(0xc0); db(0xe1); db(0x80);
+ db(0x22); db(0xc0); db(0x70); db(0x00); db(0x30); db(0x3a); db(0xfc); db(0x8e);
+ db(0x6b); db(0x08); db(0x22); db(0xfc); db(0x80); db(0x03); db(0xa0); db(0x08);
+ db(0x22); db(0xc0); db(0x42); db(0x91); db(0x61); db(0x00); db(0xfc); db(0x40);
+ db(0x36); db(0x3c); db(0x00); db(0x68); db(0x74); db(0x01); db(0x28); db(0x3a);
+ db(0xfc); db(0x70); db(0x20); db(0x04); db(0xc0); db(0x82); db(0x22); db(0x2b);
+ db(0x00); db(0x04); db(0xc2); db(0x82); db(0xb2); db(0x80); db(0x67); db(0x22);
+ db(0x42); db(0x92); db(0x35); db(0x7c); db(0x02); db(0x00); db(0x00); db(0x04);
+ db(0x42); db(0xaa); db(0x00); db(0x0a); db(0x32); db(0x03); db(0x4a); db(0x00);
+ db(0x66); db(0x04); db(0x08); db(0xc1); db(0x00); db(0x07); db(0x35); db(0x41);
+ db(0x00); db(0x06); db(0x42); db(0x6a); db(0x00); db(0x08); db(0x61); db(0x00);
+ db(0xfc); db(0x06); db(0x52); db(0x43); db(0xd4); db(0x42); db(0x0c); db(0x42);
+ db(0x00); db(0x08); db(0x66); db(0xc6); db(0x27); db(0x44); db(0x00); db(0x04);
+ db(0x10); db(0x3a); db(0xfc); db(0x0c); db(0x08); db(0x00); db(0x00); db(0x00);
+ db(0x67); db(0x00); db(0xfd); db(0x7e); db(0x42); db(0x92); db(0x35); db(0x7c);
+ db(0x04); db(0x00); db(0x00); db(0x04); db(0x42); db(0x6a); db(0x00); db(0x06);
+ db(0x42); db(0x6a); db(0x00); db(0x08); db(0x20); db(0x6b); db(0x00); db(0x14);
+ db(0x30); db(0x3a); db(0xfc); db(0x14); db(0x32); db(0x28); db(0x00); db(0x30);
+ db(0xd2); db(0x41); db(0x90); db(0x41); db(0x6a); db(0x02); db(0x70); db(0x00);
+ db(0x35); db(0x40); db(0x00); db(0x0a); db(0x30); db(0x3a); db(0xfc); db(0x02);
+ db(0x32); db(0x28); db(0x00); db(0x2e); db(0xd2); db(0x41); db(0x90); db(0x41);
+ db(0x6a); db(0x02); db(0x70); db(0x00); db(0x35); db(0x40); db(0x00); db(0x0c);
+ db(0x61); db(0x00); db(0xfb); db(0x78); db(0x60); db(0x00); db(0xfd); db(0x3a);
+ db(0x4e); db(0x75); db(0x4a); db(0xa9); db(0x02); db(0x08); db(0x67); db(0x14);
+ db(0x4a); db(0xa9); db(0x02); db(0x0c); db(0x67); db(0x0e); db(0x30); db(0x3a);
+ db(0xfb); db(0xb0); db(0xb0); db(0x69); db(0x00); db(0x16); db(0x67); db(0x14);
+ db(0x33); db(0x40); db(0x00); db(0x16); db(0x2c); db(0x69); db(0x00); db(0x26);
+ db(0x20); db(0x29); db(0x00); db(0x22); db(0x22); db(0x69); db(0x00); db(0x1e);
+ db(0x4e); db(0xae); db(0xfe); db(0xbc); db(0x53); db(0x69); db(0x00); db(0x46);
+ db(0x6a); db(0x12); db(0x33); db(0x7c); db(0x00); db(0x32); db(0x00); db(0x46);
+ db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x02); db(0x61); db(0x00);
+ db(0xf9); db(0xea); db(0x4e); db(0x90); db(0x41); db(0xf9); db(0x00); db(0xdf);
+ db(0xf0); db(0x00); db(0x70); db(0x00); db(0x4e); db(0x75); db(0x48); db(0xe7);
+ db(0x00); db(0x06); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x20); db(0x3c);
+ db(0x00); db(0x00); db(0x00); db(0x88); db(0x22); db(0x3c); db(0x00); db(0x01);
+ db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x4a); db(0x80);
+ db(0x67); db(0x00); db(0x00); db(0x40); db(0x2a); db(0x40); db(0x2b); db(0x4e);
+ db(0x00); db(0x14); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x0e);
+ db(0x61); db(0x00); db(0xf9); db(0xb0); db(0x20); db(0x0d); db(0x4e); db(0x90);
+ db(0x41); db(0xfa); db(0x04); db(0x68); db(0x43); db(0xfa); db(0x01); db(0x12);
+ db(0x70); db(0xf6); db(0x22); db(0x3c); db(0x00); db(0x00); db(0x27); db(0x10);
+ db(0x61); db(0x00); db(0xee); db(0xdc); db(0x70); db(0x00); db(0x4c); db(0xdf);
+ db(0x60); db(0x00); db(0x4e); db(0x75); db(0x30); db(0x3c); db(0xff); db(0x38);
+ db(0x72); db(0x0a); db(0x61); db(0x00); db(0xf9); db(0x86); db(0x4e); db(0x90);
+ db(0x4e); db(0x75); db(0x61); db(0xf0); db(0x20); db(0x0d); db(0x67); db(0x1c);
+ db(0x2c); db(0x6d); db(0x00); db(0x14); db(0x20); db(0x2d); db(0x00); db(0x18);
+ db(0x67); db(0x06); db(0x22); db(0x40); db(0x4e); db(0xae); db(0xfe); db(0x62);
+ db(0x22); db(0x4d); db(0x20); db(0x3c); db(0x00); db(0x00); db(0x00); db(0x88);
+ db(0x4e); db(0xae); db(0xff); db(0x2e); db(0x70); db(0x00); db(0x4e); db(0x75);
+ db(0x48); db(0xe7); db(0x38); db(0x3e); db(0x2c); db(0x6d); db(0x00); db(0x18);
+ db(0x41); db(0xfa); db(0x03); db(0xf6); db(0x22); db(0x08); db(0x24); db(0x3c);
+ db(0x00); db(0x00); db(0x03); db(0xed); db(0x4e); db(0xae); db(0xff); db(0xe2);
+ db(0x28); db(0x00); db(0x67); db(0x4c); db(0x45); db(0xed); db(0x00); db(0x68);
+ db(0x42); db(0x92); db(0x34); db(0xaa); db(0x00); db(0x02); db(0x24); db(0x0a);
+ db(0x54); db(0x82); db(0x76); db(0x02); db(0x22); db(0x04); db(0x4e); db(0xae);
+ db(0xff); db(0xd6); db(0xb6); db(0x80); db(0x66); db(0x32); db(0x0c); db(0x92);
+ db(0x50); db(0x4e); db(0x54); db(0x52); db(0x66); db(0xe4); db(0x24); db(0x0a);
+ db(0x76); db(0x04); db(0x22); db(0x04); db(0x4e); db(0xae); db(0xff); db(0xd6);
+ db(0x24); db(0x0a); db(0x76); db(0x20); db(0x22); db(0x04); db(0x4e); db(0xae);
+ db(0xff); db(0xd6); db(0xb6); db(0x80); db(0x66); db(0x12); db(0x4a); db(0x6a);
+ db(0x00); db(0x10); db(0x66); db(0xc4); db(0x30); db(0x3c); db(0xff); db(0x38);
+ db(0x72); db(0x10); db(0x61); db(0x00); db(0xf8); db(0xf6); db(0x4e); db(0x90);
+ db(0x22); db(0x04); db(0x67); db(0x04); db(0x4e); db(0xae); db(0xff); db(0xdc);
+ db(0x4c); db(0xdf); db(0x7c); db(0x1c); db(0x4e); db(0x75); db(0x2c); db(0x6d);
+ db(0x00); db(0x18); db(0x41); db(0xfa); db(0x03); db(0x6e); db(0x22); db(0x08);
+ db(0x74); db(0xfe); db(0x4e); db(0xae); db(0xff); db(0xac); db(0x22); db(0x00);
+ db(0x67); db(0x34); db(0x4e); db(0xae); db(0xff); db(0xa6); db(0x2c); db(0x6d);
+ db(0x00); db(0x14); db(0x45); db(0xed); db(0x00); db(0x38); db(0x70); db(0xff);
+ db(0x4e); db(0xae); db(0xfe); db(0xb6); db(0x15); db(0x40); db(0x00); db(0x14);
+ db(0x41); db(0xfa); db(0x03); db(0x5e); db(0x24); db(0x88); db(0x25); db(0x7c);
+ db(0x00); db(0x00); db(0x00); db(0x12); db(0x00); db(0x0c); db(0x25); db(0x6d);
+ db(0x00); db(0x08); db(0x00); db(0x10); db(0x2c); db(0x6d); db(0x00); db(0x18);
+ db(0x22); db(0x0a); db(0x4e); db(0xae); db(0xfc); db(0x88); db(0x2c); db(0x6d);
+ db(0x00); db(0x14); db(0x4e); db(0x75); db(0x00); db(0x00); db(0x00); db(0x10);
  db(0x00); db(0x00); db(0x00); db(0x00); db(0x30); db(0x3c); db(0xff); db(0x38);
- db(0x72); db(0x0d); db(0x61); db(0x00); db(0xf8); db(0x84); db(0x4e); db(0x90);
- db(0x4a); db(0x80); db(0x67); db(0x00); db(0xfe); db(0xfc); db(0x2a); db(0x40);
+ db(0x72); db(0x0d); db(0x61); db(0x00); db(0xf8); db(0x86); db(0x4e); db(0x90);
+ db(0x4a); db(0x80); db(0x67); db(0x00); db(0xfe); db(0xfe); db(0x2a); db(0x40);
  db(0x2c); db(0x6d); db(0x00); db(0x14); db(0x93); db(0xc9); db(0x4e); db(0xae);
  db(0xfe); db(0xda); db(0x2b); db(0x40); db(0x00); db(0x08); db(0x43); db(0xfa);
  db(0x03); db(0x8c); db(0x70); db(0x00); db(0x4e); db(0xae); db(0xfd); db(0xd8);
- db(0x2b); db(0x40); db(0x00); db(0x18); db(0x67); db(0x00); db(0xfe); db(0xda);
+ db(0x2b); db(0x40); db(0x00); db(0x18); db(0x67); db(0x00); db(0xfe); db(0xdc);
  db(0x2c); db(0x40); db(0x72); db(0x32); db(0x4e); db(0xae); db(0xff); db(0x3a);
  db(0x41); db(0xfa); db(0x02); db(0xc4); db(0x22); db(0x08); db(0x74); db(0xfe);
  db(0x4e); db(0xae); db(0xff); db(0xac); db(0x4a); db(0x80); db(0x67); db(0xea);
  db(0x22); db(0x00); db(0x4e); db(0xae); db(0xff); db(0xa6); db(0x72); db(0x32);
  db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x41); db(0xfa); db(0x02); db(0xae);
  db(0x22); db(0x08); db(0x74); db(0xfe); db(0x4e); db(0xae); db(0xff); db(0xac);
- db(0x4a); db(0x80); db(0x67); db(0x00); db(0xfe); db(0xa4); db(0x22); db(0x00);
+ db(0x4a); db(0x80); db(0x67); db(0x00); db(0xfe); db(0xa6); db(0x22); db(0x00);
  db(0x4e); db(0xae); db(0xff); db(0xa6); db(0x2c); db(0x6d); db(0x00); db(0x14);
- db(0x61); db(0x00); db(0xf8); db(0x32); db(0x72); db(0x00); db(0x32); db(0x3c);
- db(0x00); db(0x34); db(0x61); db(0x00); db(0xf8); db(0x76); db(0x28); db(0x40);
- db(0x4a); db(0x80); db(0x67); db(0x00); db(0xfe); db(0x84); db(0x70); db(0x00);
+ db(0x61); db(0x00); db(0xf8); db(0x34); db(0x72); db(0x00); db(0x32); db(0x3c);
+ db(0x00); db(0x34); db(0x61); db(0x00); db(0xf8); db(0x78); db(0x28); db(0x40);
+ db(0x4a); db(0x80); db(0x67); db(0x00); db(0xfe); db(0x86); db(0x70); db(0x00);
  db(0x08); db(0xc0); db(0x00); db(0x0d); db(0x4e); db(0xae); db(0xfe); db(0xc2);
  db(0x72); db(0x00); db(0x20); db(0x2d); db(0x00); db(0x0c); db(0x41); db(0xfa);
  db(0x02); db(0x87); db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x44);
  db(0x4a); db(0x80); db(0x66); db(0xe2); db(0x20); db(0x6c); db(0x00); db(0x14);
  db(0x0c); db(0x68); db(0x00); db(0x25); db(0x00); db(0x14); db(0x64); db(0x0c);
- db(0x61); db(0x00); db(0xfe); db(0x48); db(0x70); db(0x00); db(0x4e); db(0xae);
- db(0xfe); db(0xc2); db(0x60); db(0xf8); db(0x61); db(0x00); db(0xfe); db(0xe6);
+ db(0x61); db(0x00); db(0xfe); db(0x4a); db(0x70); db(0x00); db(0x4e); db(0xae);
+ db(0xfe); db(0xc2); db(0x60); db(0xf8); db(0x61); db(0x00); db(0xfe); db(0xe8);
  db(0x41); db(0xed); db(0x00); db(0x1c); db(0x29); db(0x48); db(0x00); db(0x28);
  db(0x70); db(0x01); db(0x29); db(0x40); db(0x00); db(0x24); db(0x39); db(0x7c);
  db(0x00); db(0x0c); db(0x00); db(0x1c); db(0x2b); db(0x4d); db(0x00); db(0x2c);
  db(0x41); db(0xfa); db(0x01); db(0x60); db(0x2b); db(0x48); db(0x00); db(0x24);
  db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x38); db(0x30); db(0x3c);
- db(0xff); db(0x38); db(0x72); db(0x0f); db(0x61); db(0x00); db(0xf7); db(0x9a);
+ db(0xff); db(0x38); db(0x72); db(0x0f); db(0x61); db(0x00); db(0xf7); db(0x9c);
  db(0x4e); db(0x90); db(0x4a); db(0xad); db(0x00); db(0x00); db(0x66); db(0x1c);
  db(0x70); db(0x00); db(0x74); db(0x00); db(0x14); db(0x2d); db(0x00); db(0x4c);
  db(0x05); db(0xc0); db(0x08); db(0xc0); db(0x00); db(0x0d); db(0x4e); db(0xae);
  db(0xfe); db(0xc2); db(0x05); db(0x00); db(0x67); db(0x06); db(0x61); db(0x00);
- db(0xfe); db(0x1e); db(0x60); db(0xe4); db(0x20); db(0x2d); db(0x00); db(0x00);
+ db(0xfe); db(0x20); db(0x60); db(0xe4); db(0x20); db(0x2d); db(0x00); db(0x00);
  db(0x67); db(0x00); db(0x00); db(0x76); db(0x72); db(0x01); db(0x4e); db(0xae);
  db(0xff); db(0x3a); db(0x2b); db(0x40); db(0x00); db(0x04); db(0x30); db(0x3c);
- db(0xff); db(0x38); db(0x72); db(0x0c); db(0x61); db(0x00); db(0xf7); db(0x5a);
+ db(0xff); db(0x38); db(0x72); db(0x0c); db(0x61); db(0x00); db(0xf7); db(0x5c);
  db(0x4e); db(0x90); db(0x4a); db(0x80); db(0x67); db(0x40); db(0x4a); db(0xad);
  db(0x00); db(0x04); db(0x67); db(0x3a); db(0x39); db(0x7c); db(0x00); db(0x03);
  db(0x00); db(0x1c); db(0x42); db(0x2c); db(0x00); db(0x1f); db(0x42); db(0xac);
  db(0x00); db(0x28); db(0x20); db(0x02); db(0x51); db(0x80); db(0x29); db(0x40);
  db(0x00); db(0x24); db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x38);
  db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x0b); db(0x61); db(0x00);
- db(0xf6); db(0x80); db(0x20); db(0x2c); db(0x00); db(0x20); db(0x4e); db(0x90);
+ db(0xf6); db(0x82); db(0x20); db(0x2c); db(0x00); db(0x20); db(0x4e); db(0x90);
  db(0x22); db(0x4a); db(0x20); db(0x02); db(0x4e); db(0xae); db(0xff); db(0x2e);
  db(0x4a); db(0xac); db(0x00); db(0x20); db(0x67); db(0x00); db(0xfe); db(0xda);
  db(0x41); db(0xed); db(0x00); db(0x30); db(0x29); db(0x48); db(0x00); db(0x28);
  db(0x08); db(0xc0); db(0x00); db(0x0d); db(0x4e); db(0xae); db(0xfe); db(0xbc);
  db(0x2c); db(0x5f); db(0x70); db(0x00); db(0x4e); db(0x75); db(0x2c); db(0x78);
  db(0x00); db(0x04); db(0x74); db(0xff); db(0x30); db(0x3c); db(0xff); db(0x38);
- db(0x72); db(0x64); db(0x61); db(0x00); db(0xf6); db(0x14); db(0x4e); db(0x90);
+ db(0x72); db(0x64); db(0x61); db(0x00); db(0xf6); db(0x16); db(0x4e); db(0x90);
  db(0x4a); db(0x80); db(0x67); db(0x38); db(0x74); db(0x00); db(0x4e); db(0xae);
  db(0xff); db(0x7c); db(0x41); db(0xee); db(0x01); db(0x5e); db(0x43); db(0xfa);
  db(0x00); db(0x62); db(0x4e); db(0xae); db(0xfe); db(0xec); db(0x4a); db(0x80);
  db(0x67); db(0x1e); db(0x20); db(0x40); db(0x43); db(0xfa); db(0x00); db(0x22);
  db(0x24); db(0x68); db(0xff); db(0xe4); db(0x21); db(0x49); db(0xff); db(0xe4);
  db(0x22); db(0x48); db(0x30); db(0x3c); db(0xff); db(0x38); db(0x72); db(0x65);
- db(0x61); db(0x00); db(0xf5); db(0xde); db(0x4e); db(0x90); db(0x74); db(0x01);
+ db(0x61); db(0x00); db(0xf5); db(0xe0); db(0x4e); db(0x90); db(0x74); db(0x01);
  db(0x4e); db(0xae); db(0xff); db(0x76); db(0x20); db(0x02); db(0x4e); db(0x75);
  db(0x59); db(0x8f); db(0x48); db(0xe7); db(0xc0); db(0x80); db(0x30); db(0x3c);
- db(0xff); db(0x38); db(0x72); db(0x66); db(0x61); db(0x00); db(0xf5); db(0xc2);
+ db(0xff); db(0x38); db(0x72); db(0x66); db(0x61); db(0x00); db(0xf5); db(0xc4);
  db(0x4e); db(0x90); db(0x4c); db(0xdf); db(0x01); db(0x03); db(0x4e); db(0x75);
  db(0x69); db(0x6e); db(0x70); db(0x75); db(0x74); db(0x2e); db(0x64); db(0x65);
  db(0x76); db(0x69); db(0x63); db(0x65); db(0x00); db(0x74); db(0x69); db(0x6d);
diff --git a/fpp.cpp b/fpp.cpp
index 82980c995077ab2d7da4763323bb94b09a572dc0..e06432a273cf7c2b2389e6fa3fcc67ceb17f0d6a 100644 (file)
--- a/fpp.cpp
+++ b/fpp.cpp
@@ -851,7 +851,7 @@ void fpuop_trapcc (uae_u32 opcode, uaecptr oldpc, uae_u16 extra)
                fpu_op_illg (opcode, m68k_getpc () - oldpc);
        }
        if (cc)
-               Exception (7, oldpc - 2);
+               Exception (7);
 }
 
 void fpuop_bcc (uae_u32 opcode, uaecptr pc, uae_u32 extra)
index 347bf6be610b34d671abf623b27cc7e25cdbb44e..232467d56600d6f1092e549926760dcebb45c47d 100644 (file)
--- a/gayle.cpp
+++ b/gayle.cpp
@@ -155,7 +155,7 @@ read 1 byte to stop reset */
 #define IDE_GAYLE 0
 #define IDE_ADIDE 1
 
-#define MAX_IDE_MULTIPLE_SECTORS 128
+#define MAX_IDE_MULTIPLE_SECTORS 64
 #define SECBUF_SIZE (512 * (MAX_IDE_MULTIPLE_SECTORS * 2))
 
 struct ide_hdf
@@ -286,7 +286,7 @@ static void gayle_cs_change (uae_u8 mask, int onoff)
                        if (gayle_irq & GAYLE_IRQ_RESET)
                                uae_reset (0);
                        if (gayle_irq & GAYLE_IRQ_BERR)
-                               Exception (2, 0);
+                               Exception (2);
                }
        }
 }
@@ -1904,7 +1904,7 @@ static void initide (void)
        int i;
 
        alloc_ide_mem (idedrive, 4);
-       if (savestate_state == STATE_RESTORE)
+       if (isrestore ())
                return;
        ide_error = 1;
        ide_sector = ide_nsector = 1;
@@ -1954,13 +1954,16 @@ uae_u8 *restore_gayle (uae_u8 *src)
        return src;
 }
 
-uae_u8 *save_gayle (int *len)
+uae_u8 *save_gayle (int *len, uae_u8 *dstptr)
 {
        uae_u8 *dstbak, *dst;
 
        if (currprefs.cs_ide <= 0)
                return NULL;
-       dstbak = dst = xmalloc (uae_u8, 1000);
+       if (dstptr)
+               dstbak = dst = dstptr;
+       else
+               dstbak = dst = xmalloc (uae_u8, 1000);
        save_u8 (currprefs.cs_ide);
        save_u8 (gayle_int);
        save_u8 (gayle_irq);
@@ -1971,7 +1974,7 @@ uae_u8 *save_gayle (int *len)
        return dstbak;
 }
 
-uae_u8 *save_ide (int num, int *len)
+uae_u8 *save_ide (int num, int *len, uae_u8 *dstptr)
 {
        uae_u8 *dstbak, *dst;
        struct ide_hdf *ide;
@@ -1983,7 +1986,10 @@ uae_u8 *save_ide (int num, int *len)
        ide = idedrive[num];
        if (ide->hdhfd.size == 0)
                return NULL;
-       dstbak = dst = xmalloc (uae_u8, 1000);
+       if (dstptr)
+               dstbak = dst = dstptr;
+       else
+               dstbak = dst = xmalloc (uae_u8, 1000);
        save_u32 (num);
        save_u64 (ide->hdhfd.size);
        save_string (ide->hdhfd.path);
index 003d4c6913d85c707b44dfde9705dfc65d43ae5d..fa2313f6780685ef304b29aacfee7f2e137d6d38 100644 (file)
@@ -35,6 +35,7 @@ static int using_prefetch, using_indirect, using_mmu;
 static int using_ce020;
 static int using_exception_3;
 static int using_ce;
+static int using_tracer;
 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;
@@ -69,6 +70,13 @@ static int fixupcnt;
 #define GENA_MOVEM_NO_INC      1
 #define GENA_MOVEM_MOVE16      2
 
+static char *srcl, *dstl;
+static char *srcw, *dstw;
+static char *srcb, *dstb;
+static char *prefetch_long, *prefetch_word;
+static char *srcli, *srcwi, *srcbi, *nextl, *nextw, *nextb;
+static char *do_cycles, *disp000, *disp020;
+
 static void read_counts (void)
 {
        FILE *file;
@@ -148,14 +156,14 @@ static void addcycles000 (int cycles)
 {
        if (!using_ce)
                return;
-       printf ("\tdo_cycles_ce000 (%d);\n", cycles);
+       printf ("\t%s (%d);\n", do_cycles, cycles);
        count_cycles += cycles;
 }
 static void addcycles000_2 (char *s, int cycles)
 {
        if (!using_ce)
                return;
-       printf ("%sdo_cycles_ce000 (%d);\n", s, cycles);
+       printf ("%s%s (%d);\n", s, do_cycles, cycles);
        count_cycles += cycles;
 }
 
@@ -163,7 +171,7 @@ static void addcycles000_3 (char *s)
 {
        if (!using_ce)
                return;
-       printf ("%sif (cycles > 0) do_cycles_ce000 (cycles);\n", s);
+       printf ("%sif (cycles > 0) %s (cycles);\n", s, do_cycles);
        count_ncycles++;
 }
 
@@ -221,56 +229,44 @@ static const char *bit_mask (int size)
        return 0;
 }
 
-static char *srcl, *dstl;
-static char *srcw, *dstw;
-static char *srcb, *dstb;
-static char *ce020_prefetch_long;
-static char *ce020_prefetch_word;
-
 static void gen_nextilong (char *type, char *name, int flags)
 {
        int r = m68k_pc_offset;
        m68k_pc_offset += 4;
 
        if (using_ce020) {
-               printf ("\t%s %s = %s (%d);\n", type, name, ce020_prefetch_long, r);
+               printf ("\t%s %s = %s (%d);\n", type, name, prefetch_long, r);
                count_read += 2;
        } else if (using_ce) {
                printf ("\t%s %s;\n", type, name);
                /* we must do this because execution order of (something | something2) is not defined */
                if (flags & GF_NOREFILL) {
-                       printf ("\t%s = get_word_ce_prefetch (%d) << 16;\n", name, r + 2);
+                       printf ("\t%s = %s (%d) << 16;\n", name, prefetch_word, r + 2);
                        count_read++;
                        printf ("\t%s |= regs.irc;\n", name);
                } else {
-                       printf ("\t%s = get_word_ce_prefetch (%d) << 16;\n", name, r + 2);
+                       printf ("\t%s = %s (%d) << 16;\n", name, prefetch_word, r + 2);
                        count_read++;
-                       printf ("\t%s |= get_word_ce_prefetch (%d);\n", name, r + 4);
+                       printf ("\t%s |= %s (%d);\n", name, prefetch_word, r + 4);
                        count_read++;
                }
        } else {
                if (using_prefetch) {
                        if (flags & GF_NOREFILL) {
                                printf ("\t%s %s;\n", type, name);
-                               printf ("\t%s = get_word_prefetch (%d) << 16;\n", name, r + 2);
+                               printf ("\t%s = %s (%d) << 16;\n", name, prefetch_word, r + 2);
                                count_read++;
                                printf ("\t%s |= regs.irc;\n", name);
                                insn_n_cycles += 4;
                        } else {
-                               printf ("\t%s %s = get_long_prefetch (%d);\n", type, name, r + 2);
+                               printf ("\t%s %s = %s (%d);\n", type, name, prefetch_long, r + 2);
                                count_read++;
                                count_read++;
                                insn_n_cycles += 8;
                        }
-               } else if (using_indirect) {
-                       insn_n_cycles += 8;
-                       printf ("\t%s %s = get_ilongi (%d);\n", type, name, r);
-               } else if (using_mmu) {
-                       insn_n_cycles += 8;
-                       printf ("\t%s %s = get_ilong_mmu (%d);\n", type, name, r);
                } else {
                        insn_n_cycles += 8;
-                       printf ("\t%s %s = get_ilong (%d);\n", type, name, r);
+                       printf ("\t%s %s = %s (%d);\n", type, name, prefetch_long, r);
                }
        }
 }
@@ -282,13 +278,13 @@ static const char *gen_nextiword (int flags)
        m68k_pc_offset += 2;
 
        if (using_ce020) {
-               sprintf (buffer, "%s (%d)", ce020_prefetch_word, r);
+               sprintf (buffer, "%s (%d)", prefetch_word, r);
                count_read++;
        } else if (using_ce) {
                if (flags & GF_NOREFILL) {
                        strcpy (buffer, "regs.irc");
                } else {
-                       sprintf (buffer, "get_word_ce_prefetch (%d)", r + 2);
+                       sprintf (buffer, "%s (%d)", prefetch_word, r + 2);
                        count_read++;
                }
        } else {
@@ -296,18 +292,12 @@ static const char *gen_nextiword (int flags)
                        if (flags & GF_NOREFILL) {
                                sprintf (buffer, "regs.irc", r);
                        } else {
-                               sprintf (buffer, "get_word_prefetch (%d)", r + 2);
+                               sprintf (buffer, "%s (%d)", prefetch_word, r + 2);
                                count_read++;
                                insn_n_cycles += 4;
                        }
-               } else if (using_indirect) {
-                       sprintf (buffer, "get_iwordi(%d)", r);
-                       insn_n_cycles += 4;
-               } else if (using_mmu) {
-                       sprintf (buffer, "get_iword_mmu (%d)", r);
-                       insn_n_cycles += 4;
                } else {
-                       sprintf (buffer, "get_iword (%d)", r);
+                       sprintf (buffer, "%s (%d)", prefetch_word, r);
                        insn_n_cycles += 4;
                }
        }
@@ -321,13 +311,13 @@ static const char *gen_nextibyte (int flags)
        m68k_pc_offset += 2;
 
        if (using_ce020) {
-               sprintf (buffer, "(uae_u8)%s (%d)", ce020_prefetch_word, r);
+               sprintf (buffer, "(uae_u8)%s (%d)", prefetch_word, r);
                count_read++;
        } else if (using_ce) {
                if (flags & GF_NOREFILL) {
                        strcpy (buffer, "(uae_u8)regs.irc");
                } else {
-                       sprintf (buffer, "(uae_u8)get_word_ce_prefetch (%d)", r + 2);
+                       sprintf (buffer, "(uae_u8)%s (%d)", prefetch_word, r + 2);
                        count_read++;
                }
        } else {
@@ -336,18 +326,12 @@ static const char *gen_nextibyte (int flags)
                        if (flags & GF_NOREFILL) {
                                sprintf (buffer, "(uae_u8)regs.irc", r);
                        } else {
-                               sprintf (buffer, "(uae_u8)get_word_prefetch (%d)", r + 2);
+                               sprintf (buffer, "(uae_u8)%s (%d)", prefetch_word, r + 2);
                                insn_n_cycles += 4;
                                count_read++;
                        }
-               } else if (using_indirect)  {
-                       sprintf (buffer, "get_ibytei (%d)", r);
-                       insn_n_cycles += 4;
-               } else if (using_mmu)  {
-                       sprintf (buffer, "get_ibyte_mmu (%d)", r);
-                       insn_n_cycles += 4;
                } else {
-                       sprintf (buffer, "get_ibyte (%d)", r);
+                       sprintf (buffer, "%s (%d)", srcbi, r);
                        insn_n_cycles += 4;
                }
        }
@@ -369,10 +353,7 @@ static void fill_prefetch_2 (void)
 {
        if (!using_prefetch)
                return;
-       if (using_ce)
-               printf ("\tget_word_ce_prefetch (%d);\n", m68k_pc_offset + 2);
-       else
-               printf ("\tget_word_prefetch (%d);\n", m68k_pc_offset + 2);
+       printf ("\t%s (%d);\n", prefetch_word, m68k_pc_offset + 2);
        did_prefetch = 1;
        count_read++;
        insn_n_cycles += 4;
@@ -382,11 +363,7 @@ static void fill_prefetch_1 (int o)
 {
        if (!using_prefetch)
                return;
-       if (using_ce) {
-               printf ("\tget_word_ce_prefetch (%d);\n", o);
-       } else {
-               printf ("\tget_word_prefetch (%d);\n", o);
-       }
+       printf ("\t%s (%d);\n", prefetch_word, o);
        did_prefetch = 1;
        count_read++;
        insn_n_cycles += 4;
@@ -403,10 +380,7 @@ static void fill_prefetch_0 (void)
 {
        if (!using_prefetch)
                return;
-       if (using_ce)
-               printf ("\tget_word_ce_prefetch (0);\n");
-       else
-               printf ("\tget_word_prefetch (0);\n");
+       printf ("\t%s (0);\n", prefetch_word);
        did_prefetch = 1;
        count_read++;
        insn_n_cycles += 4;
@@ -417,11 +391,7 @@ static void dummy_prefetch (void)
        int o = m68k_pc_offset + 2;
        if (!using_prefetch)
                return;
-       if (using_ce) {
-               printf ("\tget_wordi_ce (m68k_getpc () + %d);\n", o);
-       } else {
-               printf ("\tget_wordi (m68k_getpc () + %d);\n", o);
-       }
+       printf ("\t%s (%d);\n", srcwi, o);
        count_read++;
        insn_n_cycles += 4;
 }
@@ -437,27 +407,6 @@ static void fill_prefetch_next (void)
        fill_prefetch_next_1 ();
 }
 
-#if 0
-static void fill_prefetch_next_delay (int extracycles)
-{
-       if (!using_prefetch)
-               return;
-       if (using_ce) {
-               if (extracycles > 0) {
-                       printf("\t{\n");
-                       fill_prefetch_next ();
-                       printf("\tif (%d > 0) do_cycles(%d * CYCLE_UNIT / 2);\n",
-                               extracycles, extracycles);
-                       printf("\t}\n");
-               } else {
-                       fill_prefetch_next ();
-               }
-       } else {
-               fill_prefetch_next ();
-       }
-}
-#endif
-
 static void fill_prefetch_finish (void)
 {
        if (did_prefetch || !using_prefetch)
@@ -508,7 +457,7 @@ static void gen_set_fault_pc (void)
        if (!using_mmu)
                return;
        sync_m68k_pc ();
-       printf ("\tregs.fault_pc = m68k_getpci ();\n");
+       printf ("\tregs.instruction_pc = m68k_getpci ();\n");
        m68k_pc_offset = 0;
 }
 
@@ -631,17 +580,14 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
                        start_brace ();
                        /* This would ordinarily be done in gen_nextiword, which we bypass.  */
                        insn_n_cycles += 4;
-                       if (using_ce020 || using_mmu)
-                               printf ("\t%sa = x_get_disp_ea_020 (m68k_areg (regs, %s), x_next_iword ());\n", name, reg);
-                       else
-                               printf ("\t%sa = get_disp_ea_020 (m68k_areg (regs, %s), next_iword ());\n", name, reg);
+                       printf ("\t%sa = %s (m68k_areg (regs, %s), %s ());\n", name, disp020, reg, nextw);
                } else {
                        if (!(flags & GF_AD8R)) {
                                addcycles000 (2);
                                insn_n_cycles += 2;
                                count_cycles_ea += 2;
                        }
-                       printf ("\t%sa = get_disp_ea_000 (m68k_areg (regs, %s), %s);\n", name, reg, gen_nextiword (flags));
+                       printf ("\t%sa = %s (m68k_areg (regs, %s), %s);\n", name, disp000, reg, gen_nextiword (flags));
                        count_read_ea++; 
                }
                break;
@@ -660,10 +606,7 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
                        /* This would ordinarily be done in gen_nextiword, which we bypass.  */
                        insn_n_cycles += 4;
                        printf ("\ttmppc = m68k_getpc ();\n");
-                       if (using_ce020 || using_mmu)
-                               printf ("\t%sa = x_get_disp_ea_020 (tmppc, x_next_iword ());\n", name);
-                       else
-                               printf ("\t%sa = get_disp_ea_020 (tmppc, next_iword ());\n", name);
+                       printf ("\t%sa = %s (tmppc, %s ());\n", name, disp020, nextw);
                } else {
                        printf ("\ttmppc = m68k_getpc () + %d;\n", m68k_pc_offset);
                        if (!(flags & GF_PC8R)) {
@@ -671,7 +614,7 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
                                insn_n_cycles += 2;
                                count_cycles_ea += 2;
                        }
-                       printf ("\t%sa = get_disp_ea_000 (tmppc, %s);\n", name, gen_nextiword (flags));
+                       printf ("\t%sa = %s (tmppc, %s);\n", name, disp000, gen_nextiword (flags));
                }
 
                break;
@@ -750,8 +693,8 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
                        offset = m68k_pc_offset_last;
                }
                printf ("\tif (%sa & 1) {\n", name);
-               printf ("\t\texception3 (opcode, m68k_getpc () + %d, %sa);\n",
-                       offset, name);
+               incpc ("%d", offset);
+               printf ("\t\texception3 (opcode, %sa);\n", name);
                printf ("\t\tgoto %s;\n", endlabelstr);
                printf ("\t}\n");
                need_endlabel = 1;
@@ -772,9 +715,9 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
                        }
                } else if (using_ce) {
                        switch (size) {
-                       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;
+                       case sz_byte: printf ("\tuae_s8 %s = %s (%sa);\n", name, srcb, name); count_read++; break;
+                       case sz_word: printf ("\tuae_s16 %s = %s (%sa);\n", name, srcw, name); count_read++; break;
+                       case sz_long: printf ("\tuae_s32 %s = %s (%sa) << 16; %s |= %s (%sa + 2);\n", name, srcw, name, name, srcw, name); count_read += 2; break;
                        default: abort ();
                        }
                } else if (using_mmu) {
@@ -787,17 +730,17 @@ 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_mmu (%sa);\n", name, name); break;
-                               case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = get_word_mmu (%sa);\n", name, name); break;
-                               case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = get_long_mmu (%sa);\n", name, name); break;
+                               case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = %s (%sa);\n", name, srcb, name); break;
+                               case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = %s (%sa);\n", name, srcw, name); break;
+                               case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = %s (%sa);\n", name, srcl, name); break;
                                default: abort ();
                                }
                        }
                } else {
                        switch (size) {
-                       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;
+                       case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = %s (%sa);\n", name, srcb, name); count_read++; break;
+                       case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = %s (%sa);\n", name, srcw, name); count_read++; break;
+                       case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = %s (%sa);\n", name, srcl, name); count_read += 2; break;
                        default: abort ();
                        }
                }
@@ -933,22 +876,22 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha
                } else if (using_ce) {
                        switch (size) {
                        case sz_byte:
-                               printf ("\tput_byte_ce (%sa, %s);\n", to, from);
+                               printf ("\tx_put_byte (%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);
+                               printf ("\tx_put_word (%sa, %s);\n", to, from);
                                count_write++;
                                break;
                        case sz_long:
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
                                        abort ();
                                if (store_dir)
-                                       printf ("\tput_word_ce (%sa + 2, %s); put_word_ce (%sa, %s >> 16);\n", to, from, to, from);
+                                       printf ("\t%s (%sa + 2, %s); %s (%sa, %s >> 16);\n", dstw, to, from, dstw, to, from);
                                else
-                                       printf ("\tput_word_ce (%sa, %s >> 16); put_word_ce (%sa + 2, %s);\n", to, from, to, from);
+                                       printf ("\t%s (%sa, %s >> 16); %s (%sa + 2, %s);\n", dstw, to, from, dstw, to, from);
                                count_write += 2;
                                break;
                        default:
@@ -961,7 +904,7 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha
                                if (flags & GF_FC)
                                        printf ("\tdfc_put_byte (%sa, %s);\n", to, from);
                                else
-                                       printf ("\tput_byte_mmu (%sa, %s);\n", to, from);
+                                       printf ("\t%s (%sa, %s);\n", dstb, to, from);
                                break;
                        case sz_word:
                                insn_n_cycles += 4;
@@ -970,7 +913,7 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha
                                if (flags & GF_FC)
                                        printf ("\tdfc_put_word (%sa, %s);\n", to, from);
                                else
-                                       printf ("\tput_word_mmu (%sa, %s);\n", to, from);
+                                       printf ("\t%s (%sa, %s);\n", dstw, to, from);
                                break;
                        case sz_long:
                                insn_n_cycles += 8;
@@ -979,7 +922,7 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha
                                if (flags & GF_FC)
                                        printf ("\tdfc_put_long (%sa, %s);\n", to, from);
                                else
-                                       printf ("\tput_long_mmu (%sa, %s);\n", to, from);
+                                       printf ("\t%s (%sa, %s);\n", dstl, to, from);
                                break;
                        default:
                                abort ();
@@ -988,21 +931,21 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha
                        switch (size) {
                        case sz_byte:
                                insn_n_cycles += 4;
-                               printf ("\tput_byte (%sa, %s);\n", to, from);
+                               printf ("\t%s (%sa, %s);\n", dstb, 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);
+                               printf ("\t%s (%sa, %s);\n", dstw, 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);
+                               printf ("\t%s (%sa, %s);\n", dstl, to, from);
                                count_write += 2;
                                break;
                        default:
@@ -1074,17 +1017,17 @@ static void genmovemel_ce (uae_u16 opcode)
                addcycles000 (2);
        start_brace ();
        if (table68k[opcode].size == sz_long) {
-               printf ("\twhile (dmask) { v = get_word_ce(srca) << 16; v |= get_word_ce(srca + 2); m68k_dreg (regs, movem_index1[dmask]) = v; srca += %d; dmask = movem_next[dmask]; }\n",
-                       size);
-               printf ("\twhile (amask) { v = get_word_ce(srca) << 16; v |= get_word_ce(srca + 2); m68k_areg (regs, movem_index1[amask]) = v; srca += %d; amask = movem_next[amask]; }\n",
-                       size);
+               printf ("\twhile (dmask) { v = %s (srca) << 16; v |= %s (srca + 2); m68k_dreg (regs, movem_index1[dmask]) = v; srca += %d; dmask = movem_next[dmask]; }\n",
+                       srcw, srcw, size);
+               printf ("\twhile (amask) { v = %s (srca) << 16; v |= %s (srca + 2); m68k_areg (regs, movem_index1[amask]) = v; srca += %d; amask = movem_next[amask]; }\n",
+                       srcw, srcw, size);
        } else {
-               printf ("\twhile (dmask) { m68k_dreg (regs, movem_index1[dmask]) = (uae_s32)(uae_s16)get_word_ce(srca); srca += %d; dmask = movem_next[dmask]; }\n",
-                       size);
-               printf ("\twhile (amask) { m68k_areg (regs, movem_index1[amask]) = (uae_s32)(uae_s16)get_word_ce(srca); srca += %d; amask = movem_next[amask]; }\n",
-                       size);
+               printf ("\twhile (dmask) { m68k_dreg (regs, movem_index1[dmask]) = (uae_s32)(uae_s16)%s (srca); srca += %d; dmask = movem_next[dmask]; }\n",
+                       srcw, size);
+               printf ("\twhile (amask) { m68k_areg (regs, movem_index1[amask]) = (uae_s32)(uae_s16)%s (srca); srca += %d; amask = movem_next[amask]; }\n",
+                       srcw, size);
        }
-       printf ("\tget_word_ce (srca);\n"); // and final extra word fetch that goes nowhere..
+       printf ("\t%s (srca);\n", srcw); // and final extra word fetch that goes nowhere..
        count_read++;
        if (table68k[opcode].dmode == Aipi)
                printf ("\tm68k_areg (regs, dstreg) = srca;\n");
@@ -1110,7 +1053,7 @@ static void genmovemle (uae_u16 opcode)
        if (table68k[opcode].dmode == Apdi) {
                printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n");
                if (!using_mmu)
-                       printf ("\tint type = get_cpu_model() >= 68020;\n");
+                       printf ("\tint type = get_cpu_model () >= 68020;\n");
                printf ("\twhile (amask) {\n");
                printf ("\t\tsrca -= %d;\n", size);
                if (!using_mmu)
@@ -1145,32 +1088,32 @@ static void genmovemle_ce (uae_u16 opcode)
        if (table68k[opcode].size == sz_long) {
                if (table68k[opcode].dmode == Apdi) {
                        printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n");
-                       printf ("\twhile (amask) { srca -= %d; put_word_ce (srca, m68k_areg (regs, movem_index2[amask]) >> 16); put_word_ce (srca + 2, m68k_areg (regs, movem_index2[amask])); amask = movem_next[amask]; }\n",
-                               size);
-                       printf ("\twhile (dmask) { srca -= %d; put_word_ce (srca, m68k_dreg (regs, movem_index2[dmask]) >> 16); put_word_ce (srca + 2, m68k_dreg (regs, movem_index2[dmask])); dmask = movem_next[dmask]; }\n",
-                               size);
+                       printf ("\twhile (amask) { srca -= %d; %s (srca, m68k_areg (regs, movem_index2[amask]) >> 16); %s (srca + 2, m68k_areg (regs, movem_index2[amask])); amask = movem_next[amask]; }\n",
+                               size, dstw, dstw);
+                       printf ("\twhile (dmask) { srca -= %d; %s (srca, m68k_dreg (regs, movem_index2[dmask]) >> 16); %s (srca + 2, m68k_dreg (regs, movem_index2[dmask])); dmask = movem_next[dmask]; }\n",
+                               size, dstw, dstw);
                        printf ("\tm68k_areg (regs, dstreg) = srca;\n");
                } else {
                        printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
-                       printf ("\twhile (dmask) { put_word_ce (srca, m68k_dreg (regs, movem_index1[dmask]) >> 16); put_word_ce (srca + 2, m68k_dreg (regs, movem_index1[dmask])); srca += %d; dmask = movem_next[dmask]; }\n",
-                               size);
-                       printf ("\twhile (amask) { put_word_ce (srca, m68k_areg (regs, movem_index1[amask]) >> 16); put_word_ce (srca + 2, m68k_areg (regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n",
-                               size);
+                       printf ("\twhile (dmask) { %s (srca, m68k_dreg (regs, movem_index1[dmask]) >> 16); %s (srca + 2, m68k_dreg (regs, movem_index1[dmask])); srca += %d; dmask = movem_next[dmask]; }\n",
+                               dstw, dstw, size);
+                       printf ("\twhile (amask) { %s (srca, m68k_areg (regs, movem_index1[amask]) >> 16); %s (srca + 2, m68k_areg (regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n",
+                               dstw, dstw, size);
                }
        } else {
                if (table68k[opcode].dmode == Apdi) {
                        printf ("\tuae_u16 amask = mask & 0xff, dmask = (mask >> 8) & 0xff;\n");
-                       printf ("\twhile (amask) { srca -= %d; put_word_ce (srca, m68k_areg (regs, movem_index2[amask])); amask = movem_next[amask]; }\n",
-                               size);
-                       printf ("\twhile (dmask) { srca -= %d; put_word_ce (srca, m68k_dreg (regs, movem_index2[dmask])); dmask = movem_next[dmask]; }\n",
-                               size);
+                       printf ("\twhile (amask) { srca -= %d; %s (srca, m68k_areg (regs, movem_index2[amask])); amask = movem_next[amask]; }\n",
+                               size, dstw);
+                       printf ("\twhile (dmask) { srca -= %d; %s (srca, m68k_dreg (regs, movem_index2[dmask])); dmask = movem_next[dmask]; }\n",
+                               size, dstw);
                        printf ("\tm68k_areg (regs, dstreg) = srca;\n");
                } else {
                        printf ("\tuae_u16 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
-                       printf ("\twhile (dmask) { put_word_ce (srca, m68k_dreg (regs, movem_index1[dmask])); srca += %d; dmask = movem_next[dmask]; }\n",
-                               size);
-                       printf ("\twhile (amask) { put_word_ce (srca, m68k_areg (regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n",
-                               size);
+                       printf ("\twhile (dmask) { %s (srca, m68k_dreg (regs, movem_index1[dmask])); srca += %d; dmask = movem_next[dmask]; }\n",
+                               dstw, size);
+                       printf ("\twhile (amask) { %s (srca, m68k_areg (regs, movem_index1[amask])); srca += %d; amask = movem_next[amask]; }\n",
+                               dstw, size);
                }
        }
        count_ncycles++;
@@ -1471,7 +1414,7 @@ static void bsetcycles (struct instr *curi)
                if (isreg (curi->dmode)) {
                        addcycles000 (2);
                        if (curi->mnemo != i_BTST && using_ce) {
-                               printf ("\tif (src > 15) do_cycles_ce000 (2);\n");
+                               printf ("\tif (src > 15) %s (2);\n", do_cycles);
                                count_ncycles++;
                        }
                }
@@ -1489,10 +1432,56 @@ static void gen_opcode (unsigned long int opcode)
 
        insn_n_cycles = using_prefetch ? 0 : 4;
 
-       if (using_ce020) {
+       prefetch_long = NULL;
+       srcli = NULL;
+       srcbi = NULL;
+       disp000 = "get_disp_ea_000";
+       disp020 = "get_disp_ea_020";
+       nextw = NULL;
+       nextl = NULL;
+       do_cycles = "do_cycles";
+
+       if (using_indirect) {
+               // tracer
+               if (!using_ce020) {
+                       prefetch_word = "get_word_ce000_prefetch";
+                       srcli = "x_get_ilong";
+                       srcwi = "x_get_iword";
+                       srcbi = "x_get_ibyte";
+                       srcl = "x_get_long";
+                       dstl = "x_put_long";
+                       srcw = "x_get_word";
+                       dstw = "x_put_word";
+                       srcb = "x_get_byte";
+                       dstb = "x_put_byte";
+                       do_cycles = "do_cycles_ce000";
+               } else if (using_ce020) {
+                       disp020 = "x_get_disp_ea_020";
+                       prefetch_long = "get_long_ce020_prefetch";
+                       prefetch_word = "get_word_ce020_prefetch";
+                       srcli = "x_get_ilong";
+                       srcwi = "x_get_iword";
+                       srcbi = "x_get_ibyte";
+                       srcl = "x_get_long";
+                       dstl = "x_put_long";
+                       srcw = "x_get_word";
+                       dstw = "x_put_word";
+                       srcb = "x_get_byte";
+                       dstb = "x_put_byte";
+                       do_cycles = "do_cycles_ce020";
+               }
+
+       } else if (using_ce020) {
+               disp020 = "x_get_disp_ea_020";
+               do_cycles = "do_cycles_ce020";
                if (using_ce020 == 2) {
-                       ce020_prefetch_long = "get_long_ce030_prefetch";
-                       ce020_prefetch_word = "get_word_ce030_prefetch";
+                       // 68030 CE
+                       prefetch_long = "get_long_ce030_prefetch";
+                       prefetch_word = "get_word_ce030_prefetch";
+                       nextw = "next_iword_030ce";
+                       nextl = "next_ilong_030ce";
+                       srcli = "get_word_ce030_prefetch";
+                       srcwi = "get_long_ce030_prefetch";
                        srcl = "get_long_ce030";
                        dstl = "put_long_ce030";
                        srcw = "get_word_ce030";
@@ -1500,8 +1489,13 @@ static void gen_opcode (unsigned long int opcode)
                        srcb = "get_byte_ce030";
                        dstb = "put_byte_ce030";
                } else {
-                       ce020_prefetch_long = "get_long_ce020_prefetch";
-                       ce020_prefetch_word = "get_word_ce020_prefetch";
+                       // 68020 CE
+                       prefetch_long = "get_long_ce020_prefetch";
+                       prefetch_word = "get_word_ce020_prefetch";
+                       nextw = "next_iword_020ce";
+                       nextl = "next_ilong_020ce";
+                       srcli = "get_word_ce020_prefetch";
+                       srcwi = "get_long_ce020_prefetch";
                        srcl = "get_long_ce020";
                        dstl = "put_long_ce020";
                        srcw = "get_word_ce020";
@@ -1510,6 +1504,15 @@ static void gen_opcode (unsigned long int opcode)
                        dstb = "put_byte_ce020";
                }
        } else if (using_mmu) {
+               // 68040 MMU
+               disp020 = "x_get_disp_ea_020";
+               prefetch_long = "get_ilong_mmu";
+               prefetch_word = "get_iword_mmu";
+               nextw = "next_iword_mmu";
+               nextl = "next_ilong_mmu";
+               srcli = "get_ilong_mmu";
+               srcwi = "get_iword_muu";
+               srcbi = "get_ibyte_mmu";
                srcl = "get_long_mmu";
                dstl = "put_long_mmu";
                srcw = "get_word_mmu";
@@ -1517,13 +1520,35 @@ static void gen_opcode (unsigned long int opcode)
                srcb = "get_byte_mmu";
                dstb = "put_byte_mmu";
        } else if (using_ce) {
-               srcl = "get_long_ce";
-               dstl = "put_long_ce";
-               srcw = "get_word_ce";
-               dstw = "put_word_ce";
-               srcb = "get_byte_ce";
-               dstb = "put_byte_ce";
+               // 68000 ce
+               prefetch_word = "get_word_ce000_prefetch";
+               srcwi = "get_wordi_ce000";
+               srcl = "get_long_ce000";
+               dstl = "put_long_ce000";
+               srcw = "get_word_ce000";
+               dstw = "put_word_ce000";
+               srcb = "get_byte_ce000";
+               dstb = "put_byte_ce000";
+               do_cycles = "do_cycles_ce000";
+       } else if (using_prefetch) {
+               prefetch_word = "get_word_prefetch";
+               prefetch_long = "get_long_prefetch";
+               srcwi = "get_wordi";
+               srcl = "get_long";
+               dstl = "put_long";
+               srcw = "get_word";
+               dstw = "put_word";
+               srcb = "get_byte";
+               dstb = "put_byte";
        } else {
+               // generic
+               prefetch_long = "get_ilong";
+               prefetch_word = "get_iword";
+               nextw = "next_iword";
+               nextl = "next_ilong";
+               srcli = "get_ilong";
+               srcwi = "get_iword";
+               srcbi = "get_ibyte";
                srcl = "get_long";
                dstl = "put_long";
                srcw = "get_word";
@@ -1547,14 +1572,14 @@ static void gen_opcode (unsigned long int opcode)
 
                /* fall through */
        case 2: /* priviledged */
-               printf ("if (!regs.s) { Exception (8, 0); goto %s; }\n", endlabelstr);
+               printf ("if (!regs.s) { Exception (8); goto %s; }\n", endlabelstr);
                need_endlabel = 1;
                start_brace ();
                break;
        case 3: /* privileged if size == word */
                if (curi->size == sz_byte)
                        break;
-               printf ("if (!regs.s) { Exception (8, 0); goto %s; }\n", endlabelstr);
+               printf ("if (!regs.s) { Exception (8); goto %s; }\n", endlabelstr);
                need_endlabel = 1;
                start_brace ();
                break;
@@ -2047,7 +2072,7 @@ static void gen_opcode (unsigned long int opcode)
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                gen_set_fault_pc ();
                sync_m68k_pc ();
-               printf ("\tException (src + 32, 0);\n");
+               printf ("\tException (src + 32);\n");
                did_prefetch = 1;
                m68k_pc_offset = 0;
                break;
@@ -2066,12 +2091,12 @@ static void gen_opcode (unsigned long int opcode)
                printf ("\tcpureset ();\n");
                addcycles000 (128);
                if (using_prefetch)
-                       printf ("\tregs.irc = get_iword (4);\n");
+                       printf ("\tregs.irc = %s (4);\n", srcwi);
                break;
        case i_NOP:
                fill_prefetch_next ();
                if (using_ce020)
-                       printf ("\tdo_cycles_ce (6 * CYCLE_UNIT);\n");
+                       printf ("\t%s (6);\n", do_cycles);
                break;
        case i_STOP:
                if (using_prefetch) {
@@ -2088,11 +2113,11 @@ static void gen_opcode (unsigned long int opcode)
                did_prefetch = -1;
                break;
        case i_LPSTOP: /* 68060 */
-               printf ("\tuae_u16 sw = get_iword (2);\n");
+               printf ("\tuae_u16 sw = x_get_iword (2);\n");
                printf ("\tuae_u16 sr;\n");
-               printf ("\tif (sw != (0x100|0x80|0x40)) { Exception (4, 0); goto %s; }\n", endlabelstr);
-               printf ("\tsr = get_iword (4);\n");
-               printf ("\tif (!(sr & 0x8000)) { Exception (8, 0); goto %s; }\n", endlabelstr);
+               printf ("\tif (sw != (0x100|0x80|0x40)) { Exception (4); goto %s; }\n", endlabelstr);
+               printf ("\tsr = x_get_iword (4);\n");
+               printf ("\tif (!(sr & 0x8000)) { Exception (8); goto %s; }\n", endlabelstr);
                printf ("\tregs.sr = sr;\n");
                printf ("\tMakeFromSR ();\n");
                printf ("\tm68k_setstopped();\n");
@@ -2130,12 +2155,12 @@ static void gen_opcode (unsigned long int opcode)
                    printf ("\t\telse if (frame == 0x9) { m68k_areg (regs, 7) += offset + 12; break; }\n");
                    printf ("\t\telse if (frame == 0xa) { m68k_areg (regs, 7) += offset + 24; break; }\n");
                    printf ("\t\telse if (frame == 0xb) { m68k_areg (regs, 7) += offset + 84; break; }\n");
-                   printf ("\t\telse { m68k_areg (regs, 7) += offset; Exception (14, 0); goto %s; }\n", endlabelstr);
+                   printf ("\t\telse { m68k_areg (regs, 7) += offset; Exception (14); goto %s; }\n", endlabelstr);
                    printf ("\t\tregs.sr = newsr; MakeFromSR ();\n}\n");
                    pop_braces (old_brace_level);
                    printf ("\tregs.sr = newsr; MakeFromSR ();\n");
                    printf ("\tif (newpc & 1) {\n");
-                   printf ("\t\texception3i (0x%04X, m68k_getpc (), newpc);\n", opcode);
+                   printf ("\t\texception3i (0x%04X, newpc);\n", opcode);
                        printf ("\t\tgoto %s;\n", endlabelstr);
                        printf ("\t}\n");
                    printf ("\t\tm68k_setpc (newpc);\n");
@@ -2156,12 +2181,12 @@ static void gen_opcode (unsigned long int opcode)
                        genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0, 0);
                        printf ("\tm68k_areg (regs, 7) += offs;\n");
                        printf ("\tif (pc & 1) {\n");
-                       printf ("\t\texception3i (0x%04X, m68k_getpc (), pc);\n", opcode);
+                       printf ("\t\texception3i (0x%04X, pc);\n", opcode);
                        printf ("\t\tgoto %s;\n", endlabelstr);
                        printf ("\t}\n");
                }
            printf ("\tif (pc & 1) {\n");
-           printf ("\t\texception3i (0x%04X, m68k_getpc(), pc);\n", opcode);
+           printf ("\t\texception3i (0x%04X, pc);\n", opcode);
                printf ("\t\tgoto %s;\n", endlabelstr);
                printf ("\t}\n");
                setpc ("pc");
@@ -2212,8 +2237,6 @@ static void gen_opcode (unsigned long int opcode)
                        printf ("\tm68k_do_rts_ce030 ();\n");
                else if (using_ce)
                        printf ("\tm68k_do_rts_ce ();\n");
-               else if (using_indirect)
-                       printf ("\tm68k_do_rtsi ();\n");
                else if (using_mmu)
                        printf ("\tm68k_do_rts_mmu ();\n");
                else
@@ -2221,24 +2244,23 @@ static void gen_opcode (unsigned long int opcode)
            printf ("\tif (m68k_getpc () & 1) {\n");
                printf ("\t\tuaecptr faultpc = m68k_getpc ();\n");
                printf ("\t\tm68k_setpc (pc);\n");
-               printf ("\t\texception3i (0x%04X, pc, faultpc);\n", opcode);
-               printf ("\t\tgoto %s;\n", endlabelstr);
+               printf ("\t\texception3i (0x%04X, faultpc);\n", opcode);
                printf ("\t}\n");
                count_read += 2;
                m68k_pc_offset = 0;
                fill_prefetch_full ();
-           need_endlabel = 1;
                break;
        case i_TRAPV:
                sync_m68k_pc ();
                fill_prefetch_next ();
                printf ("\tif (GET_VFLG ()) {\n");
-               printf ("\t\tException (7, m68k_getpc ());\n");
+               printf ("\t\tException (7);\n");
                printf ("\t\tgoto %s;\n", endlabelstr);
                printf ("\t}\n");
                need_endlabel = 1;
                break;
        case i_RTR:
+               printf ("\tuaecptr oldpc = m68k_getpc ();\n");
                printf ("\tMakeSR ();\n");
                genamode_pre (Aipi, "7", sz_word, "sr", 1, 0, 0);
                genamode (Aipi, "7", sz_long, "pc", 1, 0, 0);
@@ -2247,6 +2269,11 @@ static void gen_opcode (unsigned long int opcode)
                printf ("\tregs.sr |= sr;\n");
                setpc ("pc");
                printf ("\tMakeFromSR ();\n");
+               printf ("\tif (m68k_getpc () & 1) {\n");
+               printf ("\t\tuaecptr faultpc = m68k_getpc ();\n");
+               printf ("\t\tm68k_setpc (oldpc);\n");
+               printf ("\t\texception3i (0x%04X, faultpc);\n", opcode);
+               printf ("\t}\n");
                m68k_pc_offset = 0;
                fill_prefetch_full ();
                break;
@@ -2256,7 +2283,7 @@ static void gen_opcode (unsigned long int opcode)
                printf ("\tuaecptr oldpc = m68k_getpc () + %d;\n", m68k_pc_offset);
                if (using_exception_3) {
                        printf ("\tif (srca & 1) {\n");
-                       printf ("\t\texception3i (opcode, oldpc, srca);\n");
+                       printf ("\t\texception3i (opcode, srca);\n");
                        printf ("\t\tgoto %s;\n", endlabelstr);
                        printf ("\t}\n");
                        need_endlabel = 1;
@@ -2276,8 +2303,8 @@ static void gen_opcode (unsigned long int opcode)
                                addcycles000 (6);
                        printf ("\tm68k_areg (regs, 7) -= 4;\n");
                        if (using_ce) {
-                               printf ("\tput_word_ce (m68k_areg (regs, 7), oldpc >> 16);\n");
-                               printf ("\tput_word_ce (m68k_areg (regs, 7) + 2, oldpc);\n");
+                               printf ("\tx_put_word (m68k_areg (regs, 7), oldpc >> 16);\n");
+                               printf ("\tx_put_word (m68k_areg (regs, 7) + 2, oldpc);\n");
                        } else {
                                printf ("\t%s (m68k_areg (regs, 7), oldpc);\n", dstl);
                        }
@@ -2289,7 +2316,7 @@ static void gen_opcode (unsigned long int opcode)
                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 () + 6, srca);\n");
+                       printf ("\t\texception3i (opcode, srca);\n");
                        printf ("\t\tgoto %s;\n", endlabelstr);
                        printf ("\t}\n");
                        need_endlabel = 1;
@@ -2307,7 +2334,7 @@ static void gen_opcode (unsigned long int opcode)
                printf ("\ts = (uae_s32)src + 2;\n");
                if (using_exception_3) {
                        printf ("\tif (src & 1) {\n");
-                       printf ("\t\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + s);\n");
+                       printf ("\t\texception3i (opcode, m68k_getpc () + s);\n");
                        printf ("\t\tgoto %s;\n", endlabelstr);
                        printf ("\t}\n");
                        need_endlabel = 1;
@@ -2319,8 +2346,6 @@ static void gen_opcode (unsigned long int opcode)
                        printf ("\tm68k_do_bsr_ce030 (m68k_getpc () + %d, s);\n", m68k_pc_offset);
                } else if (using_ce) {
                        printf ("\tm68k_do_bsr_ce (m68k_getpc () + %d, s);\n", m68k_pc_offset);
-               } else if (using_indirect) {    
-                       printf ("\tm68k_do_bsri (m68k_getpc () + %d, s);\n", m68k_pc_offset);
                } else if (using_mmu) {
                        printf ("\tm68k_do_bsr_mmu (m68k_getpc () + %d, s);\n", m68k_pc_offset);
                } else {
@@ -2337,7 +2362,7 @@ static void gen_opcode (unsigned long int opcode)
                        if (cpu_level < 2) {
                                addcycles000 (2);
                                printf ("\tif (cctrue (%d)) {\n", curi->cc);
-                               printf ("\t\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + 1);\n");
+                               printf ("\t\texception3i (opcode, m68k_getpc () + 1);\n");
                                printf ("\t\tgoto %s;\n", endlabelstr);
                                printf ("\t}\n");
                                sync_m68k_pc ();
@@ -2355,7 +2380,7 @@ static void gen_opcode (unsigned long int opcode)
                printf ("\tif (!cctrue (%d)) goto didnt_jump;\n", curi->cc);
                if (using_exception_3) {
                        printf ("\tif (src & 1) {\n");
-                       printf ("\t\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + 2 + (uae_s32)src);\n");
+                       printf ("\t\texception3i (opcode, m68k_getpc () + 2 + (uae_s32)src);\n");
                        printf ("\t\tgoto %s;\n", endlabelstr);
                        printf ("\t}\n");
                        need_endlabel = 1;
@@ -2423,7 +2448,7 @@ static void gen_opcode (unsigned long int opcode)
                addcycles_ce020 (4);
                if (using_exception_3) {
                        printf ("\t\t\tif (offs & 1) {\n");
-                       printf ("\t\t\t\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + 2 + (uae_s32)offs + 2);\n");
+                       printf ("\t\t\t\texception3i (opcode, m68k_getpc () + 2 + (uae_s32)offs + 2);\n");
                        printf ("\t\t\t\tgoto %s;\n", endlabelstr);
                        printf ("\t\t\t}\n");
                        need_endlabel = 1;
@@ -2461,7 +2486,6 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("val", curi->smode, "srcreg", curi->size, "src");
                break;
        case i_DIVU:
-               printf ("\tuaecptr oldpc = m68k_getpc ();\n");
                genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
                genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
                printf ("\tCLEAR_CZNV ();\n");
@@ -2474,7 +2498,7 @@ static void gen_opcode (unsigned long int opcode)
                        printf("\t\tif (dst < 0) SET_NFLG (1);\n");
                }
                incpc ("%d", m68k_pc_offset);
-               printf ("\t\tException (5, oldpc);\n");
+               printf ("\t\tException (5);\n");
                printf ("\t\tgoto %s;\n", endlabelstr);
                printf ("\t} else {\n");
                printf ("\t\tuae_u32 newv = (uae_u32)dst / (uae_u32)(uae_u16)src;\n");
@@ -2509,7 +2533,6 @@ static void gen_opcode (unsigned long int opcode)
                need_endlabel = 1;
                break;
        case i_DIVS:
-               printf ("\tuaecptr oldpc = m68k_getpc ();\n");
                genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
                genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
                printf ("\tCLEAR_CZNV ();\n");
@@ -2522,7 +2545,7 @@ static void gen_opcode (unsigned long int opcode)
                        printf("\t\tSET_ZFLG (1);\n");
                }
                incpc ("%d", m68k_pc_offset);
-               printf ("\t\tException (5, oldpc);\n");
+               printf ("\t\tException (5);\n");
                printf ("\t\tgoto %s;\n", endlabelstr);
                printf ("\t} else {\n");
                printf ("\t\tuae_s32 newv = (uae_s32)dst / (uae_s32)(uae_s16)src;\n");
@@ -2602,27 +2625,25 @@ static void gen_opcode (unsigned long int opcode)
                insn_n_cycles += (70 - 38) / 2 + 38; /* average */
                break;
        case i_CHK:
-               printf ("\tuaecptr oldpc = m68k_getpc ();\n");
                genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
                sync_m68k_pc ();
                addcycles000 (4);
                printf ("\tif (dst > src) {\n");
                printf ("\t\tSET_NFLG (0);\n");
-               printf ("\t\tException (6, oldpc);\n");
+               printf ("\t\tException (6);\n");
                printf ("\t\tgoto %s;\n", endlabelstr);
                printf ("\t}\n");
                addcycles000 (2);
                printf ("\tif ((uae_s32)dst < 0) {\n");
                printf ("\t\tSET_NFLG (1);\n");
-               printf ("\t\tException (6, oldpc);\n");
+               printf ("\t\tException (6);\n");
                printf ("\t\tgoto %s;\n", endlabelstr);
                printf ("\t}\n");
                fill_prefetch_next ();
                need_endlabel = 1;
                break;
        case i_CHK2:
-               printf ("\tuaecptr oldpc = m68k_getpc ();\n");
                genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
                genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
                fill_prefetch_0 ();
@@ -2644,7 +2665,7 @@ static void gen_opcode (unsigned long int opcode)
                }
                printf ("\tSET_ZFLG (upper == reg || lower == reg);\n");
                printf ("\tSET_CFLG_ALWAYS (lower <= upper ? reg < lower || reg > upper : reg > upper || reg < lower);\n");
-               printf ("\tif ((extra & 0x800) && GET_CFLG ()) { Exception (6, oldpc); goto %s; }\n}\n", endlabelstr);
+               printf ("\tif ((extra & 0x800) && GET_CFLG ()) { Exception (6); goto %s; }\n}\n", endlabelstr);
                need_endlabel = 1;
                break;
 
@@ -3182,18 +3203,17 @@ static void gen_opcode (unsigned long int opcode)
                if (curi->smode != am_unknown && curi->smode != am_illg)
                        genamode (curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0);
                fill_prefetch_0 ();
-               printf ("\tif (cctrue (%d)) { Exception (7, m68k_getpc ()); goto %s; }\n", curi->cc, endlabelstr);
+               printf ("\tif (cctrue (%d)) { Exception (7); goto %s; }\n", curi->cc, endlabelstr);
                need_endlabel = 1;
                break;
        case i_DIVL:
-               printf ("\tuaecptr oldpc = m68k_getpc ();\n");
                genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
                genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
                if (using_ce020) {
                        addcycles_ce020 (70);
                }
                sync_m68k_pc ();
-               printf ("\tm68k_divl(opcode, dst, extra, oldpc);\n");
+               printf ("\tm68k_divl(opcode, dst, extra);\n");
                break;
        case i_MULL:
                genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
@@ -3341,7 +3361,7 @@ static void gen_opcode (unsigned long int opcode)
                        printf ("\tif (!is_cycle_ce ()) {\n");
                        genastore ("src", curi->smode, "srcreg", curi->size, "src");
                        printf ("\t} else {\n");
-                       printf ("\t\tdo_cycles_ce000 (4);\n");
+                       printf ("\t\t%s (4);\n", do_cycles);
                        printf ("\t}\n");
                }
                break;
@@ -3620,7 +3640,7 @@ static char *outopcode (int opcode)
        return out;
 }
 
-static void generate_one_opcode (int rp)
+static void generate_one_opcode (int rp, char *extra)
 {
        int idx;
        uae_u16 smsk, dmsk;
@@ -3642,21 +3662,21 @@ static void generate_one_opcode (int rp)
        if (opcode_next_clev[rp] != cpu_level) {
                char *name = ua (lookuptab[idx].name);
                if (generate_stbl)
-                       fprintf (stblfile, "{ %sCPUFUNC(op_%04x_%d), %d }, /* %s */\n",
+                       fprintf (stblfile, "{ %sCPUFUNC(op_%04x_%d%s), %d }, /* %s */\n",
                        (using_ce || using_ce020) ? "(cpuop_func*)" : "",
                        opcode, opcode_last_postfix[rp],
-                       opcode, name);
+                       extra, opcode, name);
                xfree (name);
                return;
        }
-       fprintf (headerfile, "extern %s op_%04lx_%d_nf;\n",
-               (using_ce || using_ce020) ? "cpuop_func_ce" : "cpuop_func", opcode, postfix);
-       fprintf (headerfile, "extern %s op_%04lx_%d_ff;\n",
-               (using_ce || using_ce020) ? "cpuop_func_ce" : "cpuop_func", opcode, postfix);
+       fprintf (headerfile, "extern %s op_%04lx_%d%s_nf;\n",
+               (using_ce || using_ce020) ? "cpuop_func_ce" : "cpuop_func", opcode, postfix, extra);
+       fprintf (headerfile, "extern %s op_%04lx_%d%s_ff;\n",
+               (using_ce || using_ce020) ? "cpuop_func_ce" : "cpuop_func", opcode, postfix, extra);
        printf ("/* %s */\n", outopcode (opcode));
        if (i68000)
                printf("#ifndef CPUEMU_68000_ONLY\n");
-       printf ("%s REGPARAM2 CPUFUNC(op_%04lx_%d)(uae_u32 opcode)\n{\n", (using_ce || using_ce020) ? "void" : "unsigned long", opcode, postfix);
+       printf ("%s REGPARAM2 CPUFUNC(op_%04lx_%d%s)(uae_u32 opcode)\n{\n", (using_ce || using_ce020) ? "void" : "unsigned long", opcode, postfix, extra);
 
        switch (table68k[opcode].stype) {
        case 0: smsk = 7; break;
@@ -3748,16 +3768,16 @@ static void generate_one_opcode (int rp)
                char *name = ua (lookuptab[idx].name);
                if (i68000)
                        fprintf (stblfile, "#ifndef CPUEMU_68000_ONLY\n");
-               fprintf (stblfile, "{ %sCPUFUNC(op_%04x_%d), %d }, /* %s */\n",
+               fprintf (stblfile, "{ %sCPUFUNC(op_%04x_%d%s), %d }, /* %s */\n",
                        (using_ce || using_ce020) ? "(cpuop_func*)" : "",
-                       opcode, postfix, opcode, name);
+                       opcode, postfix, extra, opcode, name);
                if (i68000)
                        fprintf (stblfile, "#endif\n");
                xfree (name);
        }
 }
 
-static void generate_func (void)
+static void generate_func (char *extra)
 {
        int j, rp;
 
@@ -3783,7 +3803,7 @@ static void generate_func (void)
                int k = (j * nr_cpuop_funcs) / 8;
                printf ("#ifdef PART_%d\n",j);
                for (; rp < k; rp++)
-                       generate_one_opcode (rp);
+                       generate_one_opcode (rp, extra);
                printf ("#endif\n\n");
        }
 
@@ -3791,10 +3811,89 @@ static void generate_func (void)
                fprintf (stblfile, "{ 0, 0 }};\n");
 }
 
-int main (int argc, char **argv)
+static void generate_cpu (int id, int mode)
 {
-       int i, rp, postfix2;
        char fname[100];
+       char *extra, *extraup;
+       static int postfix2 = -1;
+       int rp;
+
+       using_tracer = mode;
+       extra = "";
+       extraup = "";
+       if (using_tracer) {
+               extra = "_t";
+               extraup = "_T";
+       }
+
+       postfix = id;
+       if (id == 0 || id == 11 || id == 12 || id == 20 || id == 21 || id == 31) {
+               if (generate_stbl)
+                       fprintf (stblfile, "#ifdef CPUEMU_%d%s\n", postfix, extraup);
+               postfix2 = postfix;
+               sprintf (fname, "cpuemu_%d%s.cpp", postfix, extra);
+               freopen (fname, "wb", stdout);
+               generate_includes (stdout);
+       }
+
+       using_mmu = 0;
+       using_prefetch = 0;
+       using_ce = 0;
+       using_ce020 = 0;
+       using_mmu = 0;
+
+       if (id == 11 || id == 12) { // 11 = 68000 prefetch, 12 = 68000 cycle-exact
+               cpu_level = 0;
+               using_prefetch = 1;
+               using_exception_3 = 1;
+               if (id == 12)
+                       using_ce = 1;
+               for (rp = 0; rp < nr_cpuop_funcs; rp++)
+                       opcode_next_clev[rp] = 0;
+       } else if (id == 20) { // 68020 cycle-exact
+               cpu_level = 2;
+               using_ce020 = 1;
+               read_counts ();
+               for (rp = 0; rp < nr_cpuop_funcs; rp++)
+                       opcode_next_clev[rp] = cpu_level;
+       } else if (id == 21 || id == 22 || id == 23) { // 68030+ "cycle-exact"
+               cpu_level = 3 + (23 - id);
+               using_ce020 = 2;
+               if (id == 21) {
+                       read_counts ();
+                       for (rp = 0; rp < nr_cpuop_funcs; rp++)
+                               opcode_next_clev[rp] = cpu_level;
+               }
+       } else if (id >= 31 && id < 40) { // 31 = 68040 MMU
+               cpu_level = 4;
+               using_mmu = 1;
+               if (id == 31)
+                       read_counts ();
+               for (rp = 0; rp < nr_cpuop_funcs; rp++)
+                       opcode_next_clev[rp] = cpu_level;
+       } else {
+               cpu_level = 5 - id; // "generic"
+       }
+       using_indirect = using_ce && !using_ce020;
+
+       if (generate_stbl) {
+               if ((id > 0 && id < 10) || (id >= 20))
+                       fprintf (stblfile, "#ifndef CPUEMU_68000_ONLY\n");
+               fprintf (stblfile, "const struct cputbl CPUFUNC(op_smalltbl_%d%s)[] = {\n", postfix, extra);
+       }
+       generate_func (extra);
+       if (generate_stbl) {
+               if ((id > 0 && id < 10) || (id >= 20))
+                       fprintf (stblfile, "#endif /* CPUEMU_68000_ONLY */\n");
+               if (postfix2 >= 0)
+                       fprintf (stblfile, "#endif /* CPUEMU_%d%s */\n", postfix2, extraup);
+       }
+       postfix2 = -1;
+}
+
+int main (int argc, char **argv)
+{
+       int i;
 
        read_table68k ();
        do_merges ();
@@ -3819,70 +3918,11 @@ int main (int argc, char **argv)
        using_exception_3 = 1;
        using_ce = 0;
 
-       postfix2 = -1;
        for (i = 0; i < 32; i++) {
-               postfix = i;
                if ((i >= 6 && i < 11) || (i > 12 && i < 20) || (i > 23 && i < 31))
                        continue;
                generate_stbl = 1;
-               if (i == 0 || i == 11 || i == 12 || i == 20 || i == 21 || i == 31) {
-                       if (generate_stbl)
-                               fprintf (stblfile, "#ifdef CPUEMU_%d\n", postfix);
-                       postfix2 = postfix;
-                       sprintf (fname, "cpuemu_%d.cpp", postfix);
-                       freopen (fname, "wb", stdout);
-                       generate_includes (stdout);
-               }
-               using_mmu = 0;
-               using_prefetch = 0;
-               using_ce = 0;
-               using_ce020 = 0;
-               using_mmu = 0;
-               cpu_level = 5 - i;
-               if (i == 11 || i == 12) {
-                       cpu_level = 0;
-                       using_prefetch = 1;
-                       using_exception_3 = 1;
-                       if (i == 12)
-                               using_ce = 1;
-                       for (rp = 0; rp < nr_cpuop_funcs; rp++)
-                               opcode_next_clev[rp] = 0;
-               } else if (i == 20) {
-                       cpu_level = 2;
-                       using_ce020 = 1;
-                       read_counts ();
-                       for (rp = 0; rp < nr_cpuop_funcs; rp++)
-                               opcode_next_clev[rp] = cpu_level;
-               } else if (i == 21 || i == 22 || i == 23) {
-                       cpu_level = 3 + (23 - i);
-                       using_ce020 = 2;
-                       if (i == 21) {
-                               read_counts ();
-                               for (rp = 0; rp < nr_cpuop_funcs; rp++)
-                                       opcode_next_clev[rp] = cpu_level;
-                       }
-               } else if (i >= 31 && i < 40) {
-                       cpu_level = 4;
-                       using_mmu = 1;
-                       if (i == 31)
-                               read_counts ();
-                       for (rp = 0; rp < nr_cpuop_funcs; rp++)
-                               opcode_next_clev[rp] = cpu_level;
-               }
-
-               if (generate_stbl) {
-                       if ((i > 0 && i < 10) || (i >= 20))
-                               fprintf (stblfile, "#ifndef CPUEMU_68000_ONLY\n");
-                       fprintf (stblfile, "const struct cputbl CPUFUNC(op_smalltbl_%d)[] = {\n", postfix);
-               }
-               generate_func ();
-               if (generate_stbl) {
-                       if ((i > 0 && i < 10) || (i >= 20))
-                               fprintf (stblfile, "#endif /* CPUEMU_68000_ONLY */\n");
-                       if (postfix2 >= 0)
-                               fprintf (stblfile, "#endif /* CPUEMU_%d */\n", postfix2);
-               }
-               postfix2 = -1;
+               generate_cpu (i, 0);
        }
 
        free (table68k);
index edbf4d112fce72c33d64a1c46c36d516942b6566..b267a2334ca268c2d58dca723907b174f561bc45 100644 (file)
@@ -122,6 +122,7 @@ typedef int (*rawread_func)(int, uae_u8*, int, int, int, uae_u32);
 typedef int (*write_func)(int, uae_u8*, int, int);
 typedef int (*isatapi_func)(int);
 typedef int (*ismedia_func)(int, int);
+typedef int (*scsiemu_func)(int, uae_u8*);
 
 struct device_functions {
        const TCHAR *name;
@@ -147,6 +148,8 @@ struct device_functions {
        isatapi_func isatapi;
        ismedia_func ismedia;
 
+       scsiemu_func scsiemu;
+
 };
 
 extern struct device_functions *device_func[MAX_TOTAL_SCSI_DEVICES];
index b76d5888aed47f77e03f3b014a9f8dae88122d71..63398bbaaada7118e834a67bc44e6e08b7da0fb5 100644 (file)
@@ -7,8 +7,10 @@
   */
 
 extern void CIA_reset (void);
-extern void CIA_vsync_handler (int);
-extern void CIA_hsync_handler (int);
+extern void CIA_vsync_prehandler (void);
+extern void CIA_hsync_prehandler (void);
+extern void CIA_vsync_posthandler (bool);
+extern void CIA_hsync_posthandler (bool);
 extern void CIA_handler (void);
 
 extern void diskindex_handler (void);
@@ -24,6 +26,4 @@ extern int parallel_direct_read_data (uae_u8*);
 extern int parallel_direct_write_status (uae_u8, uae_u8);
 extern int parallel_direct_read_status (uae_u8*);
 
-extern void CIA_inprec_prepare(void);
-
-extern void rtc_hardreset(void);
+extern void rtc_hardreset (void);
index db273c79489bd816b5017738d9be27f865f20ad4..b35d2df105c3d1266072decd6a7a8c5fb582e660 100644 (file)
@@ -14,6 +14,17 @@ STATIC_INLINE uae_u32 get_long_prefetch (int o)
 
 #ifdef CPUEMU_20
 
+
+STATIC_INLINE void do_cycles_ce020 (int clocks)
+{
+       do_cycles_ce (clocks * cpucycleunit);
+}
+STATIC_INLINE void do_cycles_ce020_mem (int clocks)
+{
+       regs.ce020memcycles -= clocks * cpucycleunit;
+       do_cycles_ce (clocks * cpucycleunit);
+}
+
 STATIC_INLINE void checkcycles_ce020 (void)
 {
        if (regs.ce020memcycles > 0)
@@ -259,6 +270,8 @@ STATIC_INLINE void m68k_do_rts_ce020 (void)
        m68k_setpc (get_long_ce020 (m68k_areg (regs, 7)));
        m68k_areg (regs, 7) += 4;
 }
+
+
 #endif
 
 #ifdef CPUEMU_21
@@ -327,10 +340,16 @@ STATIC_INLINE void m68k_do_rts_ce030 (void)
        m68k_setpc (get_long_ce030 (m68k_areg (regs, 7)));
        m68k_areg (regs, 7) += 4;
 }
+
 #endif
 
 #ifdef CPUEMU_12
 
+STATIC_INLINE void do_cycles_ce000 (int clocks)
+{
+       x_do_cycles (clocks * cpucycleunit);
+}
+
 STATIC_INLINE void ipl_fetch (void)
 {
        regs.ipl = regs.ipl_pin;
@@ -344,8 +363,9 @@ STATIC_INLINE uae_u32 mem_access_delay_word_read (uaecptr addr)
                return wait_cpu_cycle_read (addr, 1);
        case CE_MEMBANK_FAST:
        case CE_MEMBANK_FAST16BIT:
-               do_cycles_ce000 (4);
-               break;
+               uae_u32 v = get_word (addr);
+               x_do_cycles_post (4 * cpucycleunit, v);
+               return v;
        }
        return get_word (addr);
 }
@@ -357,8 +377,9 @@ STATIC_INLINE uae_u32 mem_access_delay_wordi_read (uaecptr addr)
                return wait_cpu_cycle_read (addr, 1);
        case CE_MEMBANK_FAST:
        case CE_MEMBANK_FAST16BIT:
-               do_cycles_ce000 (4);
-               break;
+               uae_u32 v = get_wordi (addr);
+               x_do_cycles_post (4 * cpucycleunit, v);
+               return v;
        }
        return get_wordi (addr);
 }
@@ -371,9 +392,9 @@ STATIC_INLINE uae_u32 mem_access_delay_byte_read (uaecptr addr)
                return wait_cpu_cycle_read (addr, 0);
        case CE_MEMBANK_FAST:
        case CE_MEMBANK_FAST16BIT:
-               do_cycles_ce000 (4);
-               break;
-
+               uae_u32 v = get_byte (addr);
+               x_do_cycles_post (4 * cpucycleunit, v);
+               return v;
        }
        return get_byte (addr);
 }
@@ -386,8 +407,9 @@ STATIC_INLINE void mem_access_delay_byte_write (uaecptr addr, uae_u32 v)
                return;
        case CE_MEMBANK_FAST:
        case CE_MEMBANK_FAST16BIT:
-               do_cycles_ce000 (4);
-               break;
+               put_byte (addr, v);
+               x_do_cycles_post (4 * cpucycleunit, v);
+               return;
        }
        put_byte (addr, v);
 }
@@ -398,50 +420,50 @@ STATIC_INLINE void mem_access_delay_word_write (uaecptr addr, uae_u32 v)
        case CE_MEMBANK_CHIP:
                wait_cpu_cycle_write (addr, 1, v);
                return;
-               break;
        case CE_MEMBANK_FAST:
        case CE_MEMBANK_FAST16BIT:
-               do_cycles_ce000 (4);
-               break;
+               put_word (addr, v);
+               x_do_cycles_post (4 * cpucycleunit, v);
+               return;
        }
        put_word (addr, v);
 }
 
-STATIC_INLINE uae_u32 get_long_ce (uaecptr addr)
+STATIC_INLINE uae_u32 get_long_ce000 (uaecptr addr)
 {
        uae_u32 v = mem_access_delay_word_read (addr) << 16;
        v |= mem_access_delay_word_read (addr + 2);
        return v;
 }
-STATIC_INLINE uae_u32 get_word_ce (uaecptr addr)
+STATIC_INLINE uae_u32 get_word_ce000 (uaecptr addr)
 {
        return mem_access_delay_word_read (addr);
 }
-STATIC_INLINE uae_u32 get_wordi_ce (uaecptr addr)
+STATIC_INLINE uae_u32 get_wordi_ce000 (int offset)
 {
-       return mem_access_delay_wordi_read (addr);
+       return mem_access_delay_wordi_read (m68k_getpc () + offset);
 }
-STATIC_INLINE uae_u32 get_byte_ce (uaecptr addr)
+STATIC_INLINE uae_u32 get_byte_ce000 (uaecptr addr)
 {
        return mem_access_delay_byte_read (addr);
 }
-STATIC_INLINE uae_u32 get_word_ce_prefetch (int o)
+STATIC_INLINE uae_u32 get_word_ce000_prefetch (int o)
 {
        uae_u32 v = regs.irc;
-       regs.irc = get_wordi_ce (m68k_getpc () + o);
+       regs.irc = x_get_iword (o);
        return v;
 }
 
-STATIC_INLINE void put_long_ce (uaecptr addr, uae_u32 v)
+STATIC_INLINE void put_long_ce000 (uaecptr addr, uae_u32 v)
 {
        mem_access_delay_word_write (addr, v >> 16);
        mem_access_delay_word_write (addr + 2, v);
 }
-STATIC_INLINE void put_word_ce (uaecptr addr, uae_u32 v)
+STATIC_INLINE void put_word_ce000 (uaecptr addr, uae_u32 v)
 {
        mem_access_delay_word_write (addr, v);
 }
-STATIC_INLINE void put_byte_ce (uaecptr addr, uae_u32 v)
+STATIC_INLINE void put_byte_ce000 (uaecptr addr, uae_u32 v)
 {
        mem_access_delay_byte_write (addr, v);
 }
@@ -449,11 +471,11 @@ STATIC_INLINE void put_byte_ce (uaecptr addr, uae_u32 v)
 STATIC_INLINE void m68k_do_rts_ce (void)
 {
        uaecptr pc;
-       pc = get_word_ce (m68k_areg (regs, 7)) << 16;
-       pc |= get_word_ce (m68k_areg (regs, 7) + 2);
+       pc = x_get_word (m68k_areg (regs, 7)) << 16;
+       pc |= x_get_word (m68k_areg (regs, 7) + 2);
        m68k_areg (regs, 7) += 4;
        if (pc & 1)
-               exception3 (0x4e75, m68k_getpc (), pc);
+               exception3 (0x4e75, pc);
        else
                m68k_setpc (pc);
 }
@@ -461,16 +483,26 @@ STATIC_INLINE void m68k_do_rts_ce (void)
 STATIC_INLINE void m68k_do_bsr_ce (uaecptr oldpc, uae_s32 offset)
 {
        m68k_areg (regs, 7) -= 4;
-       put_word_ce (m68k_areg (regs, 7), oldpc >> 16);
-       put_word_ce (m68k_areg (regs, 7) + 2, oldpc);
+       x_put_word (m68k_areg (regs, 7), oldpc >> 16);
+       x_put_word (m68k_areg (regs, 7) + 2, oldpc);
        m68k_incpc (offset);
 }
 
 STATIC_INLINE void m68k_do_jsr_ce (uaecptr oldpc, uaecptr dest)
 {
        m68k_areg (regs, 7) -= 4;
-       put_word_ce (m68k_areg (regs, 7), oldpc >> 16);
-       put_word_ce (m68k_areg (regs, 7) + 2, oldpc);
+       x_put_word (m68k_areg (regs, 7), oldpc >> 16);
+       x_put_word (m68k_areg (regs, 7) + 2, oldpc);
        m68k_setpc (dest);
 }
-#endif
\ No newline at end of file
+
+#endif
+
+STATIC_INLINE uae_u32 get_disp_ea_000 (uae_u32 base, uae_u32 dp)
+{
+       int reg = (dp >> 12) & 15;
+       uae_s32 regd = regs.regs[reg];
+       if ((dp & 0x800) == 0)
+               regd = (uae_s32)(uae_s16)regd;
+       return base + (uae_s8)dp + regd;
+}
index 61d779416ea200a1a9f00601b01147a432280e95..655c35399d6242bfcf6d219d9e16067bf20316bc 100644 (file)
@@ -1,15 +1,15 @@
- /*
-  * UAE - The Un*x Amiga Emulator
-  *
-  * custom chip support
-  *
-  * (c) 1995 Bernd Schmidt
-  */
+/*
+* UAE - The Un*x Amiga Emulator
+*
+* custom chip support
+*
+* (c) 1995 Bernd Schmidt
+*/
 
 #include "machdep/rpt.h"
 
 /* These are the masks that are ORed together in the chipset_mask option.
- * If CSMASK_AGA is set, the ECS bits are guaranteed to be set as well.  */
+* If CSMASK_AGA is set, the ECS bits are guaranteed to be set as well.  */
 #define CSMASK_ECS_AGNUS 1
 #define CSMASK_ECS_DENISE 2
 #define CSMASK_AGA 4
@@ -18,7 +18,8 @@
 uae_u32 get_copper_address (int copno);
 
 extern int custom_init (void);
-extern void customreset (int hardreset);
+extern void custom_prepare (void);
+extern void custom_reset (int hardreset);
 extern int intlev (void);
 extern void dumpcustom (void);
 
@@ -28,7 +29,7 @@ extern void do_copper (void);
 extern void notice_new_xcolors (void);
 extern void notice_screen_contents_lost (void);
 extern void init_row_map (void);
-extern void init_hz (void);
+extern void init_hz_full (void);
 extern void init_custom (void);
 
 extern bool picasso_requested_on;
@@ -36,14 +37,13 @@ extern bool picasso_on;
 extern void set_picasso_hack_rate (int hz);
 
 /* Set to 1 to leave out the current frame in average frame time calculation.
- * Useful if the debugger was active.  */
+* Useful if the debugger was active.  */
 extern int bogusframe;
-extern unsigned long int hsync_counter;
+extern unsigned long int hsync_counter, vsync_counter;
 
 extern uae_u16 dmacon;
 extern uae_u16 intena, intreq, intreqr;
 
-extern int current_hpos (void);
 extern int vpos;
 
 extern int find_copper_record (uaecptr, int *, int *);
@@ -52,7 +52,7 @@ extern int n_frames;
 
 STATIC_INLINE int dmaen (unsigned int dmamask)
 {
-    return (dmamask & dmacon) && (dmacon & 0x200);
+       return (dmamask & dmacon) && (dmacon & 0x200);
 }
 
 #define SPCFLAG_STOP 2
@@ -130,11 +130,11 @@ extern frame_time_t syncbase;
 
 #define CYCLE_REFRESH  0x01
 #define CYCLE_STROBE   0x02
-#define CYCLE_MISC     0x04
+#define CYCLE_MISC             0x04
 #define CYCLE_SPRITE   0x08
 #define CYCLE_COPPER   0x10
 #define CYCLE_BLITTER  0x20
-#define CYCLE_CPU      0x40
+#define CYCLE_CPU              0x40
 #define CYCLE_CPUNASTY 0x80
 
 extern unsigned long frametime, timeframes;
@@ -142,8 +142,8 @@ extern int plfstrt, plfstop, plffirstline, plflastline;
 extern uae_u16 htotal, vtotal, beamcon0;
 
 /* 100 words give you 1600 horizontal pixels. Should be more than enough for
- * superhires. Don't forget to update the definition in genp2c.c as well.
- * needs to be larger for superhires support */
+* superhires. Don't forget to update the definition in genp2c.c as well.
+* needs to be larger for superhires support */
 #ifdef CUSTOM_SIMPLE
 #define MAX_WORDS_PER_LINE 50
 #else
@@ -178,26 +178,26 @@ extern int xbluecolor_s, xbluecolor_b, xbluecolor_m;
 /* get resolution from bplcon0 */
 STATIC_INLINE int GET_RES_DENISE (uae_u16 con0)
 {
-    if (!(currprefs.chipset_mask & CSMASK_ECS_DENISE))
-       con0 &= ~0x40;
-    return ((con0) & 0x8000) ? RES_HIRES : ((con0) & 0x40) ? RES_SUPERHIRES : RES_LORES;
+       if (!(currprefs.chipset_mask & CSMASK_ECS_DENISE))
+               con0 &= ~0x40; // SUPERHIRES
+       return ((con0) & 0x8000) ? RES_HIRES : ((con0) & 0x40) ? RES_SUPERHIRES : RES_LORES;
 }
 STATIC_INLINE int GET_RES_AGNUS (uae_u16 con0)
 {
-    if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS))
-       con0 &= ~0x40;
-    return ((con0) & 0x8000) ? RES_HIRES : ((con0) & 0x40) ? RES_SUPERHIRES : RES_LORES;
+       if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS))
+               con0 &= ~0x40; // SUPERHIRES
+       return ((con0) & 0x8000) ? RES_HIRES : ((con0) & 0x40) ? RES_SUPERHIRES : RES_LORES;
 }
 /* get sprite width from FMODE */
 #define GET_SPRITEWIDTH(FMODE) ((((FMODE) >> 2) & 3) == 3 ? 64 : (((FMODE) >> 2) & 3) == 0 ? 16 : 32)
 /* Compute the number of bitplanes from a value written to BPLCON0  */
 STATIC_INLINE int GET_PLANES(uae_u16 bplcon0)
 {
-    if ((bplcon0 & 0x0010) && (bplcon0 & 0x7000))
-       return 0;
-    if (bplcon0 & 0x0010)
-       return 8;
-    return (bplcon0 >> 12) & 7;
+       if ((bplcon0 & 0x0010) && (bplcon0 & 0x7000))
+               return 0; // >8 planes = 0 planes
+       if (bplcon0 & 0x0010)
+               return 8; // AGA 8-planes bit
+       return (bplcon0 >> 12) & 7; // normal planes bits
 }
 
 extern void fpscounter_reset (void);
@@ -205,10 +205,11 @@ extern unsigned long idletime;
 extern int lightpen_x, lightpen_y, lightpen_cx, lightpen_cy;
 
 struct customhack {
-    uae_u16 v;
-    int vpos, hpos;
+       uae_u16 v;
+       int vpos, hpos;
 };
 void customhack_put (struct customhack *ch, uae_u16 v, int hpos);
 uae_u16 customhack_get (struct customhack *ch, int hpos);
 extern void alloc_cycle_ext (int, int);
 extern bool ispal (void);
+extern int current_maxvpos (void);
\ No newline at end of file
index 4e30a5a6251b7feda251c1f4be66b64a668346b1..45514d4dcfde4aced36f7b65d4f89fc8dfe9547d 100644 (file)
@@ -14,12 +14,13 @@ typedef enum { DRV_NONE = -1, DRV_35_DD = 0, DRV_35_HD, DRV_525_SD, DRV_35_DD_ES
 extern void DISK_init (void);
 extern void DISK_free (void);
 extern void DISK_select (uae_u8 data);
+extern void DISK_select_set (uae_u8 data);
 extern uae_u8 DISK_status (void);
 extern void disk_eject (int num);
 extern int disk_empty (int num);
 extern void disk_insert (int num, const TCHAR *name);
-extern void disk_insert_force (int num, const TCHAR *name);
-extern void DISK_check_change (void);
+extern void disk_insert_force (int num, const TCHAR *name, bool writeprotected);
+extern void DISK_vsync (void);
 extern int DISK_validate_filename (const TCHAR *fname, int leave_open, bool *wrprot, uae_u32 *crc32, struct zfile **zf);
 extern void DISK_handler (uae_u32);
 extern void DISK_update (int hpos);
index 50b349794adaf0fc6cf736ea0a1226004d9179a2..df402501365ed044c6b82aa38180ad5d90c0c6ae 100644 (file)
@@ -277,6 +277,7 @@ extern void notice_interlace_seen (void);
 extern void frame_drawn (void);
 extern void redraw_frame (void);
 extern int get_custom_limits (int *pw, int *ph, int *pdx, int *pdy);
+extern void putpixel (uae_u8 *buf, int bpp, int x, xcolnr c8, int opaq);
 
 /* Finally, stuff that shouldn't really be shared.  */
 
index 944980df1b7f8d77dcfcac9ed0a11ca009064acd..40b4c1ba8294f0d54a451424ba55abfa53aa4e41 100644 (file)
@@ -20,13 +20,12 @@ extern volatile frame_time_t vsynctime, vsyncmintime;
 extern void reset_frame_rate_hack (void);
 extern int rpt_available;
 extern frame_time_t syncbase;
+extern unsigned long int vsync_cycles;
+extern unsigned long start_cycles;
 
 extern void compute_vsynctime (void);
 extern void init_eventtab (void);
-extern void do_cycles_ce (long cycles);
-extern void do_cycles_ce020 (int clocks);
-extern void do_cycles_ce020_mem (int clocks);
-extern void do_cycles_ce000 (int clocks);
+extern void do_cycles_ce (unsigned long cycles);
 extern int is_cycle_ce (void);
 
 extern unsigned long currcycle, nextevent, is_lastline;
index 5b54cc10382f982ec7d34410425dab60e9cd3275..d32a6bb61292c1c4c9698a855daa8523f56a2a4c 100644 (file)
@@ -51,6 +51,7 @@ STATIC_INLINE unsigned long int get_cycles (void)
 STATIC_INLINE void set_cycles (unsigned long int x)
 {
        currcycle = x;
+       eventtab[ev_hsync].oldcycles = x;
 #ifdef EVT_DEBUG
        if (currcycle & (CYCLE_UNIT - 1))
                write_log (L"%x\n", currcycle);
@@ -96,18 +97,3 @@ STATIC_INLINE void do_cycles_slow (unsigned long cycles_to_add)
 
 #define do_cycles do_cycles_slow
 #define countdown pissoff
-
-/* This is a special-case function.  Normally, all events should lie in the
-future; they should only ever be active at the current cycle during
-do_cycles.  However, a snapshot is saved during do_cycles, and so when
-restoring it, we may have other events pending.  */
-
-STATIC_INLINE void handle_active_events (void)
-{
-       int i;
-       for (i = 0; i < ev_max; i++) {
-               if (eventtab[i].active && eventtab[i].evtime == currcycle) {
-                       (*eventtab[i].handler)();
-               }
-       }
-}
index 08abbf3fc0ae4b865b3048c190edf8a12956522d..5157ada37b9ca41eca71924850ccb4feff0caf5f 100644 (file)
 #endif
 
 /* AmigaOS errors */
-#define ERROR_BAD_NUMBER                 6
-#define ERROR_NO_FREE_STORE            103
-#define ERROR_OBJECT_IN_USE            202
-#define ERROR_OBJECT_EXISTS            203
-#define ERROR_DIR_NOT_FOUND            204
+#define ERROR_BAD_NUMBER                         6
+#define ERROR_NO_FREE_STORE                    103
+#define ERROR_OBJECT_IN_USE                    202
+#define ERROR_OBJECT_EXISTS                    203
+#define ERROR_DIR_NOT_FOUND                    204
 #define ERROR_OBJECT_NOT_AROUND                205
 #define ERROR_ACTION_NOT_KNOWN         209
-#define ERROR_INVALID_LOCK             211
+#define ERROR_INVALID_LOCK                     211
 #define ERROR_OBJECT_WRONG_TYPE                212
 #define ERROR_DISK_WRITE_PROTECTED     214
 #define ERROR_DIRECTORY_NOT_EMPTY      216
 #define ERROR_DEVICE_NOT_MOUNTED       218
-#define ERROR_SEEK_ERROR               219
+#define ERROR_SEEK_ERROR                       219
 #define ERROR_COMMENT_TOO_BIG          220
-#define ERROR_DISK_IS_FULL             221
+#define ERROR_DISK_IS_FULL                     221
 #define ERROR_DELETE_PROTECTED         222
 #define ERROR_WRITE_PROTECTED          223
 #define ERROR_READ_PROTECTED           224
 #define ERROR_NOT_A_DOS_DISK           225
-#define ERROR_NO_DISK                  226
+#define ERROR_NO_DISK                          226
 #define ERROR_NO_MORE_ENTRIES          232
 #define ERROR_NOT_IMPLEMENTED          236
+#define ERROR_RECORD_NOT_LOCKED                240
+#define ERROR_LOCK_COLLISION           241
+#define ERROR_LOCK_TIMEOUT                     242
+#define ERROR_UNLOCK_ERROR                     243
 
 #define A_FIBF_HIDDEN  (1<<7)
 #define A_FIBF_SCRIPT  (1<<6)
index 98a68d1431d51b6d02db9929a4497a3835673dd7..92129c183f504f6642fc5087bfd16bcf483eef9b 100644 (file)
@@ -8,6 +8,7 @@ typedef unsigned long u32;
 extern void S2X_refresh (void);
 extern void S2X_render (void);
 extern void S2X_init (int dw, int dh, int aw, int ah, int ad, int dd);
+extern void S2X_reset (void);
 extern void S2X_free (void);
 extern int S2X_getmult (void);
 
index 0351b405033038416476e51298a0fd0e3892119d..478417e0154c9b3532433fd9c34dc25edee12fec 100644 (file)
@@ -126,8 +126,6 @@ INPUTEVENT_END
 extern void handle_cd32_joystick_cia (uae_u8, uae_u8);
 extern uae_u8 handle_parport_joystick (int port, uae_u8 pra, uae_u8 dra);
 extern uae_u8 handle_joystick_buttons (uae_u8, uae_u8);
-extern int getbuttonstate (int joy, int button);
-extern int getjoystate (int joy);
 
 #define MAGICMOUSE_BOTH 0
 #define MAGICMOUSE_NATIVE_ONLY 1
@@ -154,7 +152,6 @@ extern void inputdevice_devicechange (struct uae_prefs *prefs);
 
 extern int inputdevice_translatekeycode (int keyboard, int scancode, int state);
 extern void inputdevice_setkeytranslation (struct uae_input_device_kbr_default *trans, int **kbmaps);
-extern int handle_input_event (int nr, int state, int max, int autofire);
 extern void inputdevice_do_keyboard (int code, int state);
 extern int inputdevice_iskeymapped (int keyboard, int scancode);
 extern int inputdevice_synccapslock (int, int*);
@@ -175,6 +172,8 @@ extern uae_u16 POT1DAT (void);
 extern void JOYTEST (uae_u16 v);
 extern uae_u16 JOY0DAT (void);
 extern uae_u16 JOY1DAT (void);
+extern void JOYSET (int num, uae_u16 v);
+extern uae_u16 JOYGET (int num);
 
 extern void inputdevice_vsync (void);
 extern void inputdevice_hsync (void);
@@ -211,10 +210,11 @@ extern void inputdevice_tablet_strobe (void);
 #define JSEM_MODE_DEFAULT 0
 #define JSEM_MODE_MOUSE 1
 #define JSEM_MODE_JOYSTICK 2
-#define JSEM_MODE_JOYSTICK_ANALOG 3
-#define JSEM_MODE_MOUSE_CDTV 4
-#define JSEM_MODE_JOYSTICK_CD32 5
-#define JSEM_MODE_LIGHTPEN 6
+#define JSEM_MODE_GAMEPAD 3
+#define JSEM_MODE_JOYSTICK_ANALOG 4
+#define JSEM_MODE_MOUSE_CDTV 5
+#define JSEM_MODE_JOYSTICK_CD32 6
+#define JSEM_MODE_LIGHTPEN 7
 
 #define JSEM_KBDLAYOUT 0
 #define JSEM_JOYS 100
@@ -237,33 +237,6 @@ extern int jsem_iskbdjoy (int port, const struct uae_prefs *p);
 
 extern int inputdevice_uaelib (TCHAR *, TCHAR *);
 
-#define INPREC_JOYPORT 1
-#define INPREC_JOYBUTTON 2
-#define INPREC_KEY 3
-#define INPREC_DISKINSERT 4
-#define INPREC_DISKREMOVE 5
-#define INPREC_VSYNC 6
-#define INPREC_CIAVSYNC 7
-#define INPREC_STATEFILE 0x7f
-#define INPREC_END 0xff
-#define INPREC_QUIT 0xfe
-
-extern int input_recording;
-extern void inprec_close (void);
-extern int inprec_open (const TCHAR*, int);
-extern void inprec_rend (void);
-extern void inprec_rstart (uae_u8);
-extern void inprec_ru8 (uae_u8);
-extern void inprec_ru16 (uae_u16);
-extern void inprec_ru32 (uae_u32);
-extern void inprec_rstr (const TCHAR*);
-extern int inprec_pstart (uae_u8);
-extern void inprec_pend (void);
-extern uae_u8 inprec_pu8 (void);
-extern uae_u16 inprec_pu16 (void);
-extern uae_u32 inprec_pu32 (void);
-extern int inprec_pstr (TCHAR*);
-
 extern int inputdevice_testread (int*, int*, int*);
 extern int inputdevice_istest (void);
 extern void inputdevice_settest (int);
diff --git a/include/inputrecord.h b/include/inputrecord.h
new file mode 100644 (file)
index 0000000..0a30761
--- /dev/null
@@ -0,0 +1,56 @@
+ /*
+  * UAE - The Un*x Amiga Emulator
+  *
+  * Input recording and playback
+  *
+  * Copyright 2010 Toni Wilen
+  */
+
+extern int inputrecord_debug;
+
+//#define INPREC_JOYPORT 1
+//#define INPREC_JOYBUTTON 2
+//#define INPREC_KEY 3
+#define INPREC_DISKINSERT 4
+#define INPREC_DISKREMOVE 5
+//#define INPREC_VSYNC 6
+//#define INPREC_CIAVSYNC 7
+#define INPREC_EVENT 8
+#define INPREC_CIADEBUG 0x61
+#define INPREC_DEBUG 0x62
+#define INPREC_DEBUG2 0x63
+#define INPREC_STOP 0x7d
+#define INPREC_END 0x7e
+#define INPREC_QUIT 0x7f
+
+#define INPREC_RECORD_START 1
+#define INPREC_RECORD_NORMAL 2
+#define INPREC_RECORD_RERECORD 3
+#define INPREC_RECORD_PLAYING 4
+#define INPREC_PLAY_NORMAL 1
+#define INPREC_PLAY_RERECORD 2
+
+extern int input_record, input_play;
+extern void inprec_close (bool);
+extern void inprec_save (const TCHAR*, const TCHAR*);
+extern int inprec_open (const TCHAR*, const TCHAR*);
+extern bool inprec_prepare_record (const TCHAR*);
+extern void inprec_playtorecord (void);
+extern void inprec_startup (void);
+
+extern bool inprec_playevent (int *nr, int *state, int *max, int *autofire);
+extern void inprec_playdiskchange (void);
+extern void inprec_recordevent (int nr, int state, int max, int autofire);
+extern void inprec_recorddiskchange (int nr, const TCHAR *fname, bool writeprotected);
+
+extern void inprec_recorddebug (uae_u32);
+extern void inprec_playdebug (uae_u32);
+extern void inprec_recorddebug_cpu (int);
+extern void inprec_playdebug_cpu (int);
+extern void inprec_recorddebug_cia (uae_u32, uae_u32, uae_u32);
+extern void inprec_playdebug_cia (uae_u32, uae_u32, uae_u32);
+
+extern int inprec_getposition (void);
+extern void inprec_setposition (int offset, int replaycounter);
+extern bool inprec_realtime (void);
+extern void inprec_getstatus (TCHAR*);
\ No newline at end of file
index 7ce9f6d910dd195c33d85a6a347056ccec148c43..e1bcbded9b1123349af1503b24c122825a4a70d4 100644 (file)
@@ -138,7 +138,8 @@ enum aks { AKS_ENTERGUI = 0x200, AKS_SCREENSHOT_FILE, AKS_SCREENSHOT_CLIPBOARD,
        AKS_TOGGLEDEFAULTSCREEN,
     AKS_TOGGLEWINDOWEDFULLSCREEN, AKS_TOGGLEFULLWINDOWFULLSCREEN, AKS_TOGGLEWINDOWFULLWINDOW,
        AKS_ENTERDEBUGGER, AKS_IRQ7,
-    AKS_PAUSE, AKS_WARP, AKS_INHIBITSCREEN, AKS_STATEREWIND,
+    AKS_PAUSE, AKS_WARP, AKS_INHIBITSCREEN,
+       AKS_STATEREWIND, AKS_STATECURRENT, AKS_STATECAPTURE, 
     AKS_VOLDOWN, AKS_VOLUP, AKS_VOLMUTE,
     AKS_MVOLDOWN, AKS_MVOLUP, AKS_MVOLMUTE,
     AKS_QUIT, AKS_HARDRESET, AKS_SOFTRESET,
index df31789a38a8b58d1555e80828816ae4602d6ab6..1336063c9da0f3bb418771b825508140697f1bff 100644 (file)
@@ -84,7 +84,7 @@ typedef double fptype;
 #endif
 #endif
 
-#define CPU_PIPELINE_MAX 2
+#define CPU_PIPELINE_MAX 3
 #define CPU000_MEM_CYCLE 4
 #define CPU000_CLOCK_MULT 2
 #define CPU020_MEM_CYCLE 3
@@ -123,6 +123,7 @@ struct regstruct
        uae_u32 pc;
        uae_u8 *pc_p;
        uae_u8 *pc_oldp;
+       uae_u32 instruction_pc;
 
        uae_u16 irc, ir;
        uae_u32 spcflags;
@@ -135,6 +136,7 @@ struct regstruct
        flagtype m;
        flagtype x;
        flagtype stopped;
+       int exception;
        int intmask;
        int ipl, ipl_pin;
 
@@ -157,7 +159,6 @@ struct regstruct
        uae_u16 wb3_status;
        int mmu_enabled;
        int mmu_pagesize_8k;
-       uae_u32 fault_pc;
 #endif
 
        uae_u32 pcr;
@@ -166,13 +167,35 @@ struct regstruct
        uae_u8 panic;
        uae_u32 panic_pc, panic_addr;
 
-       uae_u32 prefetch020data[CPU_PIPELINE_MAX];
-       uae_u32 prefetch020addr[CPU_PIPELINE_MAX];
+       uae_u16 prefetch020[CPU_PIPELINE_MAX];
+       uae_u32 prefetch020addr;
+       uae_u32 cacheholdingdata020;
+       uae_u32 cacheholdingaddr020;
        int ce020memcycles;
 };
 
 extern struct regstruct regs;
 
+#define MAX_CPUTRACESIZE 128
+struct cputracememory
+{
+       uae_u32 addr;
+       uae_u32 data;
+       int mode;
+};
+
+struct cputracestruct
+{
+       uae_u32 regs[16];
+       uae_u32 usp, isp, pc;
+       uae_u16 ir, irc, sr, opcode;
+       int intmask, stopped, state;
+       int memoryoffset;
+       int cyclecounter, cyclecounter_pre, cyclecounter_post;
+       int readcounter, writecounter;
+       struct cputracememory ctm[MAX_CPUTRACESIZE];
+};
+
 STATIC_INLINE uae_u32 munge24 (uae_u32 x)
 {
        return x & regs.address_space_mask;
@@ -198,7 +221,7 @@ STATIC_INLINE void unset_special (uae_u32 x)
 STATIC_INLINE void m68k_setpc (uaecptr newpc)
 {
        regs.pc_p = regs.pc_oldp = get_real_address (newpc);
-       regs.fault_pc = regs.pc = newpc;
+       regs.instruction_pc = regs.pc = newpc;
 }
 
 STATIC_INLINE uaecptr m68k_getpc (void)
@@ -219,12 +242,12 @@ STATIC_INLINE void m68k_incpc (int o)
 
 STATIC_INLINE void m68k_setpc_mmu (uaecptr newpc)
 {
-       regs.fault_pc = regs.pc = newpc;
+       regs.instruction_pc = regs.pc = newpc;
        regs.pc_p = regs.pc_oldp = 0;
 }
 STATIC_INLINE void m68k_setpci (uaecptr newpc)
 {
-       regs.fault_pc = regs.pc = newpc;
+       regs.instruction_pc = regs.pc = newpc;
 }
 STATIC_INLINE uaecptr m68k_getpci (void)
 {
@@ -241,11 +264,6 @@ STATIC_INLINE void m68k_do_rts (void)
        m68k_setpc (newpc);
        m68k_areg (regs, 7) += 4;
 }
-STATIC_INLINE void m68k_do_rtsi (void)
-{
-       m68k_setpci (get_long (m68k_areg (regs, 7)));
-       m68k_areg (regs, 7) += 4;
-}
 
 STATIC_INLINE void m68k_do_bsr (uaecptr oldpc, uae_s32 offset)
 {
@@ -253,12 +271,6 @@ STATIC_INLINE void m68k_do_bsr (uaecptr oldpc, uae_s32 offset)
        put_long (m68k_areg (regs, 7), oldpc);
        m68k_incpc (offset);
 }
-STATIC_INLINE void m68k_do_bsri (uaecptr oldpc, uae_s32 offset)
-{
-       m68k_areg (regs, 7) -= 4;
-       put_long (m68k_areg (regs, 7), oldpc);
-       m68k_incpci (offset);
-}
 
 STATIC_INLINE uae_u32 get_ibyte (int o)
 {
@@ -309,6 +321,8 @@ STATIC_INLINE uae_u32 next_ilongi (void)
        return r;
 }
 
+extern uae_u32 (*x_prefetch)(int);
+extern uae_u32 (*x_prefetch_long)(int);
 extern uae_u32 (*x_get_byte)(uaecptr addr);
 extern uae_u32 (*x_get_word)(uaecptr addr);
 extern uae_u32 (*x_get_long)(uaecptr addr);
@@ -317,6 +331,12 @@ extern void (*x_put_word)(uaecptr addr, uae_u32 v);
 extern void (*x_put_long)(uaecptr addr, uae_u32 v);
 extern uae_u32 (*x_next_iword)(void);
 extern uae_u32 (*x_next_ilong)(void);
+extern uae_u32 (*x_get_ilong)(int);
+extern uae_u32 (*x_get_iword)(int);
+extern uae_u32 (*x_get_ibyte)(int);
+extern void (*x_do_cycles)(unsigned long);
+extern void (*x_do_cycles_pre)(unsigned long);
+extern void (*x_do_cycles_post)(unsigned long, uae_u32);
 
 extern uae_u32 REGPARAM3 x_get_disp_ea_020 (uae_u32 base, uae_u32 dp) REGPARAM;
 extern uae_u32 REGPARAM3 x_get_bitfield (uae_u32 src, uae_u32 bdata[2], uae_s32 offset, int width) REGPARAM;
@@ -326,7 +346,6 @@ extern void m68k_setstopped (void);
 extern void m68k_resumestopped (void);
 
 extern uae_u32 REGPARAM3 get_disp_ea_020 (uae_u32 base, uae_u32 dp) REGPARAM;
-extern uae_u32 REGPARAM3 get_disp_ea_000 (uae_u32 base, uae_u32 dp) REGPARAM;
 extern uae_u32 REGPARAM3 get_bitfield (uae_u32 src, uae_u32 bdata[2], uae_s32 offset, int width) REGPARAM;
 extern void REGPARAM3 put_bitfield (uae_u32 dst, uae_u32 bdata[2], uae_u32 val, uae_s32 offset, int width) REGPARAM;
 
@@ -337,7 +356,7 @@ extern int get_cpu_model (void);
 
 extern void REGPARAM3 MakeSR (void) REGPARAM;
 extern void REGPARAM3 MakeFromSR (void) REGPARAM;
-extern void REGPARAM3 Exception (int, uaecptr) REGPARAM;
+extern void REGPARAM3 Exception (int) REGPARAM;
 extern void NMI (void);
 extern void NMI_delayed (void);
 extern void prepare_interrupt (uae_u32);
@@ -345,7 +364,7 @@ extern void doint (void);
 extern void dump_counts (void);
 extern int m68k_move2c (int, uae_u32 *);
 extern int m68k_movec2 (int, uae_u32 *);
-extern void m68k_divl (uae_u32, uae_u32, uae_u16, uaecptr);
+extern void m68k_divl (uae_u32, uae_u32, uae_u16);
 extern void m68k_mull (uae_u32, uae_u32, uae_u16);
 extern void init_m68k (void);
 extern void init_m68k_full (void);
@@ -373,12 +392,12 @@ extern void fpu_reset (void);
 extern void fpux_save (int*);
 extern void fpux_restore (int*);
 
-extern void exception3 (uae_u32 opcode, uaecptr addr, uaecptr fault);
-extern void exception3i (uae_u32 opcode, uaecptr addr, uaecptr fault);
-extern void exception2 (uaecptr addr, uaecptr fault);
+extern void exception3 (uae_u32 opcode, uaecptr addr);
+extern void exception3i (uae_u32 opcode, uaecptr addr);
+extern void exception2 (uaecptr addr);
 extern void cpureset (void);
 
-extern void fill_prefetch_slow (void);
+extern void fill_prefetch (void);
 
 #define CPU_OP_NAME(a) op ## a
 
@@ -424,3 +443,7 @@ struct cpum2c {
        TCHAR *regname;
 };
 extern struct cpum2c m2cregs[];
+
+extern bool is_cpu_tracer (void);
+extern bool set_cpu_tracer (bool force);
+extern bool can_cpu_tracer (void);
\ No newline at end of file
index d2a4e1c90b49861a9609a229684550cd38788013..3b53deaeba86442e9819e278999de85a8cd19823 100644 (file)
@@ -9,7 +9,7 @@
 
 #define UAEMAJOR 2
 #define UAEMINOR 3
-#define UAESUBREV 0
+#define UAESUBREV 1
 
 typedef enum { KBD_LANG_US, KBD_LANG_DK, KBD_LANG_DE, KBD_LANG_SE, KBD_LANG_FR, KBD_LANG_IT, KBD_LANG_ES } KbdLang;
 
@@ -45,6 +45,7 @@ struct uae_input_device {
 };
 
 #define MAX_JPORTS 4
+#define NORMAL_JPORTS 2
 #define MAX_JPORTNAME 128
 struct jport {
        int id;
@@ -119,11 +120,12 @@ enum { CP_GENERIC = 1, CP_CDTV, CP_CD32, CP_A500, CP_A500P, CP_A600, CP_A1000,
 #define GFX_FULLWINDOW 2
 
 #define AUTOSCALE_NONE 0
-#define AUTOSCALE_STATIC_NOMINAL 1
-#define AUTOSCALE_STATIC_MAX 2
-#define AUTOSCALE_NORMAL 3
-#define AUTOSCALE_RESIZE 4
-#define AUTOSCALE_CENTER 5
+#define AUTOSCALE_STATIC_AUTO 1
+#define AUTOSCALE_STATIC_NOMINAL 2
+#define AUTOSCALE_STATIC_MAX 3
+#define AUTOSCALE_NORMAL 4
+#define AUTOSCALE_RESIZE 5
+#define AUTOSCALE_CENTER 6
 
 struct uae_prefs {
 
@@ -194,8 +196,8 @@ struct uae_prefs {
        struct wh gfx_size_win;
        struct wh gfx_size_fs;
        struct wh gfx_size;
-       struct wh gfx_size_win_xtra[4];
-       struct wh gfx_size_fs_xtra[4];
+       struct wh gfx_size_win_xtra[6];
+       struct wh gfx_size_fs_xtra[6];
        bool gfx_autoresolution;
        bool gfx_scandoubler;
        int gfx_refreshrate;
@@ -309,7 +311,7 @@ struct uae_prefs {
        TCHAR quitstatefile[MAX_DPATH];
        TCHAR statefile[MAX_DPATH];
        TCHAR inprecfile[MAX_DPATH];
-       int inprecmode;
+       bool inprec_autoplay;
 
        TCHAR path_floppy[256];
        TCHAR path_hardfile[256];
@@ -399,7 +401,6 @@ struct uae_prefs {
        TCHAR win32_parjoyport0[MAX_DPATH];
        TCHAR win32_parjoyport1[MAX_DPATH];
 
-       bool statecapture;
        int statecapturerate, statecapturebuffersize;
 
        /* input */
index d60b67f395f6544255403d4ba3143758517349fa..5ac119c3c05e4e0e4be75832f015739eaa0efcc6 100644 (file)
 /* functions to save byte,word or long word
  * independent of CPU's endianess */
 
+extern void save_store_pos_func (uae_u8 **);
+extern void save_store_size_func (uae_u8 **);
+extern void restore_store_pos_func (uae_u8 **);
+extern void restore_store_size_func (uae_u8 **);
+
+#define save_store_pos() save_store_pos_func (&dst)
+#define save_store_size() save_store_size_func (&dst)
+#define restore_store_pos() restore_store_pos_func (&src)
+#define restore_store_size() restore_store_size_func (&src)
+
 extern void save_u64_func (uae_u8 **, uae_u64);
 extern void save_u32_func (uae_u8 **, uae_u32);
 extern void save_u16_func (uae_u8 **, uae_u16);
@@ -43,6 +53,8 @@ extern void restore_cpu_finish (void);
 extern uae_u8 *save_cpu (int *, uae_u8 *);
 extern uae_u8 *restore_cpu_extra (uae_u8 *);
 extern uae_u8 *save_cpu_extra (int *, uae_u8 *);
+extern uae_u8 *save_cpu_trace (int *, uae_u8 *);
+extern uae_u8 *restore_cpu_trace (uae_u8 *);
 
 extern uae_u8 *restore_mmu (uae_u8 *);
 extern uae_u8 *save_mmu (int *, uae_u8 *);
@@ -51,9 +63,11 @@ extern uae_u8 *restore_fpu (uae_u8 *);
 extern uae_u8 *save_fpu (int *, uae_u8 *);
 
 extern uae_u8 *restore_disk (int, uae_u8 *);
-extern uae_u8 *save_disk (int, int *, uae_u8 *);
+extern uae_u8 *save_disk (int, int *, uae_u8 *, bool);
 extern uae_u8 *restore_floppy (uae_u8 *src);
 extern uae_u8 *save_floppy (int *len, uae_u8 *);
+extern uae_u8 *save_disk2 (int num, int *len, uae_u8 *dstptr);
+extern uae_u8 *restore_disk2 (int num,uae_u8 *src);
 extern void DISK_save_custom  (uae_u32 *pdskpt, uae_u16 *pdsklen, uae_u16 *pdsksync, uae_u16 *pdskbytr);
 extern void DISK_restore_custom  (uae_u32 pdskpt, uae_u16 pdsklength, uae_u16 pdskbytr);
 extern void restore_disk_finish (void);
@@ -69,15 +83,22 @@ extern uae_u8 *save_custom_sprite (int num, int *len, uae_u8 *);
 extern uae_u8 *restore_custom_agacolors (uae_u8 *src);
 extern uae_u8 *save_custom_agacolors (int *len, uae_u8 *);
 
+extern uae_u8 *restore_custom_event_delay (uae_u8 *src);
+extern uae_u8 *save_custom_event_delay (int *len, uae_u8 *dstptr);
+
 extern uae_u8 *restore_blitter (uae_u8 *src);
 extern uae_u8 *save_blitter (int *len, uae_u8 *);
+extern uae_u8 *restore_blitter_new (uae_u8 *src);
+extern uae_u8 *save_blitter_new (int *len, uae_u8 *);
 extern void restore_blitter_finish (void);
 
 extern uae_u8 *restore_audio (int, uae_u8 *);
 extern uae_u8 *save_audio (int, int *, uae_u8 *);
+extern void restore_audio_finish (void);
 
 extern uae_u8 *restore_cia (int, uae_u8 *);
 extern uae_u8 *save_cia (int, int *, uae_u8 *);
+extern void restore_cia_finish (void);
 
 extern uae_u8 *restore_expansion (uae_u8 *);
 extern uae_u8 *save_expansion (int *, uae_u8 *);
@@ -87,18 +108,18 @@ extern uae_u8 *save_p96 (int *, uae_u8 *);
 extern void restore_p96_finish (void);
 
 extern uae_u8 *restore_keyboard (uae_u8 *);
-extern uae_u8 *save_keyboard (int *);
+extern uae_u8 *save_keyboard (int *,uae_u8*);
 
 extern uae_u8 *restore_akiko (uae_u8 *src);
-extern uae_u8 *save_akiko (int *len);
+extern uae_u8 *save_akiko (int *len, uae_u8*);
 extern void restore_akiko_finish (void);
 
 extern uae_u8 *restore_cdtv (uae_u8 *src);
-extern uae_u8 *save_cdtv (int *len);
+extern uae_u8 *save_cdtv (int *len, uae_u8*);
 extern void restore_cdtv_finish (void);
 
 extern uae_u8 *restore_dmac (uae_u8 *src);
-extern uae_u8 *save_dmac (int *len);
+extern uae_u8 *save_dmac (int *len, uae_u8*);
 
 extern uae_u8 *restore_filesys (uae_u8 *src);
 extern uae_u8 *save_filesys (int num, int *len);
@@ -107,9 +128,9 @@ extern uae_u8 *save_filesys_common (int *len);
 extern int save_filesys_cando(void);
 
 extern uae_u8 *restore_gayle(uae_u8 *src);
-extern uae_u8 *save_gayle (int *len);
+extern uae_u8 *save_gayle (int *len, uae_u8*);
 extern uae_u8 *restore_ide (uae_u8 *src);
-extern uae_u8 *save_ide (int num, int *len);
+extern uae_u8 *save_ide (int num, int *len, uae_u8*);
 
 extern uae_u8 *save_cd (int num, int *len);
 extern uae_u8 *restore_cd (int, uae_u8 *src);
@@ -122,6 +143,20 @@ extern uae_u8 *restore_log (uae_u8 *src);
 extern uae_u8 *restore_input (uae_u8 *src);
 extern uae_u8 *save_input (int *len, uae_u8 *dstptr);
 
+extern uae_u8 *restore_inputstate (uae_u8 *src);
+extern uae_u8 *save_inputstate (int *len, uae_u8 *dstptr);
+extern void clear_inputstate (void);
+
+extern uae_u8 *save_a2065 (int *len, uae_u8 *dstptr);
+extern uae_u8 *restore_a2065 (uae_u8 *src);
+extern void restore_a2065_finish (void);
+
+extern uae_u8 *restore_debug_memwatch (uae_u8 *src);
+extern uae_u8 *save_debug_memwatch (int *len, uae_u8 *dstptr);
+
+extern uae_u8 *save_cycles (int *len, uae_u8 *dstptr);
+extern uae_u8 *restore_cycles (uae_u8 *src);
+
 extern void restore_cram (int, size_t);
 extern void restore_bram (int, size_t);
 extern void restore_fram (int, size_t);
@@ -150,14 +185,18 @@ extern uae_u8 *save_action_replay (int *, uae_u8 *);
 extern uae_u8 *restore_hrtmon (uae_u8 *);
 extern uae_u8 *save_hrtmon (int *, uae_u8 *);
 
-extern void savestate_initsave (const TCHAR *filename, int docompress, int nodialogs);
+extern void savestate_initsave (const TCHAR *filename, int docompress, int nodialogs, bool save);
 extern int save_state (const TCHAR *filename, const TCHAR *description);
 extern void restore_state (const TCHAR *filename);
 extern void savestate_restore_finish (void);
+extern void savestate_memorysave (void);
+
 
 extern void custom_save_state (void);
 extern void custom_prepare_savestate (void);
 
+extern bool savestate_check (void);
+
 #define STATE_SAVE 1
 #define STATE_RESTORE 2
 #define STATE_DOSAVE 4
@@ -169,6 +208,11 @@ extern int savestate_state;
 extern TCHAR savestate_fname[MAX_DPATH];
 extern struct zfile *savestate_file;
 
+STATIC_INLINE bool isrestore (void)
+{
+       return savestate_state == STATE_RESTORE || savestate_state == STATE_REWIND;
+}
+
 extern void savestate_quick (int slot, int save);
 
 extern void savestate_capture (int);
@@ -177,4 +221,4 @@ extern void savestate_init (void);
 extern void savestate_rewind (void);
 extern int savestate_dorewind (int);
 extern void savestate_listrewind (void);
-
+extern void statefile_save_recording (const TCHAR*);
index 115621499aefbd6c31bc328a5cbae5dc72719f4f..727ea63deb31bdb9addbfe2ab026c655797508db 100644 (file)
@@ -24,4 +24,3 @@ static int td_pos = (TD_RIGHT|TD_BOTTOM);
 #define STATUSLINE_TARGET 0x80
 
 extern void draw_status_line_single (uae_u8 *buf, int bpp, int y, int totalwidth, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc, uae_u32 *alpha);
-
index 13d4b5bcd87f4429a7331d0b29168edfa1ac35dc..92c530393b657ef3f4f5c0fe3b177fba5bc1ef65 100644 (file)
@@ -29,6 +29,8 @@ extern bool get_plugin_path (TCHAR *out, int size, const TCHAR *path);
 extern void stripslashes (TCHAR *p);
 extern void fixtrailing (TCHAR *p);
 extern void fullpath (TCHAR *path, int size);
+extern void getpathpart (TCHAR *outpath, int size, const TCHAR *inpath);
+extern void getfilepart (TCHAR *out, int size, const TCHAR *path);
 
 extern int quit_program;
 extern bool console_emulation;
@@ -58,5 +60,9 @@ extern void fetch_configurationpath (TCHAR *out, int size);
 extern void fetch_screenshotpath (TCHAR *out, int size);
 extern void fetch_ripperpath (TCHAR *out, int size);
 extern void fetch_statefilepath (TCHAR *out, int size);
+extern void fetch_inputfilepath (TCHAR *out, int size);
 extern void fetch_datapath (TCHAR *out, int size);
-extern int uaerand (void);
+extern uae_u32 uaerand (void);
+extern uae_u32 uaesrand (uae_u32 seed);
+extern uae_u32 uaerandgetseed (void);
+
index da09c97c3044186c2358962a0da2f9fefd8e818a..3187984b8493f67b54e3b5ac0ce6bf9946367f72 100644 (file)
@@ -93,6 +93,8 @@ struct vidbuf_description
     int maxblocklines; /* Set to 0 if you want calls to flush_line after each drawn line, or the number of
                        * lines that flush_block wants to/can handle (it isn't really useful to use another
                        * value than maxline here). */
+       int gfx_resolution_reserved; // reserved space for currprefs.gfx_resolution
+       int gfx_vresolution_reserved; // reserved space for currprefs.gfx_resolution
 };
 
 extern struct vidbuf_description gfxvidinfo;
index 45ec42d7a0e44682644ad68bfdad6fcec731725b..b9b863bba9d039dfa0be34cc31be613fd97ebc24 100644 (file)
@@ -14,6 +14,7 @@ struct zfile {
        int archiveid;
     uae_s64 size; // real size
        uae_s64 datasize; // available size (not yet unpacked completely?)
+       uae_s64 allocsize; // memory allocated before realloc() needed again
     uae_s64 seek; // seek position
     int deleteafterclose;
     int textmode;
index fb7be8b2958acce4cfcd31efdc8bcf3c7f5abdd5..5a9cd702fc98b6b842f53375c63c7b86bea4267f 100644 (file)
@@ -30,7 +30,8 @@ struct fs_filehandle
 typedef int (*zfile_callback)(struct zfile*, void*);
 
 extern struct zfile *zfile_fopen (const TCHAR *, const TCHAR *, int mask);
-extern struct zfile *zfile_fopen2 (const TCHAR *, const TCHAR *, int mask, int index);
+extern struct zfile *zfile_fopen (const TCHAR *, const TCHAR *);
+extern struct zfile *zfile_fopen (const TCHAR *, const TCHAR *, int mask, int index);
 extern struct zfile *zfile_fopen_empty (struct zfile*, const TCHAR *name, uae_u64 size);
 extern struct zfile *zfile_fopen_empty (struct zfile*, const TCHAR *name);
 extern struct zfile *zfile_fopen_data (const TCHAR *name, uae_u64 size, uae_u8 *data);
@@ -68,6 +69,7 @@ extern int zfile_convertimage (const TCHAR *src, const TCHAR *dst);
 extern struct zfile *zuncompress (struct znode*, struct zfile *z, int dodefault, int mask, int *retcode, int index);
 extern void zfile_seterror (const TCHAR *format, ...);
 extern TCHAR *zfile_geterror (void);
+extern int zfile_truncate (struct zfile *z, uae_s64 size);
 
 #define ZFD_NONE 0
 #define ZFD_ARCHIVE 1 //zip/lha..
index 7f8b43251829e8ad8ad1213f242118f2e21fc2b1..fb7bdf92afc796d50a9e179cc59e885daae93c3d 100644 (file)
@@ -24,6 +24,7 @@
 #include "options.h"
 #include "keyboard.h"
 #include "inputdevice.h"
+#include "inputrecord.h"
 #include "keybuf.h"
 #include "custom.h"
 #include "xwin.h"
@@ -104,7 +105,9 @@ static uae_u8 scancodeused[MAX_INPUT_DEVICES][256];
 
 // fire/left mouse button pullup resistors enabled?
 static bool mouse_pullup = true;
-static bool joystick_pullup = false;
+
+static int joymodes[MAX_JPORTS];
+static int *joyinputs[MAX_JPORTS];
 
 static int input_acquired;
 static int testmode, testmode_read, testmode_toggle;
@@ -121,255 +124,12 @@ static int testmode_count;
 static struct teststore testmode_data[TESTMODE_MAX];
 static struct teststore testmode_wait[TESTMODE_MAX];
 
-static uae_u8 *inprec_buffer, *inprec_p;
-static struct zfile *inprec_zf;
-static int inprec_size;
-int input_recording = 0;
-static uae_u8 *inprec_plast, *inprec_plastptr;
-static int inprec_div;
-
-static uae_u32 oldbuttons[4];
-static uae_u16 oldjoy[2];
-
 static int bouncy;
 static signed long bouncy_cycles;
 #define BOUNCY_CYCLES 30
 
-int inprec_open (const TCHAR *fname, int record)
-{
-       uae_u32 t = (uae_u32)time(0);
-       int i;
-
-       inprec_close();
-       inprec_zf = zfile_fopen (fname, record > 0 ? L"wb" : L"rb", ZFD_NORMAL);
-       if (inprec_zf == NULL)
-               return 0;
-       inprec_size = 10000;
-       inprec_div = 1;
-       if (record < 0) {
-               uae_u32 id;
-               zfile_fseek (inprec_zf, 0, SEEK_END);
-               inprec_size = zfile_ftell (inprec_zf);
-               zfile_fseek (inprec_zf, 0, SEEK_SET);
-               inprec_buffer = inprec_p = xmalloc (uae_u8, inprec_size);
-               zfile_fread (inprec_buffer, inprec_size, 1, inprec_zf);
-               inprec_plastptr = inprec_buffer;
-               id = inprec_pu32();
-               if (id != 'UAE\0') {
-                       inprec_close ();
-                       return 0;
-               }
-               inprec_pu32();
-               t = inprec_pu32 ();
-               i = inprec_pu32 ();
-               while (i-- > 0)
-                       inprec_pu8 ();
-               inprec_p = inprec_plastptr;
-               if (inprec_pstart (INPREC_STATEFILE)) {
-                       inprec_pstr (savestate_fname);
-                       savestate_state = STATE_RESTORE;
-                       inprec_pend ();
-               }
-               oldbuttons[0] = oldbuttons[1] = oldbuttons[2] = oldbuttons[3] = 0;
-               oldjoy[0] = oldjoy[1] = 0;
-               if (record < -1)
-                       inprec_div = maxvpos;
-       } else if (record > 0) {
-               inprec_buffer = inprec_p = xmalloc (uae_u8, inprec_size);
-               inprec_ru32 ('UAE\0');
-               inprec_ru8 (1);
-               inprec_ru8 (UAEMAJOR);
-               inprec_ru8 (UAEMINOR);
-               inprec_ru8 (UAESUBREV);
-               inprec_ru32 (t);
-               inprec_ru32 (0); // extra header size
-               if (savestate_state == STATE_DORESTORE) {
-                       inprec_rstart (INPREC_STATEFILE);
-                       inprec_rstr (savestate_fname);
-                       inprec_rend ();
-               }
-       } else {
-               return 0;
-       }
-       input_recording = record;
-       srand (t);
-       CIA_inprec_prepare ();
-       write_log (L"inprec initialized '%s', mode=%d\n", fname, input_recording);
-       return 1;
-}
-
-void inprec_close (void)
-{
-       if (!inprec_zf)
-               return;
-       if (inprec_buffer && input_recording > 0) {
-               hsync_counter++;
-               inprec_rstart(INPREC_END);
-               inprec_rend();
-               hsync_counter--;
-               zfile_fwrite (inprec_buffer, inprec_p - inprec_buffer, 1, inprec_zf);
-               inprec_p = inprec_buffer;
-       }
-       zfile_fclose (inprec_zf);
-       inprec_zf = NULL;
-       xfree (inprec_buffer);
-       inprec_buffer = NULL;
-       input_recording = 0;
-       write_log (L"inprec finished\n");
-}
-
-void inprec_ru8(uae_u8 v)
-{
-       *inprec_p++= v;
-}
-void inprec_ru16 (uae_u16 v)
-{
-       inprec_ru8 ((uae_u8)(v >> 8));
-       inprec_ru8 ((uae_u8)v);
-}
-void inprec_ru32 (uae_u32 v)
-{
-       inprec_ru16 ((uae_u16)(v >> 16));
-       inprec_ru16 ((uae_u16)v);
-}
-void inprec_rstr (const TCHAR *src)
-{
-       char *s = ua (src);
-       char *ss = s;
-       while(*s) {
-               inprec_ru8 (*s);
-               s++;
-       }
-       inprec_ru8 (0);
-       xfree (ss);
-}
-void inprec_rstart (uae_u8 type)
-{
-       write_log (L"INPREC: %08X: %d\n", hsync_counter, type);
-       inprec_ru32 (hsync_counter);
-       inprec_ru8 (0);
-       inprec_plast = inprec_p;
-       inprec_ru8 (0xff);
-       inprec_ru8 (type);
-}
-void inprec_rend (void)
-{
-       *inprec_plast = inprec_p - (inprec_plast + 2);
-       if (inprec_p >= inprec_buffer + inprec_size - 256) {
-               zfile_fwrite (inprec_buffer, inprec_p - inprec_buffer, 1, inprec_zf);
-               inprec_p = inprec_buffer;
-       }
-}
-
-int inprec_pstart (uae_u8 type)
-{
-       uae_u8 *p = inprec_p;
-       uae_u32 hc = hsync_counter;
-       static uae_u8 *lastp;
-       uae_u32 hc_orig, hc2_orig;
-
-       if (savestate_state)
-               return 0;
-       if (p[5 + 1] == INPREC_END) {
-               inprec_close ();
-               return 0;
-       } else if (p[5 + 1] == INPREC_QUIT) {
-               inprec_close ();
-               uae_quit ();
-               return 0;
-       }
-       hc_orig = hc;
-       hc /= inprec_div;
-       hc *= inprec_div;
-       for (;;) {
-               uae_u32 hc2 = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
-               if (p > lastp) {
-                       write_log (L"INPREC: Next %08x (%08x=%d): %d (%d)\n", hc2, hc, hc2 - hc, p[5 + 1], p[5]);
-                       lastp = p;
-               }
-               hc2_orig = hc2;
-               hc2 /= inprec_div;
-               hc2 *= inprec_div;
-               if (hc > hc2) {
-                       write_log (L"INPREC: %08x > %08x: %d (%d) missed!\n", hc, hc2, p[5 + 1], p[5]);
-                       inprec_close ();
-                       return 0;
-               }
-               if (hc2 != hc) {
-                       lastp = p;
-                       break;
-               }
-               if (p[5 + 1] == type) {
-                       write_log (L"INPREC: %08x: %d (%d) (%+d)\n", hc, type, p[5], hc_orig - hc2_orig);
-                       inprec_plast = p;
-                       inprec_plastptr = p + 5 + 2;
-                       return 1;
-               }
-               p += 5 + 2 + p[5];
-       }
-       inprec_plast = NULL;
-       return 0;
-}
-void inprec_pend (void)
-{
-       uae_u8 *p = inprec_p;
-       uae_u32 hc = hsync_counter;
-
-       if (!inprec_plast)
-               return;
-       inprec_plast[5 + 1] = 0;
-       inprec_plast = NULL;
-       inprec_plastptr = NULL;
-       hc /= inprec_div;
-       hc *= inprec_div;
-       for (;;) {
-               uae_u32 hc2 = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
-               hc2 /= inprec_div;
-               hc2 *= inprec_div;
-               if (hc2 != hc)
-                       break;
-               if (p[5 + 1] != 0)
-                       return;
-               p += 5 + 2 + p[5];
-       }
-       inprec_p = p;
-       if (p[5 + 1] == INPREC_END)
-               inprec_close ();
-}
-
-uae_u8 inprec_pu8 (void)
-{
-       return *inprec_plastptr++;
-}
-uae_u16 inprec_pu16 (void)
-{
-       uae_u16 v = inprec_pu8 () << 8;
-       v |= inprec_pu8 ();
-       return v;
-}
-uae_u32 inprec_pu32 (void)
-{
-       uae_u32 v = inprec_pu16 () << 16;
-       v |= inprec_pu16 ();
-       return v;
-}
-int inprec_pstr (TCHAR *dst)
-{
-       char tmp[MAX_DPATH];
-       char *s;
-       int len = 0;
+static int handle_input_event (int nr, int state, int max, int autofire, bool canstoprecord, bool playbackevent);
 
-       s = tmp;
-       for(;;) {
-               uae_u8 v = inprec_pu8 ();
-               *s++ = v;
-               if (!v)
-                       break;
-               len++;
-       }
-       au_copy (dst, MAX_DPATH, tmp);
-       return len;
-}
 
 static int isdevice (struct uae_input_device *id)
 {
@@ -389,7 +149,7 @@ int inputdevice_uaelib (TCHAR *s, TCHAR *parm)
 
        for (i = 1; events[i].name; i++) {
                if (!_tcscmp (s, events[i].confname)) {
-                       handle_input_event (i, _tstol (parm), 1, 0);
+                       handle_input_event (i, _tstol (parm), 1, 0, false, false);
                        return 1;
                }
        }
@@ -400,43 +160,53 @@ static struct uae_input_device *joysticks;
 static struct uae_input_device *mice;
 static struct uae_input_device *keyboards;
 static struct uae_input_device_kbr_default *keyboard_default;
+
+#define KBR_DEFAULT_MAP_FIRST 0
+#define KBR_DEFAULT_MAP_LAST 5
+#define KBR_DEFAULT_MAP_CD32_FIRST 6
+#define KBR_DEFAULT_MAP_CD32_LAST 8
+
 #define KBR_DEFAULT_MAP_NP 0
 #define KBR_DEFAULT_MAP_CK 1
 #define KBR_DEFAULT_MAP_SE 2
-#define KBR_DEFAULT_MAP_CD32_NP 3
-#define KBR_DEFAULT_MAP_CD32_CK 4
-#define KBR_DEFAULT_MAP_CD32_SE 5
-#define KBR_DEFAULT_MAP_XA1 6
-#define KBR_DEFAULT_MAP_XA2 7
-#define KBR_DEFAULT_MAP_ARCADIA 8
-#define KBR_DEFAULT_MAP_ARCADIA_XA 9
-#define KBR_DEFAULT_MAP_CDTV 10
+#define KBR_DEFAULT_MAP_NP3 3
+#define KBR_DEFAULT_MAP_CK3 4
+#define KBR_DEFAULT_MAP_SE3 5
+#define KBR_DEFAULT_MAP_CD32_NP 6
+#define KBR_DEFAULT_MAP_CD32_CK 7
+#define KBR_DEFAULT_MAP_CD32_SE 8
+#define KBR_DEFAULT_MAP_XA1 9
+#define KBR_DEFAULT_MAP_XA2 10
+#define KBR_DEFAULT_MAP_ARCADIA 11
+#define KBR_DEFAULT_MAP_ARCADIA_XA 12
+#define KBR_DEFAULT_MAP_CDTV 13
 static int **keyboard_default_kbmaps;
 
 static int mouse_axis[MAX_INPUT_DEVICES][MAX_INPUT_DEVICE_EVENTS];
 static int oldm_axis[MAX_INPUT_DEVICES][MAX_INPUT_DEVICE_EVENTS];
 
-static int mouse_x[MAX_INPUT_DEVICES], mouse_y[MAX_INPUT_DEVICE_EVENTS];
-static int mouse_delta[MAX_INPUT_DEVICES][MAX_INPUT_DEVICE_EVENTS];
-static int mouse_deltanoreset[MAX_INPUT_DEVICES][MAX_INPUT_DEVICE_EVENTS];
-static int joybutton[MAX_INPUT_DEVICES];
-static unsigned int joydir[MAX_INPUT_DEVICE_EVENTS];
-static int joydirpot[MAX_INPUT_DEVICE_EVENTS][2];
-static int mouse_frame_x[2], mouse_frame_y[2];
-
-static int mouse_port[2];
-static int cd32_shifter[2];
-static int cd32_pad_enabled[2];
+static int mouse_x[MAX_JPORTS], mouse_y[MAX_JPORTS];
+static int mouse_delta[MAX_JPORTS][MAX_INPUT_DEVICE_EVENTS];
+static int mouse_deltanoreset[MAX_JPORTS][MAX_INPUT_DEVICE_EVENTS];
+static int joybutton[MAX_JPORTS];
+static int joydir[MAX_JPORTS];
+static int joydirpot[MAX_JPORTS][2];
+static int mouse_frame_x[MAX_JPORTS], mouse_frame_y[MAX_JPORTS];
+
+static int mouse_port[NORMAL_JPORTS];
+static int cd32_shifter[NORMAL_JPORTS];
+static int cd32_pad_enabled[NORMAL_JPORTS];
 static int parport_joystick_enabled;
-static int oldmx[4], oldmy[4];
-static int oleft[4], oright[4], otop[4], obot[4];
+static int oldmx[MAX_JPORTS], oldmy[MAX_JPORTS];
+static int oleft[MAX_JPORTS], oright[MAX_JPORTS], otop[MAX_JPORTS], obot[MAX_JPORTS];
+static int horizclear[MAX_JPORTS], vertclear[MAX_JPORTS];
 
 uae_u16 potgo_value;
-static int pot_cap[2][2];
-static uae_u8 pot_dat[2][2];
-static int pot_dat_act[2][2];
-static int analog_port[2][2];
-static int digital_port[2][2];
+static int pot_cap[NORMAL_JPORTS][2];
+static uae_u8 pot_dat[NORMAL_JPORTS][2];
+static int pot_dat_act[NORMAL_JPORTS][2];
+static int analog_port[NORMAL_JPORTS][2];
+static int digital_port[NORMAL_JPORTS][2];
 #define POTDAT_DELAY_PAL 8
 #define POTDAT_DELAY_NTSC 7
 
@@ -1789,33 +1559,9 @@ STATIC_INLINE int adjust (int val)
        return val;
 }
 
-int getbuttonstate (int joy, int button)
+static int getbuttonstate (int joy, int button)
 {
-       int v;
-
-       v = (joybutton[joy] & (1 << button)) ? 1 : 0;
-       if (input_recording > 0 && ((joybutton[joy] ^ oldbuttons[joy]) & (1 << button))) {
-               oldbuttons[joy] &= ~(1 << button);
-               if (v)
-                       oldbuttons[joy] |= 1 << button;
-               inprec_rstart (INPREC_JOYBUTTON);
-               inprec_ru8 (joy);
-               inprec_ru8 (button);
-               inprec_ru8 (v);
-               inprec_rend ();
-       } else if (input_recording < 0) {
-               while (inprec_pstart (INPREC_JOYBUTTON)) {
-                       uae_u8 j = inprec_pu8 ();
-                       uae_u8 but = inprec_pu8 ();
-                       uae_u8 vv = inprec_pu8 ();
-                       inprec_pend ();
-                       oldbuttons[j] &= ~(1 << but);
-                       if (vv)
-                               oldbuttons[j] |= 1 << but;
-               }
-               v = (oldbuttons[joy] & (1 << button)) ? 1 : 0;
-       }
-       return v;
+       return (joybutton[joy] & (1 << button)) ? 1 : 0;
 }
 
 static int getvelocity (int num, int subnum, int pct)
@@ -1934,27 +1680,24 @@ static void readinput (void)
        uae_u32 totalvpos;
        int diff;
 
-       totalvpos = input_frame * maxvpos + vpos;
+       totalvpos = input_frame * current_maxvpos () + vpos;
        diff = totalvpos - input_vpos;
        if (diff > 0) {
                if (diff < 10) {
                        mouseupdate (0, 0);
                } else {
-                       mouseupdate (diff * 1000 / maxvpos, 0);
+                       mouseupdate (diff * 1000 / current_maxvpos (), 0);
                }
        }
        input_vpos = totalvpos;
 
 }
 
-int getjoystate (int joy)
+static uae_u16 getjoystate (int joy)
 {
        int left = 1, right = 1, top = 1, bot = 1;
        uae_u16 v;
 
-       if (inputdevice_logging & 2)
-               write_log (L"JOY%dDAT %08x\n", joy, M68K_GETPC);
-       readinput ();
        if (joydir[joy] & DIR_LEFT)
                left = 0;
        if (joydir[joy] & DIR_RIGHT)
@@ -1979,25 +1722,15 @@ int getjoystate (int joy)
        if (notinrom ())
                write_log (L"JOY%dDAT %04X %s\n", joy, v, debuginfo (0));
 #endif
-       if (input_recording > 0 && oldjoy[joy] != v) {
-               oldjoy[joy] = v;
-               inprec_rstart (INPREC_JOYPORT);
-               inprec_ru16 (v);
-               inprec_rend ();
-       } else if (input_recording < 0) {
-               v = oldjoy[joy];
-               if (inprec_pstart (INPREC_JOYPORT)) {
-                       v = inprec_pu16 ();
-                       inprec_pend ();
-               }
-               oldjoy[joy] = v;
-       }
+       if (inputdevice_logging & 2)
+               write_log (L"JOY%dDAT=%04x %08x\n", joy, v, M68K_GETPC);
        return v;
 }
 
 uae_u16 JOY0DAT (void)
 {
        uae_u16 v;
+       readinput ();
        v = getjoystate (0);
        v = dongle_joydat (0, v);
        return v;
@@ -2006,11 +1739,36 @@ uae_u16 JOY0DAT (void)
 uae_u16 JOY1DAT (void)
 {
        uae_u16 v;
+       readinput ();
        v = getjoystate (1);
        v = dongle_joydat (1, v);
+
+       if (inputrecord_debug & 2) {
+               if (input_record > 0)
+                       inprec_recorddebug_cia (v, -1, m68k_getpc ());
+               else if (input_play > 0)
+                       inprec_playdebug_cia (v, -1, m68k_getpc ());
+       }
+
+       return v;
+}
+
+uae_u16 JOYGET (int num)
+{
+       uae_u16 v;
+       v = getjoystate (num);
+       v = dongle_joydat (num, v);
        return v;
 }
 
+void JOYSET (int num, uae_u16 dat)
+{
+       mouse_x[num] = dat & 0xff;
+       mouse_y[num] = (dat >> 8) & 0xff;
+       mouse_frame_x[num] = mouse_x[num];
+       mouse_frame_y[num] = mouse_y[num];
+}
+
 void JOYTEST (uae_u16 v)
 {
        mouse_x[0] &= 3;
@@ -2079,6 +1837,14 @@ static bool cd32padmode (uae_u16 p5dir, uae_u16 p5dat)
        return true;
 }
 
+static bool is_joystick_pullup (int joy)
+{
+       return joymodes[joy] == JSEM_MODE_GAMEPAD;
+}
+static bool is_mouse_pullup (int joy)
+{
+       return mouse_pullup;
+}
 
 static void charge_cap (int joy, int idx, int charge)
 {
@@ -2124,13 +1890,13 @@ static void cap_check (void)
                                joypot = joydirpot[joy][i];
                                if (analog_port[joy][i] && pot_cap[joy][i] < joypot)
                                        charge = 1; // slow charge via pot variable resistor
-                               if (((joystick_pullup && digital_port[joy][i]) || (mouse_pullup && mouse_port[joy] && digital_port[joy][i])))
+                               if ((is_joystick_pullup (joy) && digital_port[joy][i]) || (is_mouse_pullup (joy) && mouse_port[joy]))
                                        charge = 1; // slow charge via pull-up resistor
                        }
                        if (!(potgo_value & pdir)) { // input?
                                if (pot_dat_act[joy][i])
                                        pot_dat[joy][i]++;
-                               /* first 8 lines after potgo has been started = discharge cap */
+                               /* first 7 or 8 lines after potgo has been started = discharge cap */
                                if (pot_dat_act[joy][i] == 1) {
                                        if (pot_dat[joy][i] < (currprefs.ntscmode ? POTDAT_DELAY_NTSC : POTDAT_DELAY_PAL)) {
                                                charge = -2; /* fast discharge delay */
@@ -2172,13 +1938,13 @@ static void cap_check (void)
                
                        /* official Commodore mouse has pull-up resistors in button lines
                        * NOTE: 3rd party mice may not have pullups! */
-                       if (dong < 0 && (mouse_pullup && mouse_port[joy] && digital_port[joy][i]) && charge == 0)
+                       if (dong < 0 && (is_mouse_pullup (joy) && mouse_port[joy] && digital_port[joy][i]) && charge == 0)
                                charge = 2;
                        /* emulate pullup resistor if button mapped because there too many broken
                        * programs that read second button in input-mode (and most 2+ button pads have
                        * pullups)
                        */
-                       if (dong < 0 && (joystick_pullup && digital_port[joy][i]) && charge == 0)
+                       if (dong < 0 && (is_joystick_pullup (joy) && digital_port[joy][i]) && charge == 0)
                                charge = 2;
 
                        charge_cap (joy, i, charge);
@@ -2216,8 +1982,12 @@ uae_u8 handle_joystick_buttons (uae_u8 pra, uae_u8 dra)
                }
        }
 
-       if (inputdevice_logging & 4)
-               write_log (L"BFE001: %02X:%02X %x\n", dra, but, M68K_GETPC);
+       if (inputdevice_logging & 4) {
+               static uae_u8 old;
+               if (but != old)
+                       write_log (L"BFE001: %02X:%02X %x\n", dra, but, M68K_GETPC);
+               old = but;
+       }
        return but;
 }
 
@@ -2322,7 +2092,7 @@ void inputdevice_hsync (void)
                                        iq->state = 0;
                                else
                                        iq->state = iq->storedstate;
-                               handle_input_event (iq->event, iq->state, iq->max, 0);
+                               handle_input_event (iq->event, iq->state, iq->max, 0, false, true);
                                iq->linecnt = iq->nextlinecnt;
                        }
                }
@@ -2331,12 +2101,27 @@ void inputdevice_hsync (void)
        if (bouncy && get_cycles () > bouncy_cycles)
                bouncy = 0;
 
-       if ((++cnt & 63) == 63 ) {
-               inputdevice_read ();
-       } else if (inputdelay > 0) {
-               inputdelay--;
-               if (inputdelay == 0)
+       if (input_record && input_record != INPREC_RECORD_PLAYING) {
+               if (vpos == 0)
+                       inputdevice_read ();
+               inputdelay = 0;
+       }
+       if (input_play) {
+               inprec_playdiskchange ();
+               int nr, state, max, autofire;
+               while (inprec_playevent (&nr, &state, &max, &autofire))
+                       handle_input_event (nr, state, max, autofire, false, true);
+               if (vpos == 0)
+                       handle_msgpump ();
+       }
+       if (!input_record && !input_play) {
+               if ((++cnt & 63) == 63 ) {
                        inputdevice_read ();
+               } else if (inputdelay > 0) {
+                       inputdelay--;
+                       if (inputdelay == 0)
+                               inputdevice_read ();
+               }
        }
 }
 
@@ -2443,7 +2228,7 @@ static void queue_input_event (int event, int state, int max, int linecnt, int a
                iq->linecnt = -1;
                iq->event = 0;
                if (iq->state == 0)
-                       handle_input_event (event, 0, 1, 0);
+                       handle_input_event (event, 0, 1, 0, false, false);
        } else if (i < 0) {
                for (i = 0; i < INPUT_QUEUE_SIZE; i++) {
                        iq = &input_queue[i];
@@ -2517,15 +2302,47 @@ void inputdevice_do_keyboard (int code, int state)
        inputdevice_add_inputcode (code, state);
 }
 
+// these need cpu trace data
+static bool needcputrace (int code)
+{
+       switch (code)
+       {
+       case AKS_ENTERGUI:
+       case AKS_STATECAPTURE:
+       case AKS_STATESAVEQUICK:
+       case AKS_STATESAVEQUICK1:
+       case AKS_STATESAVEQUICK2:
+       case AKS_STATESAVEQUICK3:
+       case AKS_STATESAVEQUICK4:
+       case AKS_STATESAVEQUICK5:
+       case AKS_STATESAVEQUICK6:
+       case AKS_STATESAVEQUICK7:
+       case AKS_STATESAVEQUICK8:
+       case AKS_STATESAVEQUICK9:
+       case AKS_STATESAVEDIALOG:
+               return true;
+       }
+       return false;
+}
+
 void inputdevice_handle_inputcode (void)
 {
        static int swapperslot;
        int code = inputcode_pending;
        int state = inputcode_pending_state;
+       static int tracer_enable;
 
-       inputcode_pending = 0;
        if (code == 0)
-               return;
+               goto end;
+       if (needcputrace (code) && can_cpu_tracer () == true && is_cpu_tracer () == false) {
+               if (set_cpu_tracer (true)) {
+                       tracer_enable = 1;
+                       return; // wait for next frame
+               }
+       }
+
+       inputcode_pending = 0;
+
        if (vpos != 0)
                write_log (L"inputcode=%d but vpos = %d", code, vpos);
 
@@ -2610,7 +2427,13 @@ void inputdevice_handle_inputcode (void)
                toggle_inhibit_frame (IHF_SCROLLLOCK);
                break;
        case AKS_STATEREWIND:
-               savestate_dorewind (1);
+               savestate_dorewind (-2);
+               break;
+       case AKS_STATECURRENT:
+               savestate_dorewind (-1);
+               break;
+       case AKS_STATECAPTURE:
+               savestate_capture (1);
                break;
        case AKS_VOLDOWN:
                sound_volume (-1);
@@ -2755,6 +2578,11 @@ void inputdevice_handle_inputcode (void)
        break;
 #endif
        }
+end:
+       if (tracer_enable) {
+               set_cpu_tracer (false);
+               tracer_enable = 0;
+       }
 }
 
 int handle_custom_event (TCHAR *custom)
@@ -2785,15 +2613,32 @@ int handle_custom_event (TCHAR *custom)
        return 0;
 }
 
-int handle_input_event (int nr, int state, int max, int autofire)
+static int handle_input_event (int nr, int state, int max, int autofire, bool canstopplayback, bool playbackevent)
 {
        struct inputevent *ie;
        int joy;
+       bool isaks = false;
 
        if (nr <= 0)
                return 0;
        ie = &events[nr];
-       if (inputdevice_logging & 1)
+       if (ie->unit == 0 && ie->data >= 0x200)
+               isaks = true;
+
+       if (!isaks) {
+               if (input_record && input_record != INPREC_RECORD_PLAYING)
+                       inprec_recordevent (nr, state, max, autofire);
+               if (input_play && state && canstopplayback) {
+                       if (inprec_realtime ()) {
+                               if (input_record && input_record != INPREC_RECORD_PLAYING)
+                                       inprec_recordevent (nr, state, max, autofire);
+                       }
+               }
+               if (!playbackevent && input_play)
+                       return 0;
+       }
+
+       if ((inputdevice_logging & 1) || input_record || input_play)
                write_log (L"'%s' STATE=%d MAX=%d AF=%d\n", ie->name, state, max, autofire);
        if (autofire) {
                if (state)
@@ -2851,9 +2696,11 @@ int handle_input_event (int nr, int state, int max, int autofire)
                        }
 
                        if (ie->data == 0 && old != (joybutton[joy] & (1 << ie->data)) && currprefs.cpu_cycle_exact) {
-                               // emulate contact bounce, 1st button only, others have capacitors
-                               bouncy = 1;
-                               bouncy_cycles = get_cycles () + CYCLE_UNIT * BOUNCY_CYCLES;
+                               if (!input_record && !input_play) {
+                                       // emulate contact bounce, 1st button only, others have capacitors
+                                       bouncy = 1;
+                                       bouncy_cycles = get_cycles () + CYCLE_UNIT * BOUNCY_CYCLES;
+                               }
                        }
 
 
@@ -2984,14 +2831,34 @@ int handle_input_event (int nr, int state, int max, int autofire)
                        int left = oleft[joy], right = oright[joy], top = otop[joy], bot = obot[joy];
                        if (ie->type & 16) {
                                /* button to axis mapping */
-                               if (ie->data & DIR_LEFT)
+                               if (ie->data & DIR_LEFT) {
                                        left = oleft[joy] = state ? 1 : 0;
-                               if (ie->data & DIR_RIGHT)
+                                       if (horizclear[joy] && left) {
+                                               horizclear[joy] = 0;
+                                               right = oright[joy] = 0;
+                                       }
+                               }
+                               if (ie->data & DIR_RIGHT) {
                                        right = oright[joy] = state ? 1 : 0;
-                               if (ie->data & DIR_UP)
+                                       if (horizclear[joy] && right) {
+                                               horizclear[joy] = 0;
+                                               left = oleft[joy] = 0;
+                                       }
+                               }
+                               if (ie->data & DIR_UP) {
                                        top = otop[joy] = state ? 1 : 0;
-                               if (ie->data & DIR_DOWN)
+                                       if (vertclear[joy] && top) {
+                                               vertclear[joy] = 0;
+                                               bot = obot[joy] = 0;
+                                       }
+                               }
+                               if (ie->data & DIR_DOWN) {
                                        bot = obot[joy] = state ? 1 : 0;
+                                       if (vertclear[joy] && bot) {
+                                               vertclear[joy] = 0;
+                                               top = otop[joy] = 0;
+                                       }
+                               }
                        } else {
                                /* "normal" joystick axis */
                                int deadzone = currprefs.input_joystick_deadzone * max / 100;
@@ -3000,14 +2867,34 @@ int handle_input_event (int nr, int state, int max, int autofire)
                                        state = 0;
                                neg = state < 0 ? 1 : 0;
                                pos = state > 0 ? 1 : 0;
-                               if (ie->data & DIR_LEFT)
+                               if (ie->data & DIR_LEFT) {
                                        left = oleft[joy] = neg;
-                               if (ie->data & DIR_RIGHT)
+                                       if (horizclear[joy] && left) {
+                                               horizclear[joy] = 0;
+                                               right = oright[joy] = 0;
+                                       }
+                               }
+                               if (ie->data & DIR_RIGHT) {
                                        right = oright[joy] = pos;
-                               if (ie->data & DIR_UP)
+                                       if (horizclear[joy] && right) {
+                                               horizclear[joy] = 0;
+                                               left = oleft[joy] = 0;
+                                       }
+                               }
+                               if (ie->data & DIR_UP) {
                                        top = otop[joy] = neg;
-                               if (ie->data & DIR_DOWN)
+                                       if (vertclear[joy] && top) {
+                                               vertclear[joy] = 0;
+                                               bot = obot[joy] = 0;
+                                       }
+                               }
+                               if (ie->data & DIR_DOWN) {
                                        bot = obot[joy] = pos;
+                                       if (vertclear[joy] && bot) {
+                                               vertclear[joy] = 0;
+                                               top = otop[joy] = 0;
+                                       }
+                               }
                        }
                        mouse_deltanoreset[joy][0] = 1;
                        mouse_deltanoreset[joy][1] = 1;
@@ -3070,9 +2957,13 @@ void inputdevice_vsync (void)
 
        input_frame++;
        mouseupdate (0, 1);
-       inputdevice_read ();
 
-       inputdelay = uaerand () % (maxvpos <= 1 ? 1 : maxvpos - 1);
+       if (!input_record) {
+               inputdevice_read ();
+               if (!input_play)
+                       inputdelay = uaerand () % (maxvpos <= 1 ? 1 : maxvpos - 1);
+       }
+
        inputdevice_handle_inputcode ();
        if (mouseedge_alive > 0)
                mouseedge_alive--;
@@ -3104,6 +2995,7 @@ void inputdevice_reset (void)
        mousehack_reset ();
        if (inputdevice_is_tablet ())
                mousehack_enable ();
+       bouncy = 0;
 }
 
 static int getoldport (struct uae_input_device *id)
@@ -3271,6 +3163,10 @@ static void setbuttonstateall (struct uae_input_device *id, struct uae_input_dev
        uae_u32 omask = id2->buttonmask & mask;
        uae_u32 nmask = (state ? 1 : 0) << button;
 
+       if (input_play && state)
+               inprec_realtime ();
+       if (input_play)
+               return;
        if (!id->enabled) {
                if (state)
                        switchdevice (id, button, 1);
@@ -3285,7 +3181,7 @@ static void setbuttonstateall (struct uae_input_device *id, struct uae_input_dev
                int toggle = (id->flags[ID_BUTTON_OFFSET + button][sublevdir[state <= 0 ? 1 : 0][i]] & ID_FLAG_TOGGLE) ? 1 : 0;
 
                if (state < 0) {
-                       handle_input_event (evt, 1, 1, 0);
+                       handle_input_event (evt, 1, 1, 0, true, false);
                        queue_input_event (evt, 0, 1, 1, 0); /* send release event next frame */
                        if (i == 0)
                                process_custom_event (id, ID_BUTTON_OFFSET + button, state);
@@ -3297,12 +3193,12 @@ static void setbuttonstateall (struct uae_input_device *id, struct uae_input_dev
                                continue;
                        id->flags[ID_BUTTON_OFFSET + button][sublevdir[state <= 0 ? 1 : 0][i]] ^= ID_FLAG_TOGGLED;
                        toggled = (id->flags[ID_BUTTON_OFFSET + button][sublevdir[state <= 0 ? 1 : 0][i]] & ID_FLAG_TOGGLED) ? 1 : 0;
-                       handle_input_event (evt, toggled, 1, autofire);
+                       handle_input_event (evt, toggled, 1, autofire, true, false);
                        if (i == 0)
                                process_custom_event (id, ID_BUTTON_OFFSET + button, toggled);
                } else {
                        if ((omask ^ nmask) & mask) {
-                               handle_input_event (evt, state, 1, autofire);
+                               handle_input_event (evt, state, 1, autofire, true, false);
                                if (i == 0)
                                        process_custom_event (id, ID_BUTTON_OFFSET + button, state);
                        }
@@ -3382,19 +3278,19 @@ static int isanalog (int ei)
 static int isdigitalbutton (int ei)
 {
        if (ei == INPUTEVENT_JOY1_2ND_BUTTON) {
-               digital_port[0][0] = 1;
+               digital_port[0][1] = 1;
                return 1;
        }
        if (ei == INPUTEVENT_JOY1_3RD_BUTTON) {
-               digital_port[0][1] = 1;
+               digital_port[0][0] = 1;
                return 1;
        }
        if (ei == INPUTEVENT_JOY2_2ND_BUTTON) {
-               digital_port[1][0] = 1;
+               digital_port[1][1] = 1;
                return 1;
        }
        if (ei == INPUTEVENT_JOY2_3RD_BUTTON) {
-               digital_port[1][1] = 1;
+               digital_port[1][0] = 1;
                return 1;
        }
        return 0;
@@ -3411,7 +3307,7 @@ static void scanevents (struct uae_prefs *p)
        parport_joystick_enabled = 0;
        mouse_port[0] = mouse_port[1] = 0;
 
-       for (i = 0; i < 2; i++) {
+       for (i = 0; i < NORMAL_JPORTS; i++) {
                for (j = 0; j < 2; j++) {
                        digital_port[i][j] = 0;
                        analog_port[i][j] = 0;
@@ -3419,7 +3315,7 @@ static void scanevents (struct uae_prefs *p)
                }
        }
 
-       for (i = 0; i < MAX_INPUT_DEVICE_EVENTS; i++)
+       for (i = 0; i < MAX_JPORTS; i++)
                joydir[i] = 0;
 
        for (i = 0; i < MAX_INPUT_DEVICES; i++) {
@@ -3594,6 +3490,16 @@ static int ip_joy2[] = {
        INPUTEVENT_JOY2_FIRE_BUTTON, INPUTEVENT_JOY2_2ND_BUTTON,
        -1
 };
+static int ip_joypad1[] = {
+       INPUTEVENT_JOY1_LEFT, INPUTEVENT_JOY1_RIGHT, INPUTEVENT_JOY1_UP, INPUTEVENT_JOY1_DOWN,
+       INPUTEVENT_JOY1_FIRE_BUTTON, INPUTEVENT_JOY1_2ND_BUTTON, INPUTEVENT_JOY1_3RD_BUTTON,
+       -1
+};
+static int ip_joypad2[] = {
+       INPUTEVENT_JOY2_LEFT, INPUTEVENT_JOY2_RIGHT, INPUTEVENT_JOY2_UP, INPUTEVENT_JOY2_DOWN,
+       INPUTEVENT_JOY2_FIRE_BUTTON, INPUTEVENT_JOY2_2ND_BUTTON, INPUTEVENT_JOY2_3RD_BUTTON,
+       -1
+};
 static int ip_joycd321[] = {
        INPUTEVENT_JOY1_LEFT, INPUTEVENT_JOY1_RIGHT, INPUTEVENT_JOY1_UP, INPUTEVENT_JOY1_DOWN,
        INPUTEVENT_JOY1_CD32_RED, INPUTEVENT_JOY1_CD32_BLUE, INPUTEVENT_JOY1_CD32_GREEN, INPUTEVENT_JOY1_CD32_YELLOW,
@@ -3683,6 +3589,8 @@ static void checkcompakb (int *kb, int *srcmap)
                        }
                        j++;
                }
+               if (srcmap[k] < 0)
+                       break;
                j++;
                k++;
        }
@@ -3781,9 +3689,6 @@ static void setcompakb (int *kb, int *srcmap, int index, int af)
        }
 }
 
-static int joymodes[MAX_JPORTS];
-static int *joyinputs[MAX_JPORTS];
-
 int inputdevice_get_compatibility_input (struct uae_prefs *prefs, int index, int *typelist, int **inputlist, int **at)
 {
        if (index >= MAX_JPORTS || joymodes[index] < 0)
@@ -4018,6 +3923,9 @@ static void setjoyinputs (struct uae_prefs *prefs, int port)
                        else
                                joyinputs[port] = port == 1 ? ip_joy2 : ip_joy1;
                break;
+               case JSEM_MODE_GAMEPAD:
+                       joyinputs[port] = port ? ip_joypad2 : ip_joypad1;
+               break;
                case JSEM_MODE_JOYSTICK_CD32:
                        joyinputs[port] = port ? ip_joycd322 : ip_joycd321;
                break;
@@ -4108,15 +4016,21 @@ static void compatibility_copy (struct uae_prefs *prefs, bool gameports)
                                {
                                        case JSEM_MODE_DEFAULT:
                                        case JSEM_MODE_JOYSTICK:
+                                       case JSEM_MODE_GAMEPAD:
                                        case JSEM_MODE_JOYSTICK_CD32:
                                        default:
                                        {
                                                bool iscd32 = mode == JSEM_MODE_JOYSTICK_CD32 || (mode == JSEM_MODE_DEFAULT && prefs->cs_cd32cd);
-                                               joymodes[i] = iscd32 ? JSEM_MODE_JOYSTICK_CD32 : JSEM_MODE_JOYSTICK;
-                                               if (!iscd32)
-                                                       joyinputs[i] = i ? ip_joy2 : ip_joy1;
-                                               else
+                                               if (iscd32) {
+                                                       joymodes[i] = JSEM_MODE_JOYSTICK_CD32;
                                                        joyinputs[i] = i ? ip_joycd322 : ip_joycd321;
+                                               } else if (mode == JSEM_MODE_GAMEPAD) {
+                                                       joymodes[i] = JSEM_MODE_GAMEPAD;
+                                                       joyinputs[i] = i ? ip_joypad2 : ip_joypad1;
+                                               } else {
+                                                       joymodes[i] = JSEM_MODE_JOYSTICK;
+                                                       joyinputs[i] = i ? ip_joy2 : ip_joy1;
+                                               }
                                                break;
                                        }
                                        case JSEM_MODE_JOYSTICK_ANALOG:
@@ -4194,12 +4108,18 @@ static void compatibility_copy (struct uae_prefs *prefs, bool gameports)
                                {
                                case JSEM_MODE_DEFAULT:
                                case JSEM_MODE_JOYSTICK:
+                               case JSEM_MODE_GAMEPAD:
                                case JSEM_MODE_JOYSTICK_CD32:
                                default:
                                {
                                        bool iscd32 = mode == JSEM_MODE_JOYSTICK_CD32 || (mode == JSEM_MODE_DEFAULT && prefs->cs_cd32cd);
-                                       input_get_default_joystick (joysticks, joy, i, af, iscd32 ? JSEM_MODE_JOYSTICK_CD32 : 0);
-                                       joymodes[i] = iscd32 ? JSEM_MODE_JOYSTICK_CD32 : JSEM_MODE_JOYSTICK;
+                                       input_get_default_joystick (joysticks, joy, i, af, mode);
+                                       if (iscd32)
+                                               joymodes[i] = JSEM_MODE_JOYSTICK_CD32;
+                                       else if (mode == JSEM_MODE_GAMEPAD)
+                                               joymodes[i] = JSEM_MODE_GAMEPAD;
+                                       else
+                                               joymodes[i] = JSEM_MODE_JOYSTICK;
                                        break;
                                }
                                case JSEM_MODE_JOYSTICK_ANALOG:
@@ -4229,16 +4149,20 @@ static void compatibility_copy (struct uae_prefs *prefs, bool gameports)
 
        if (gameports) {
                // replace possible old mappings with default keyboard mapping
-               for (i = KBR_DEFAULT_MAP_NP; i <= KBR_DEFAULT_MAP_SE; i++) {
+               for (i = KBR_DEFAULT_MAP_FIRST; i <= KBR_DEFAULT_MAP_LAST; i++) {
                        checkcompakb (keyboard_default_kbmaps[i], ip_joy2);
                        checkcompakb (keyboard_default_kbmaps[i], ip_joy1);
+                       checkcompakb (keyboard_default_kbmaps[i], ip_joypad2);
+                       checkcompakb (keyboard_default_kbmaps[i], ip_joypad1);
                        checkcompakb (keyboard_default_kbmaps[i], ip_parjoy2);
                        checkcompakb (keyboard_default_kbmaps[i], ip_parjoy1);
                        checkcompakb (keyboard_default_kbmaps[i], ip_mouse2);
                        checkcompakb (keyboard_default_kbmaps[i], ip_mouse1);
                }
-               checkcompakb (keyboard_default_kbmaps[5], ip_joycd321);
-               checkcompakb (keyboard_default_kbmaps[5], ip_joycd322);
+               for (i = KBR_DEFAULT_MAP_CD32_FIRST; i <= KBR_DEFAULT_MAP_CD32_LAST; i++) {
+                       checkcompakb (keyboard_default_kbmaps[i], ip_joycd321);
+                       checkcompakb (keyboard_default_kbmaps[i], ip_joycd322);
+               }
        }
 
        for (i = 0; i < 2; i++) {
@@ -4252,16 +4176,22 @@ static void compatibility_copy (struct uae_prefs *prefs, bool gameports)
                                if (JSEM_ISNUMPAD (i, prefs)) {
                                        if (cd32)
                                                kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_CD32_NP];
+                                       else if (mode == JSEM_MODE_GAMEPAD)
+                                               kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_NP3];
                                        else
                                                kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_NP];
                                } else if (JSEM_ISCURSOR (i, prefs)) {
                                        if (cd32)
                                                kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_CD32_CK];
+                                       else if (mode == JSEM_MODE_GAMEPAD)
+                                               kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_CK3];
                                        else
                                                kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_CK];
                                } else if (JSEM_ISSOMEWHEREELSE (i, prefs)) {
                                        if (cd32)
                                                kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_CD32_SE];
+                                       else if (mode == JSEM_MODE_GAMEPAD)
+                                               kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_SE3];
                                        else
                                                kb = keyboard_default_kbmaps[KBR_DEFAULT_MAP_SE];
                                } else if (JSEM_ISXARCADE1 (i, prefs)) {
@@ -4273,11 +4203,15 @@ static void compatibility_copy (struct uae_prefs *prefs, bool gameports)
                                        switch (mode)
                                        {
                                        case JSEM_MODE_JOYSTICK:
+                                       case JSEM_MODE_GAMEPAD:
                                        case JSEM_MODE_JOYSTICK_CD32:
                                        case JSEM_MODE_DEFAULT:
                                                if (cd32) {
                                                        setcompakb (kb, i ? ip_joycd322 : ip_joycd321, i, af);
                                                        joymodes[i] = JSEM_MODE_JOYSTICK_CD32;
+                                               } else if (mode == JSEM_MODE_GAMEPAD) {
+                                                       setcompakb (kb, i ? ip_joypad2 : ip_joypad1, i, af);
+                                                       joymodes[i] = JSEM_MODE_GAMEPAD;
                                                } else {
                                                        setcompakb (kb, i ? ip_joy2 : ip_joy1, i, af);
                                                        joymodes[i] = JSEM_MODE_JOYSTICK;
@@ -4508,7 +4442,7 @@ void inputdevice_updateconfig (struct uae_prefs *prefs)
                otop[i] = 0;
                obot[i] = 0;
        }
-       for (i = 0; i < MAX_INPUT_DEVICES; i++) {
+       for (i = 0; i < MAX_JPORTS; i++) {
                mouse_deltanoreset[i][0] = 0;
                mouse_delta[i][0] = 0;
                mouse_deltanoreset[i][1] = 0;
@@ -4687,6 +4621,7 @@ static int inputdevice_translatekeycode_2 (int keyboard, int scancode, int state
 
        if (!keyboards || scancode < 0)
                return handled;
+
        j = 0;
        while (j < MAX_INPUT_DEVICE_EVENTS && na->extra[j] >= 0) {
                if (na->extra[j] == scancode) {
@@ -4716,9 +4651,9 @@ static int inputdevice_translatekeycode_2 (int keyboard, int scancode, int state
                                                continue;
                                        na->flags[j][sublevdir[state == 0 ? 1 : 0][k]] ^= ID_FLAG_TOGGLED;
                                        toggled = (na->flags[j][sublevdir[state == 0 ? 1 : 0][k]] & ID_FLAG_TOGGLED) ? 1 : 0;
-                                       handled |= handle_input_event (evt, toggled, 1, autofire);
+                                       handled |= handle_input_event (evt, toggled, 1, autofire, true, false);
                                } else {
-                                       handled |= handle_input_event (evt, state, 1, autofire);
+                                       handled |= handle_input_event (evt, state, 1, autofire, true, false);
                                }
                        }
                        process_custom_event (na, j, state);
@@ -4783,7 +4718,7 @@ void inputdevice_close (void)
        idev[IDTYPE_JOYSTICK].close ();
        idev[IDTYPE_MOUSE].close ();
        idev[IDTYPE_KEYBOARD].close ();
-       inprec_close ();
+       inprec_close (true);
 }
 
 static struct uae_input_device *get_uid (const struct inputdevice_functions *id, int devnum)
@@ -5505,13 +5440,17 @@ void setjoystickstate (int joy, int axis, int state, int max)
                v2 = 0;
        if (v1 == v2)
                return;
+       if (input_play && state)
+               inprec_realtime ();
+       if (input_play)
+               return;
        if (!joysticks[joy].enabled) {
                if (v1)
                        switchdevice (&joysticks[joy], axis * 2 + (v1 < 0 ? 0 : 1), 0);
                return;
        }
        for (i = 0; i < MAX_INPUT_SUB_EVENT; i++)
-               handle_input_event (id->eventid[ID_AXIS_OFFSET + axis][i], state, max, id->flags[ID_AXIS_OFFSET + axis][i] & ID_FLAG_AUTOFIRE);
+               handle_input_event (id->eventid[ID_AXIS_OFFSET + axis][i], state, max, id->flags[ID_AXIS_OFFSET + axis][i] & ID_FLAG_AUTOFIRE, true, false);
        id2->states[axis] = state;
 }
 int getjoystickstate (int joy)
@@ -5535,6 +5474,8 @@ void setmousestate (int mouse, int axis, int data, int isabs)
                inputdevice_testrecord (IDTYPE_MOUSE, mouse, IDEV_WIDGET_AXIS, axis, 0);
                return;
        }
+       if (input_play)
+               return;
        if (!mice[mouse].enabled) {
                if (isabs && currprefs.input_tablet > 0) {
                        if (axis == 0)
@@ -5575,7 +5516,7 @@ void setmousestate (int mouse, int axis, int data, int isabs)
        v += diff;
        fract[mouse][axis] -= diff;
        for (i = 0; i < MAX_INPUT_SUB_EVENT; i++)
-               handle_input_event (id->eventid[ID_AXIS_OFFSET + axis][i], v, 0, 0);
+               handle_input_event (id->eventid[ID_AXIS_OFFSET + axis][i], v, 0, 0, true, false);
 }
 
 int getmousestate (int joy)
@@ -5777,3 +5718,61 @@ int inputdevice_getjoyportdevice (int port, int val)
        }
        return idx;
 }
+
+// for state recorder use only!
+
+uae_u8 *save_inputstate (int *len, uae_u8 *dstptr)
+{
+       uae_u8 *dstbak, *dst;
+
+       if (dstptr)
+               dstbak = dst = dstptr;
+       else
+               dstbak = dst = xmalloc (uae_u8, 1000);
+       for (int i = 0; i < MAX_JPORTS; i++) {
+               save_u16 (joydir[i]);
+               save_u16 (joybutton[i]);
+               save_u16 (otop[i]);
+               save_u16 (obot[i]);
+               save_u16 (oleft[i]);
+               save_u16 (oright[i]);
+       }
+       for (int i = 0; i < NORMAL_JPORTS; i++) {
+               save_u16 (cd32_shifter[i]);
+               for (int j = 0; j < 2; j++) {
+                       save_u16 (pot_cap[i][j]);
+                       save_u16 (joydirpot[i][j]);
+               }
+       }
+       *len = dst - dstbak;
+       return dstbak;
+}
+
+uae_u8 *restore_inputstate (uae_u8 *src)
+{
+       for (int i = 0; i < MAX_JPORTS; i++) {
+               joydir[i] = restore_u16 ();
+               joybutton[i] = restore_u16 ();
+               otop[i] = restore_u16 ();
+               obot[i] = restore_u16 ();
+               oleft[i] = restore_u16 ();
+               oright[i] = restore_u16 ();
+       }
+       for (int i = 0; i < NORMAL_JPORTS; i++) {
+               cd32_shifter[i] = restore_u16 ();
+               for (int j = 0; j < 2; j++) {
+                       pot_cap[i][j] = restore_u16 ();
+                       joydirpot[i][j] = restore_u16 ();
+               }
+       }
+       return src;
+}
+
+void clear_inputstate (void)
+{
+       return;
+       for (int i = 0; i < MAX_JPORTS; i++) {
+               horizclear[i] = 1;
+               vertclear[i] = 1;
+       }
+}
index e7ae6a7f69b122fdec6612a696e4ef029cdab561..5337c8db11c389cf3032cc1096bec2986aef560c 100644 (file)
@@ -314,7 +314,11 @@ DEFEVENT(SPC_PAUSE,L"Pause emulation",AM_K,0,0,AKS_PAUSE)
 DEFEVENT(SPC_WARP,L"Warp mode",AM_K,0,0,AKS_WARP)
 DEFEVENT(SPC_INHIBITSCREEN,L"Toggle screen updates",AM_K,0,0,AKS_INHIBITSCREEN)
 DEFEVENT(SPC_IRQ7,L"Level 7 interrupt",AM_K,0,0,AKS_IRQ7)
-DEFEVENT(SPC_STATEREWIND,L"Load previous state capture",AM_K,0,0,AKS_STATEREWIND)
+
+DEFEVENT(SPC_STATEREWIND,L"Load previous state capture checkpoint",AM_K,0,0,AKS_STATEREWIND)
+DEFEVENT(SPC_STATECURRENT,L"Load current state capture checkpoint",AM_K,0,0,AKS_STATECURRENT)
+DEFEVENT(SPC_STATECAPTURE,L"Save state capture checkpoint",AM_K,0,0,AKS_STATECAPTURE)
+
 DEFEVENT(SPC_VOLUME_DOWN,L"Decrease volume level",AM_K,0,0,AKS_VOLDOWN)
 DEFEVENT(SPC_VOLUME_UP,L"Increase volume level",AM_K,0,0,AKS_VOLUP)
 DEFEVENT(SPC_VOLUME_MUTE,L"Mute/unmute volume",AM_K,0,0,AKS_VOLMUTE)
diff --git a/inputrecord.cpp b/inputrecord.cpp
new file mode 100644 (file)
index 0000000..09aa162
--- /dev/null
@@ -0,0 +1,904 @@
+/*
+* UAE - The Un*x Amiga Emulator
+*
+* Input record/playback
+*
+* Copyright 2010 Toni Wilen
+*
+*/
+
+#define INPUTRECORD_DEBUG 1
+
+#define HEADERSIZE 12
+
+#include "sysconfig.h"
+#include "sysdeps.h"
+
+#include "options.h"
+#include "inputrecord.h"
+#include "zfile.h"
+#include "custom.h"
+#include "savestate.h"
+#include "cia.h"
+#include "events.h"
+#include "uae.h"
+#include "disk.h"
+
+#if INPUTRECORD_DEBUG > 0
+#include "memory.h"
+#include "newcpu.h"
+#endif
+
+int inputrecord_debug = 3;
+
+extern int inputdevice_logging;
+
+#define INPREC_BUFFER_SIZE 10000
+
+static uae_u8 *inprec_buffer, *inprec_p;
+static struct zfile *inprec_zf;
+static int inprec_size;
+int input_record = 0;
+int input_play = 0;
+static uae_u8 *inprec_plast, *inprec_plastptr;
+static int header_end, header_end2;
+static int replaypos;
+static int lasthsync, endhsync;
+static TCHAR inprec_path[MAX_DPATH];
+static uae_u32 seed;
+static uae_u32 lastcycle;
+static uae_u32 cycleoffset;
+
+static uae_u32 pcs[16];
+static uae_u32 pcs2[16];
+extern void activate_debugger (void);
+static int warned;
+
+extern void refreshtitle (void);
+
+static void setlasthsync (void)
+{
+       if (lasthsync / current_maxvpos () != hsync_counter / current_maxvpos ()) {
+               lasthsync = hsync_counter;
+               refreshtitle ();
+       }
+}
+
+static void flush (void)
+{
+       if (inprec_p > inprec_buffer) {
+               zfile_fwrite (inprec_buffer, inprec_p - inprec_buffer, 1, inprec_zf);
+               inprec_p = inprec_buffer;
+       }
+}
+
+static void inprec_ru8 (uae_u8 v)
+{
+       if (!input_record || !inprec_zf)
+               return;
+       *inprec_p++= v;
+}
+static void inprec_ru16 (uae_u16 v)
+{
+       if (!input_record || !inprec_zf)
+               return;
+       inprec_ru8 ((uae_u8)(v >> 8));
+       inprec_ru8 ((uae_u8)v);
+}
+void inprec_ru32 (uae_u32 v)
+{
+       if (!input_record || !inprec_zf)
+               return;
+       inprec_ru16 ((uae_u16)(v >> 16));
+       inprec_ru16 ((uae_u16)v);
+}
+static void inprec_rstr (const TCHAR *src)
+{
+       if (!input_record || !inprec_zf)
+               return;
+       char *s = uutf8 (src);
+       char *ss = s;
+       while (*s) {
+               inprec_ru8 (*s);
+               s++;
+       }
+       inprec_ru8 (0);
+       xfree (ss);
+}
+
+static bool inprec_rstart (uae_u8 type)
+{
+       if (!input_record || !inprec_zf || input_record == INPREC_RECORD_PLAYING)
+               return false;
+       lastcycle = get_cycles ();
+       int mvp = current_maxvpos ();
+       if ((type != INPREC_DEBUG && type != INPREC_DEBUG2 && type != INPREC_CIADEBUG) || (0 && vsync_counter >= 49 && vsync_counter <= 51))
+               write_log (L"INPREC: %010d/%03d: %d (%d/%d) %08x\n", hsync_counter, current_hpos (), type, hsync_counter % mvp, mvp, lastcycle);
+       inprec_plast = inprec_p;
+       inprec_ru8 (type);
+       inprec_ru16 (0xffff);
+       inprec_ru32 (hsync_counter);
+       inprec_ru8 (current_hpos ());
+       inprec_ru32 (lastcycle);
+       return true;
+}
+
+static void inprec_rend (void)
+{
+       if (!input_record || !inprec_zf)
+               return;
+       int size = inprec_p - inprec_plast;
+       inprec_plast[1] = size >> 8;
+       inprec_plast[2] = size >> 0;
+       flush ();
+       endhsync = hsync_counter;
+       setlasthsync ();
+}
+
+static bool inprec_realtime (bool stopstart)
+{
+       if (input_record == INPREC_RECORD_RERECORD)
+               gui_message (L"INPREC error");
+       write_log (L"INPREC: play -> record\n");
+       input_record = INPREC_RECORD_RERECORD;
+       input_play = 0;
+       int offset = inprec_p - inprec_buffer;
+       zfile_fseek (inprec_zf, offset, SEEK_SET);
+       zfile_truncate (inprec_zf, offset);
+       xfree (inprec_buffer);
+       inprec_size = INPREC_BUFFER_SIZE;
+       inprec_buffer = inprec_p = xmalloc (uae_u8, inprec_size);
+       clear_inputstate ();
+       return true;
+}
+
+static int inprec_pstart (uae_u8 type)
+{
+       uae_u8 *p = inprec_p;
+       uae_u32 hc = hsync_counter;
+       uae_u8 hpos = current_hpos ();
+       uae_u32 cycles = get_cycles ();
+       static uae_u8 *lastp;
+       uae_u32 hc_orig, hc2_orig;
+       int mvp = current_maxvpos ();
+
+       if (!input_play || !inprec_zf)
+               return 0;
+       if (savestate_state || hsync_counter > 0xffff0000)
+               return 0;
+       if (p == inprec_buffer + inprec_size) {
+               write_log (L"INPREC: STOP\n");
+               if (input_play == INPREC_PLAY_RERECORD) {
+                       input_play = 0;
+                       inprec_realtime (true);
+               } else {
+                       inprec_close (true);
+               }
+               return 0;
+       } else if (p > inprec_buffer + inprec_size) {
+               write_log (L"INPREC: buffer error\n");
+               gui_message (L"INPREC error");
+       }
+       if (p[0] == INPREC_END) {
+               inprec_close (true);
+               return 0;
+       } else if (p[0] == INPREC_QUIT) {
+               inprec_close (true);
+               uae_quit ();
+               return 0;
+       }
+       hc_orig = hc;
+       for (;;) {
+               uae_u32 type2 = p[0];
+               uae_u32 hc2 = (p[3] << 24) | (p[4] << 16) | (p[5] << 8) | p[6];
+               uae_u32 hpos2 = p[7];
+               uae_u32 cycles2 = (p[8] << 24) | (p[9] << 16) | (p[10] << 8) | p[11];
+
+               if (p >= inprec_buffer + inprec_size)
+                       break;
+#if 0
+               if (p > lastp) {
+                       write_log (L"INPREC: Next %010d/%03d, %010d/%03d (%d/%d): %d (%d)\n",
+                               hc2, hpos2, hc, hpos, hc2 - hc, hpos2 - hpos, p[5 + 1], p[5]);
+                       lastp = p;
+               }
+#endif
+               hc2_orig = hc2;
+               if (type2 == type && hc > hc2) {
+                       write_log (L"INPREC: %010d/%03d > %010d/%03d: %d missed!\n", hc, hpos, hc2, hpos2, p[0]);
+                       gui_message (L"INPREC missed error");
+                       lastcycle = cycles;
+                       inprec_plast = p;
+                       inprec_plastptr = p + 12;
+                       setlasthsync ();
+                       return 1;
+               }
+               if (hc2 != hc) {
+                       lastp = p;
+                       break;
+               }
+               if (type2 == type) {
+                       if (type != INPREC_DEBUG && type != INPREC_DEBUG2 && type != INPREC_CIADEBUG && cycles != cycles2)
+                               write_log (L"INPREC: %010d/%03d: %d (%d/%d) (%d/%d) %08X/%08X\n", hc, hpos, type, hc % mvp, mvp, hc_orig - hc2_orig, hpos - hpos2, cycles, cycles2);
+                       if (cycles != cycles2 + cycleoffset) {
+                               if (warned > 0) {
+                                       warned--;
+                                       for (int i = 0; i < 7; i++)
+                                               write_log (L"%08x (%08x) ", pcs[i], pcs2[i]);
+                                       write_log (L"\n");
+                               }
+                               cycleoffset = cycles - cycles2;
+                               gui_message (L"INPREC OFFSET=%d\n", cycleoffset / CYCLE_UNIT);
+                       }
+                       lastcycle = cycles;
+                       inprec_plast = p;
+                       inprec_plastptr = p + 12;
+                       setlasthsync ();
+                       return 1;
+               }
+               if (type2 == INPREC_END || type2 == INPREC_QUIT)
+                       break;
+               p += (p[1] << 8) | (p[2] << 0);
+       }
+       inprec_plast = NULL;
+       return 0;
+}
+
+static void inprec_pend (void)
+{
+       uae_u8 *p = inprec_p;
+       uae_u32 hc = hsync_counter;
+       uae_u32 hpos = current_hpos ();
+
+       if (!input_play || !inprec_zf)
+               return;
+       if (!inprec_plast)
+               return;
+       inprec_plast[0] |= 0x80;
+       inprec_plast = NULL;
+       inprec_plastptr = NULL;
+       for (;;) {
+               uae_u32 hc2 = (p[3] << 24) | (p[4] << 16) | (p[5] << 8) | p[6];
+               uae_u32 hpos2 = p[7];
+               if (hc2 != hc)
+                       break;
+               if ((p[0] & 0x80) == 0)
+                       return;
+               p += (p[1] << 8) | (p[2] << 0);
+               inprec_p = p;
+       }
+}
+
+static uae_u8 inprec_pu8 (void)
+{
+       return *inprec_plastptr++;
+}
+static uae_u16 inprec_pu16 (void)
+{
+       uae_u16 v = inprec_pu8 () << 8;
+       v |= inprec_pu8 ();
+       return v;
+}
+static uae_s16 inprec_ps16 (void)
+{
+       uae_u16 v = inprec_pu8 () << 8;
+       v |= inprec_pu8 ();
+       return (uae_s16)v;
+}
+static uae_u32 inprec_pu32 (void)
+{
+       uae_u32 v = inprec_pu16 () << 16;
+       v |= inprec_pu16 ();
+       return v;
+}
+static int inprec_pstr (TCHAR *dst)
+{
+       char tmp[MAX_DPATH];
+       char *s;
+       int len = 0;
+
+       *dst = 0;
+       s = tmp;
+       for(;;) {
+               char v = inprec_pu8 ();
+               *s++ = v;
+               if (!v)
+                       break;
+               len++;
+       }
+       if (tmp[0]) {
+               TCHAR *d = utf8u (tmp);
+               _tcscpy (dst, d);
+               xfree (d);
+       }
+       return len;
+}
+
+static void findlast (void)
+{
+       uae_u32 hsync = 0;
+       uae_u8 *p = inprec_p;
+       while (p < inprec_buffer + inprec_size) {
+               hsync = (p[3] << 24) | (p[4] << 16) | (p[5] << 8) | p[6];
+               uae_u16 len = (p[1] << 8) | (p[2] << 0);
+               p += len;
+       }
+       endhsync = hsync;
+}
+
+
+int inprec_open (const TCHAR *fname, const TCHAR *statefilename)
+{
+       int i;
+
+       inprec_close (false);
+       if (fname == NULL)
+               inprec_zf = zfile_fopen_empty (NULL, L"inp");
+       else
+               inprec_zf = zfile_fopen (fname, input_record ? L"wb" : L"rb", ZFD_NORMAL);
+       if (inprec_zf == NULL)
+               return 0;
+       inprec_path[0] = 0;
+       if (fname)
+               getpathpart (inprec_path, sizeof inprec_path / sizeof (TCHAR), fname);
+       seed = (uae_u32)time(0);
+       inprec_size = INPREC_BUFFER_SIZE;
+       lasthsync = 0;
+       endhsync = 0;
+       warned = 10;
+       cycleoffset = 0;
+       header_end2 = 0;
+       if (input_play) {
+               uae_u32 id;
+               zfile_fseek (inprec_zf, 0, SEEK_END);
+               inprec_size = zfile_ftell (inprec_zf);
+               zfile_fseek (inprec_zf, 0, SEEK_SET);
+               inprec_buffer = inprec_p = xmalloc (uae_u8, inprec_size);
+               zfile_fread (inprec_buffer, inprec_size, 1, inprec_zf);
+               inprec_plastptr = inprec_buffer;
+               id = inprec_pu32();
+               if (id != 'UAE\0') {
+                       inprec_close (true);
+                       return 0;
+               }
+               int v = inprec_pu8 ();
+               if (v != 2) {
+                       inprec_close (true);
+                       return 0;
+               }
+               inprec_pu8 ();
+               inprec_pu8 ();
+               inprec_pu8 ();
+               seed = inprec_pu32();
+               seed = uaesrand (seed);
+               vsync_counter = inprec_pu32 ();
+               hsync_counter = inprec_pu32 ();
+               i = inprec_pu32 ();
+               while (i-- > 0)
+                       inprec_pu8 ();
+               header_end = inprec_plastptr - inprec_buffer;
+               inprec_pstr (savestate_fname);
+               if (savestate_fname[0]) {
+                       savestate_state = STATE_RESTORE;
+                       for (;;) {
+                               TCHAR tmp[MAX_DPATH];
+                               _tcscpy (tmp, fname);
+                               _tcscat (tmp, L".uss");
+                               if (zfile_exists (tmp)) {
+                                       _tcscpy (savestate_fname, tmp);
+                                       break;
+                               }
+                               if (zfile_exists (savestate_fname))
+                                       break;
+                               TCHAR *p = _tcsrchr (savestate_fname, '\\');
+                               if (!p)
+                                       p = _tcsrchr (savestate_fname, '/');
+                               if (!p)
+                                       p = savestate_fname;
+                               else
+                                       p++;
+                               if (zfile_exists (p)) {
+                                       _tcscpy (savestate_fname, p);
+                                       break;
+                               }
+                               fetch_statefilepath (tmp, sizeof tmp / sizeof (TCHAR));
+                               _tcscat (tmp, p);
+                               if (zfile_exists (tmp)) {
+                                       _tcscpy (savestate_fname, tmp);
+                                       break;
+                               }
+                               fetch_inputfilepath (tmp, sizeof tmp / sizeof (TCHAR));
+                               _tcscat (tmp, p);
+                               if (zfile_exists (tmp)) {
+                                       _tcscpy (savestate_fname, tmp);
+                                       break;
+                               }
+                               write_log (L"Failed to open linked statefile '%s'\n", savestate_fname);
+                               savestate_fname[0] = 0;
+                               savestate_state = 0;
+                               break;
+                       }
+               }
+               inprec_p = inprec_plastptr;
+               header_end2 = inprec_plastptr - inprec_buffer;
+               findlast ();
+       } else if (input_record) {
+               seed = uaesrand (seed);
+               inprec_buffer = inprec_p = xmalloc (uae_u8, inprec_size);
+               inprec_ru32 ('UAE\0');
+               inprec_ru8 (2);
+               inprec_ru8 (UAEMAJOR);
+               inprec_ru8 (UAEMINOR);
+               inprec_ru8 (UAESUBREV);
+               inprec_ru32 (seed);
+               inprec_ru32 (vsync_counter);
+               inprec_ru32 (hsync_counter);
+               inprec_ru32 (0); // extra header size
+               flush ();
+               header_end2 = header_end = zfile_ftell (inprec_zf);
+       } else {
+               input_record = input_play = 0;
+               return 0;
+       }
+       if (inputrecord_debug) {
+               if (disk_debug_logging < 1)
+                       disk_debug_logging = 1 | 2;
+               inputdevice_logging |= 4 | 2;
+       }
+       write_log (L"inprec initialized '%s', play=%d rec=%d\n", fname ? fname : L"<internal>", input_play, input_record);
+       refreshtitle ();
+       return 1;
+}
+
+void inprec_startup (void)
+{
+       uaesrand (seed);
+}
+
+bool inprec_prepare_record (const TCHAR *statefilename)
+{
+       TCHAR state[MAX_DPATH];
+       int mode = statefilename ? 2 : 1;
+       state[0] = 0;
+       if (statefilename)
+               _tcscpy (state, statefilename);
+       if (hsync_counter > 0 && savestate_state == 0) {
+               TCHAR *s = _tcsrchr (changed_prefs.inprecfile, '\\');
+               if (!s)
+                       s = _tcsrchr (changed_prefs.inprecfile, '/');
+               if (s) {
+                       fetch_statefilepath (state, sizeof state / sizeof (TCHAR));
+                       _tcscat (state, s + 1);
+               } else {
+                       _tcscpy (state, changed_prefs.inprecfile);
+               }
+               _tcscat (state, L".uss");
+               savestate_initsave (state, 1, 1, true); 
+               save_state (state, L"input recording test");
+               mode = 2;
+       }
+       input_record = INPREC_RECORD_NORMAL;
+       inprec_open (changed_prefs.inprecfile, state);
+       changed_prefs.inprecfile[0] = currprefs.inprecfile[0] = 0;
+       return true;
+}
+
+
+void inprec_close (bool clear)
+{
+       if (clear)
+               input_play = input_record = 0;
+       if (!inprec_zf)
+               return;
+       if (inprec_buffer && input_record) {
+               if (inprec_rstart (INPREC_END))
+                       inprec_rend ();
+       }
+       zfile_fclose (inprec_zf);
+       inprec_zf = NULL;
+       xfree (inprec_buffer);
+       inprec_buffer = NULL;
+       input_play = input_record = 0;
+       write_log (L"inprec finished\n");
+       refreshtitle ();
+}
+
+static void setwriteprotect (const TCHAR *fname, bool readonly)
+{
+       struct _stat64 st;
+       int mode, oldmode;
+       if (stat (fname, &st))
+               return;
+       oldmode = mode = st.st_mode;
+       mode &= ~FILEFLAG_WRITE;
+       if (!readonly)
+               mode |= FILEFLAG_WRITE;
+       if (mode != oldmode)
+               chmod (fname, mode);
+}
+
+void inprec_playdiskchange (void)
+{
+       if (!input_play)
+               return;
+       while (inprec_pstart (INPREC_DISKREMOVE)) {
+               int drv = inprec_pu8 ();
+               inprec_pend ();
+               write_log (L"INPREC: disk eject drive %d\n", drv);
+               disk_eject (drv);
+       }
+       while (inprec_pstart (INPREC_DISKINSERT)) {
+               int drv = inprec_pu8 ();
+               bool wp = inprec_pu8 () != 0;
+               TCHAR tmp[MAX_DPATH];
+               inprec_pstr (tmp);
+               if (!zfile_exists (tmp)) {
+                       TCHAR tmp2[MAX_DPATH];
+                       _tcscpy (tmp2, inprec_path);
+                       _tcscat (tmp2, tmp);
+                       _tcscpy (tmp, tmp2);
+               }
+               _tcscpy (currprefs.floppyslots[drv].df, tmp);
+               _tcscpy (changed_prefs.floppyslots[drv].df, tmp);
+               setwriteprotect (tmp, wp);
+               disk_insert_force (drv, tmp, wp);
+               write_log (L"INPREC: disk insert drive %d '%s'\n", drv, tmp);
+               inprec_pend ();
+       }
+}
+
+bool inprec_playevent (int *nr, int *state, int *max, int *autofire)
+{
+       if (inprec_pstart (INPREC_EVENT)) {
+               *nr = inprec_ps16 ();
+               *state = inprec_ps16 ();
+               *max = inprec_ps16 ();
+               *autofire = inprec_ps16 () & 1;
+               inprec_pend ();
+               return true;
+       }
+       return false;
+}
+
+void inprec_recorddebug_cia (uae_u32 v1, uae_u32 v2, uae_u32 v3)
+{
+#if INPUTRECORD_DEBUG > 0
+       if (inprec_rstart (INPREC_CIADEBUG)) {
+               inprec_ru32 (v1);
+               inprec_ru32 (v2);
+               inprec_ru32 (v3);
+               inprec_rend ();
+       }
+#endif
+}
+void inprec_playdebug_cia (uae_u32 v1, uae_u32 v2, uae_u32 v3)
+{
+#if INPUTRECORD_DEBUG > 0
+       int err = 0;
+       if (inprec_pstart (INPREC_CIADEBUG)) {
+               uae_u32 vv1 = inprec_pu32 ();
+               uae_u32 vv2 = inprec_pu32 ();
+               uae_u32 vv3 = inprec_pu32 ();
+               if (vv1 != v1 || vv2 != v2 || vv3 != v3)
+                       write_log (L"CIA SYNC ERROR %08x,%08x %08x,%08x %08x,%08x\n", vv1, v1, vv2, v2, vv3, v3);
+               inprec_pend ();
+       }
+#endif
+}
+
+void inprec_recorddebug_cpu (int mode)
+{
+#if INPUTRECORD_DEBUG > 0
+       if (inprec_rstart (INPREC_DEBUG2)) {
+               inprec_ru32 (m68k_getpc ());
+               inprec_ru32 (get_cycles () | mode);
+               inprec_rend ();
+       }
+#endif
+}
+void inprec_playdebug_cpu (int mode)
+{
+#if INPUTRECORD_DEBUG > 0
+       int err = 0;
+       if (inprec_pstart (INPREC_DEBUG2)) {
+               uae_u32 pc1 = m68k_getpc ();
+               uae_u32 pc2 = inprec_pu32 ();
+               uae_u32 v1 = get_cycles () | mode;
+               uae_u32 v2 = inprec_pu32 ();
+               if (pc1 != pc2) {
+                       if (warned > 0) {
+                               warned--;
+                               write_log (L"SYNC ERROR2 PC %08x != %08x\n", pc1, pc2);
+                               for (int i = 0; i < 15; i++)
+                                       write_log (L"%08x ", pcs[i]);
+                               write_log (L"\n");
+
+                       }
+                       err = 1;
+               } else {
+                       memmove (pcs + 1, pcs, 15 * 4);
+                       pcs[0] = pc1;
+                       memmove (pcs2 + 1, pcs2, 15 * 4);
+                       pcs2[0] = get_cycles ();
+               }
+               if (v1 != v2) {
+                       if (warned > 0) {
+                               warned--;
+                               write_log (L"SYNC ERROR2 %08x != %08x\n", v1, v2);
+                               for (int i = 0; i < 15; i++)
+                                       write_log (L"%08x ", pcs[i]);
+                               write_log (L"\n");
+                       }
+                       err = 1;
+               }
+               inprec_pend ();
+       } else if (input_play > 0) {
+               if (warned > 0) {
+                       warned--;
+                       write_log (L"SYNC ERROR2 debug event missing!?\n");
+               }
+       }
+#endif
+}
+
+void inprec_recorddebug (uae_u32 val)
+{
+#if INPUTRECORD_DEBUG > 0
+       if (inprec_rstart (INPREC_DEBUG)) {
+               inprec_ru32 (uaerandgetseed ());
+               inprec_ru32 (val);
+               inprec_rend ();
+       }
+#endif
+}
+void inprec_playdebug (uae_u32 val)
+{
+#if INPUTRECORD_DEBUG > 0
+       extern void activate_debugger (void);
+       static uae_u32 pcs[16];
+       int err = 0;
+       if (inprec_pstart (INPREC_DEBUG)) {
+               uae_u32 seed1 = uaerandgetseed ();
+               uae_u32 seed2 = inprec_pu32 ();
+               if (seed1 != seed2) {
+                       write_log (L"SYNC ERROR seed %08x != %08x\n", seed1, seed2);
+                       err = 1;
+               }
+               uae_u32 val2 = inprec_pu32 ();
+               if (val != val2) {
+                       write_log (L"SYNC ERROR val %08x != %08x\n", val, val2);
+                       err = 1;
+               }
+               inprec_pend ();
+       } else if (input_play > 0) {
+               gui_message (L"SYNC ERROR debug event missing!?\n");
+       }
+#endif
+}
+
+
+void inprec_recordevent (int nr, int state, int max, int autofire)
+{
+       if (savestate_state)
+               return;
+       if (input_record < INPREC_RECORD_NORMAL)
+               return;
+       if (inprec_rstart (INPREC_EVENT)) {
+               inprec_ru16 (nr);
+               inprec_ru16 (state);
+               inprec_ru16 (max);
+               inprec_ru16 (autofire ? 1 : 0);
+               inprec_rend ();
+               if (input_record == INPREC_RECORD_NORMAL)
+                       input_record = INPREC_RECORD_RERECORD;
+       }
+}
+
+void inprec_recorddiskchange (int nr, const TCHAR *fname, bool writeprotected)
+{
+       if (savestate_state)
+               return;
+       if (input_record < INPREC_RECORD_NORMAL)
+               return;
+       if (fname && fname[0]) {
+               if (inprec_rstart (INPREC_DISKINSERT)) {
+                       inprec_ru8 (nr);
+                       inprec_ru8 (writeprotected ? 1 : 0);
+                       inprec_rstr (fname);
+                       write_log (L"INPREC: disk insert %d '%s'\n", nr, fname);
+                       inprec_rend ();
+               }
+       } else {
+               if (inprec_rstart (INPREC_DISKREMOVE)) {
+                       inprec_ru8 (nr);
+                       write_log (L"INPREC: disk eject %d\n", nr);
+                       inprec_rend ();
+               }
+       }
+}
+
+int inprec_getposition (void)
+{
+       int pos = -1;
+       if (input_play == INPREC_PLAY_RERECORD) {
+               pos = inprec_p - inprec_buffer;
+       } else if (input_record) {
+               pos = zfile_ftell (inprec_zf);
+       }
+       write_log (L"INPREC: getpos=%d cycles=%08X\n", pos, lastcycle);
+       if (pos < 0) {
+               write_log (L"INPREC: getpos failure\n");
+               gui_message (L"INPREC error");
+       }
+       return pos;
+}
+
+// normal play to re-record
+void inprec_playtorecord (void)
+{
+       write_log (L"INPREC: PLAY to RE-RECORD\n");
+       replaypos = 0;
+       findlast ();
+       input_play = INPREC_PLAY_RERECORD;
+       input_record = INPREC_RECORD_PLAYING;
+       zfile_fclose (inprec_zf);
+       inprec_zf = zfile_fopen_empty (NULL, L"inp");
+       zfile_fwrite (inprec_buffer, header_end2, 1, inprec_zf);
+       uae_u8 *p = inprec_buffer + header_end2;
+       uae_u8 *end = inprec_buffer + inprec_size;
+       while (p < end) {
+               int len = (p[1] << 8) | (p[2] << 0);
+               p[0] &= ~0x80;
+               p += len;
+       }
+       zfile_fwrite (inprec_buffer + header_end2, inprec_size - header_end2, 1, inprec_zf);
+}
+
+void inprec_setposition (int offset, int replaycounter)
+{
+       if (!inprec_buffer)
+               return;
+       replaypos = replaycounter;
+       write_log (L"INPREC: setpos=%d\n", offset);
+       if (offset < header_end || offset > zfile_size (inprec_zf)) {
+               write_log (L"INPREC: buffer corruption. offset=%d, size=%d\n", offset, zfile_size (inprec_zf));
+               gui_message (L"INPREC error");
+       }
+       zfile_fseek (inprec_zf, 0, SEEK_SET);
+       xfree (inprec_buffer);
+       inprec_size = zfile_size (inprec_zf);
+       inprec_buffer = xmalloc (uae_u8, inprec_size);
+       zfile_fread (inprec_buffer, inprec_size, 1, inprec_zf);
+       inprec_p = inprec_plastptr = inprec_buffer + offset;
+       findlast ();
+       input_play = INPREC_PLAY_RERECORD;
+       input_record = INPREC_RECORD_PLAYING;
+       if (currprefs.inprec_autoplay == false)
+               inprec_realtime (false);
+}
+
+static int savedisk (const TCHAR *path, const TCHAR *file, uae_u8 *data, uae_u8 *outdata)
+{
+       int len = 0;
+       TCHAR *fname = utf8u ((const char*)data + 2);
+       if (fname[0]) {
+               TCHAR tmp[MAX_DPATH];
+               TCHAR filename[MAX_DPATH];
+               filename[0] = 0;
+               struct zfile *zf = zfile_fopen (fname, L"rb", ZFD_NORMAL);
+               if (!zf) {
+                       _tcscpy (tmp, path);
+                       _tcscat (tmp, fname);
+                       zf = zfile_fopen (tmp, L"rb", ZFD_NORMAL);
+                       if (!zf)
+                               write_log (L"failed to open '%s'\n", tmp);
+               }
+               if (zf) {
+                       _tcscpy (tmp, path);
+                       _tcscpy (filename, file);
+                       _tcscat (filename, L".");
+                       getfilepart (filename + _tcslen (filename), MAX_DPATH, zfile_getname (zf));
+                       _tcscat (tmp, filename);
+                       struct zfile *zfd = zfile_fopen (tmp, L"wb");
+                       if (zfd) {
+                               int size = zfile_size (zf);
+                               uae_u8 *data = zfile_getdata (zf, 0, size);
+                               zfile_fwrite (data, size, 1, zfd);
+                               zfile_fclose (zfd);
+                               xfree (data);
+                       }
+                       zfile_fclose (zf);
+                       setwriteprotect (fname, data[1] != 0);
+               }
+               if (filename[0]) {
+                       outdata[0] = data[0];
+                       char *fn = uutf8 (filename);
+                       strcpy ((char*)outdata + 2, fn);
+                       xfree (fn);
+                       len = 2 + strlen ((char*)outdata + 2) + 1;
+               }
+       }
+       xfree (fname);
+       return len;
+}
+
+void inprec_save (const TCHAR *filename, const TCHAR *statefilename)
+{
+       TCHAR path[MAX_DPATH], file[MAX_DPATH];
+       if (!inprec_buffer)
+               return;
+       getpathpart (path, sizeof path / sizeof (TCHAR), filename);
+       getfilepart (file, sizeof file / sizeof (TCHAR), filename);
+       struct zfile *zf = zfile_fopen (filename, L"wb", 0);
+       if (zf) {
+               TCHAR fn[MAX_DPATH];
+               uae_u8 *data;
+               data = zfile_getdata (inprec_zf, 0, header_end);
+               zfile_fwrite (data, header_end, 1, zf);
+               xfree (data);
+               getfilepart (fn, MAX_DPATH, statefilename);
+               char *s = uutf8 (fn);
+               zfile_fwrite (s, strlen (s) + 1, 1, zf);
+               int len = zfile_size (inprec_zf) -  header_end2;
+               data = zfile_getdata (inprec_zf, header_end2, len);
+               uae_u8 *p = data;
+               uae_u8 *end = data + len;
+               while (p < end) {
+                       uae_u8 tmp[MAX_DPATH];
+                       int plen = (p[1] << 8) | (p[2] << 0);
+                       int wlen = plen - HEADERSIZE;
+                       memcpy (tmp, p + HEADERSIZE, wlen);
+                       if (p[0] == INPREC_DISKINSERT) {
+                               wlen = savedisk (path, file, p + HEADERSIZE, tmp);
+                       }
+                       if (wlen) {
+                               wlen += HEADERSIZE;
+                               p[1] = wlen >> 8;
+                               p[2] = wlen;
+                               zfile_fwrite (p, HEADERSIZE, 1, zf);
+                               zfile_fwrite (tmp, wlen - HEADERSIZE, 1, zf);
+                       } else {
+                               zfile_fwrite (p, plen, 1, zf);
+                       }
+                       p += plen;
+               }
+               xfree (data);
+               zfile_fclose (zf);
+               write_log (L"inputfile '%s' saved\n", filename);
+       } else {
+               write_log (L"failed to open '%s'\n", filename);
+       }
+}
+
+bool inprec_realtime (void)
+{
+       if (input_record != INPREC_RECORD_PLAYING || input_play != INPREC_PLAY_RERECORD)
+               return false;
+       //clear_inputstate ();
+       return inprec_realtime (false);
+}
+
+void inprec_getstatus (TCHAR *title)
+{
+       TCHAR *p;
+       if (!input_record && !input_play)
+               return;
+       _tcscat (title, L"[");
+       if (input_record) {
+               if (input_record != INPREC_RECORD_PLAYING)
+                       _tcscat (title, L"-REC-");
+               else
+                       _tcscat (title, L"REPLAY");
+       } else if (input_play) {
+               _tcscat (title, L"PLAY-");
+       }
+       _tcscat (title, L" ");
+       p = title + _tcslen (title);
+       int mvp = current_maxvpos ();
+       _stprintf (p, L"%03d %02d:%02d:%02d/%02d:%02d:%02d", replaypos,
+               lasthsync / (vblank_hz * mvp * 60), (lasthsync / (vblank_hz * mvp) % 60), (lasthsync / mvp) % vblank_hz,
+               endhsync / (vblank_hz * mvp * 60), (endhsync / (vblank_hz * mvp) % 60), (endhsync / mvp) % vblank_hz);
+       p += _tcslen (p);
+       _tcscat (p, L"] ");
+
+}
index d3edb3f3587057944598f80c15199820b0d8bb88..9ce9930795ff1cb915de520acff777e816fea1fb 100644 (file)
@@ -48,7 +48,7 @@ int get_next_key (void)
 
 int record_key (int kc)
 {
-       if (input_recording < 0 || pause_emulation)
+       if (pause_emulation)
                return 0;
        return record_key_direct (kc);
 }
@@ -73,12 +73,6 @@ int record_key_direct (int kc)
                kc ^= AK_CTRL << 1;
        }
 
-       if (input_recording > 0) {
-               inprec_rstart(INPREC_KEY);
-               inprec_ru8(kc);
-               inprec_rend();
-       }
-
        keybuf[kpb_first] = kc;
        kpb_first = kpb_next;
        return 1;
@@ -89,24 +83,3 @@ void keybuf_init (void)
        kpb_first = kpb_last = 0;
        inputdevice_updateconfig (&currprefs);
 }
-
-#ifdef SAVESTATE
-
-uae_u8 *save_keyboard (int *len)
-{
-       uae_u8 *dst, *t;
-       dst = t = xmalloc (uae_u8, 8);
-       save_u32 (getcapslockstate () ? 1 : 0);
-       save_u32 (0);
-       *len = 8;
-       return t;
-}
-
-uae_u8 *restore_keyboard (uae_u8 *src)
-{
-       setcapslockstate (restore_u32 ());
-       restore_u32 ();
-       return src;
-}
-
-#endif /* SAVESTATE */
index b8d15de3d5ea5e06f7063ff89e8e291739c8197f..953c592cf610ce30a7ed7c121028df540240c3fc 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -74,9 +74,30 @@ TCHAR warning_buffer[256];
 
 TCHAR optionsfile[256];
 
-int uaerand (void)
+static uae_u32 randseed;
+static int oldhcounter;
+
+uae_u32 uaesrand (uae_u32 seed)
+{
+       oldhcounter = -1;
+       randseed = seed;
+       //randseed = 0x12345678;
+       //write_log (L"seed=%08x\n", randseed);
+       return randseed;
+}
+uae_u32 uaerand (void)
 {
-       return rand ();
+       if (oldhcounter != hsync_counter) {
+               srand (hsync_counter ^ randseed);
+               oldhcounter = hsync_counter;
+       }
+       uae_u32 r = rand ();
+       //write_log (L"rand=%08x\n", r);
+       return r;
+}
+uae_u32 uaerandgetseed (void)
+{
+       return randseed;
 }
 
 void discard_prefs (struct uae_prefs *p, int type)
@@ -401,6 +422,10 @@ static int default_config;
 
 void uae_reset (int hardreset)
 {
+       if (debug_dma) {
+               record_dma_reset ();
+               record_dma_reset ();
+       }
        currprefs.quitstatefile[0] = changed_prefs.quitstatefile[0] = 0;
 
        if (quit_program == 0) {
index 4763d6d008d0972c55064516b81d6ba5b3129066..fdf912004e67745ad949e9bbd550cd66f43d83eb 100644 (file)
@@ -2326,7 +2326,7 @@ void map_overlay (int chip)
                map_banks (rb, 0, size, 0x80000);
        }
        fill_ce_banks ();
-       if (savestate_state != STATE_RESTORE && savestate_state != STATE_REWIND && valid_address (regs.pc, 4))
+       if (!isrestore () && valid_address (regs.pc, 4))
                m68k_setpc (m68k_getpc ());
 }
 
index 31be1dccd3c7944fba3d221a4dec0e2c2d71a2a8..08bd48825432ceaae4f48b83a6283b9bdb71e92a 100644 (file)
@@ -31,7 +31,7 @@
 #include "ar.h"
 #include "gayle.h"
 #include "cia.h"
-#include "inputdevice.h"
+#include "inputrecord.h"
 #ifdef JIT
 #include "jit/compemu.h"
 #include <signal.h>
@@ -53,12 +53,12 @@ static uaecptr last_fault_for_exception_3;
 static int last_writeaccess_for_exception_3;
 /* instruction (1) or data (0) access */
 static int last_instructionaccess_for_exception_3;
-unsigned long irqcycles[15];
-int irqdelay[15];
 int mmu_enabled, mmu_triggered;
 int cpu_cycles;
 static int baseclock;
+
 int cpucycleunit;
+int cpu_tracer;
 
 const int areg_byteinc[] = { 1, 1, 1, 1, 1, 1, 1, 2 };
 const int imm8_table[] = { 8, 1, 2, 3, 4, 5, 6, 7 };
@@ -136,22 +136,492 @@ void dump_counts (void)
 }
 #endif
 
+/*
+
+ ok, all this to "record" current instruction state
+ for later 100% cycle-exact restoring
+
+ */
+
+static uae_u32 (*x2_prefetch)(int);
+static uae_u32 (*x2_prefetch_long)(int);
+static uae_u32 (*x2_next_iword)(void);
+static uae_u32 (*x2_next_ilong)(void);
+static uae_u32 (*x2_get_ilong)(int);
+static uae_u32 (*x2_get_iword)(int);
+static uae_u32 (*x2_get_ibyte)(int);
+static uae_u32 (*x2_get_long)(uaecptr);
+static uae_u32 (*x2_get_word)(uaecptr);
+static uae_u32 (*x2_get_byte)(uaecptr);
+static void (*x2_put_long)(uaecptr,uae_u32);
+static void (*x2_put_word)(uaecptr,uae_u32);
+static void (*x2_put_byte)(uaecptr,uae_u32);
+static void (*x2_do_cycles)(unsigned long);
+static void (*x2_do_cycles_pre)(unsigned long);
+static void (*x2_do_cycles_post)(unsigned long, uae_u32);
 
 uae_u32 (*x_prefetch)(int);
+uae_u32 (*x_prefetch_long)(int);
 uae_u32 (*x_next_iword)(void);
 uae_u32 (*x_next_ilong)(void);
+uae_u32 (*x_get_ilong)(int);
+uae_u32 (*x_get_iword)(int);
+uae_u32 (*x_get_ibyte)(int);
 uae_u32 (*x_get_long)(uaecptr);
 uae_u32 (*x_get_word)(uaecptr);
 uae_u32 (*x_get_byte)(uaecptr);
 void (*x_put_long)(uaecptr,uae_u32);
 void (*x_put_word)(uaecptr,uae_u32);
 void (*x_put_byte)(uaecptr,uae_u32);
+void (*x_do_cycles)(unsigned long);
+void (*x_do_cycles_pre)(unsigned long);
+void (*x_do_cycles_post)(unsigned long, uae_u32);
+
+static struct cputracestruct cputrace;
+
+STATIC_INLINE void clear_trace (void)
+{
+       struct cputracememory *ctm = &cputrace.ctm[cputrace.memoryoffset++];
+       ctm->mode = 0;
+       cputrace.cyclecounter = 0;
+       cputrace.cyclecounter_pre = cputrace.cyclecounter_post = 0;
+}
+static void set_trace (uaecptr addr, int accessmode, int size)
+{
+       struct cputracememory *ctm = &cputrace.ctm[cputrace.memoryoffset++];
+       ctm->addr = addr;
+       ctm->data = 0xdeadf00d;
+       ctm->mode = accessmode | (size << 4);
+       cputrace.cyclecounter_pre = -1;
+       if (accessmode == 1)
+               cputrace.writecounter++;
+       else
+               cputrace.readcounter++;
+}
+static void add_trace (uaecptr addr, uae_u32 val, int accessmode, int size)
+{
+       int mode = accessmode | (size << 4);
+       struct cputracememory *ctm = &cputrace.ctm[cputrace.memoryoffset - 1];
+       ctm->addr = addr;
+       ctm->data = val;
+       if (!ctm->mode) {
+               ctm->mode = mode;
+               if (accessmode == 1)
+                       cputrace.writecounter++;
+               else
+                       cputrace.readcounter++;
+       }
+       cputrace.cyclecounter_pre = cputrace.cyclecounter_post = 0;
+}
+
+
+static void check_trace2 (void)
+{
+       if (cputrace.readcounter || cputrace.writecounter ||
+               cputrace.cyclecounter || cputrace.cyclecounter_pre || cputrace.cyclecounter_post)
+               write_log (L"CPU tracer invalid state during playback!\n");
+}
+
+static bool check_trace (void)
+{
+       if (!cpu_tracer)
+               return true;
+       if (cputrace.readcounter || cputrace.writecounter ||
+               cputrace.cyclecounter || cputrace.cyclecounter_pre || cputrace.cyclecounter_post)
+               return false;
+       x_prefetch = x2_prefetch;
+       x_prefetch_long = x2_prefetch_long;
+       x_get_ilong = x2_get_ilong;
+       x_get_iword = x2_get_iword;
+       x_get_ibyte = x2_get_ibyte;
+       x_next_iword = x2_next_iword;
+       x_next_ilong = x2_next_ilong;
+       x_put_long = x2_put_long;
+       x_put_word = x2_put_word;
+       x_put_byte = x2_put_byte;
+       x_get_long = x2_get_long;
+       x_get_word = x2_get_word;
+       x_get_byte = x2_get_byte;
+       x_do_cycles = x2_do_cycles;
+       x_do_cycles_pre = x2_do_cycles_pre;
+       x_do_cycles_post = x2_do_cycles_post;
+       write_log (L"CPU tracer playback complete\n");
+       cpu_tracer = 0;
+       return true;
+}
+
+static bool get_trace (uaecptr addr, int accessmode, int size, uae_u32 *data)
+{
+       int mode = accessmode | (size << 4);
+       for (int i = 0; i < cputrace.memoryoffset; i++) {
+               struct cputracememory *ctm = &cputrace.ctm[i];
+               if (ctm->addr == addr && ctm->mode == mode) {
+                       ctm->mode = 0;
+                       write_log (L"CPU trace: GET %d: PC=%08x %08x=%08x %d %d %08x/%08x/%08x %d/%d\n",
+                               i, cputrace.pc, addr, ctm->data, accessmode, size,
+                               cputrace.cyclecounter, cputrace.cyclecounter_pre, cputrace.cyclecounter_post,
+                               cputrace.readcounter, cputrace.writecounter);
+                       if (accessmode == 1)
+                               cputrace.writecounter--;
+                       else
+                               cputrace.readcounter--;
+                       if (cputrace.writecounter == 0 && cputrace.readcounter == 0) {
+                               if (cputrace.cyclecounter_post) {
+                                       int c = cputrace.cyclecounter_post;
+                                       cputrace.cyclecounter_post = 0;
+                                       x_do_cycles (c);
+                               } else if (cputrace.cyclecounter_pre) {
+                                       cputrace.cyclecounter_pre = 0;
+                                       check_trace ();
+                                       return true; // argh, need to rerun the memory access..
+                               }
+                       }
+                       check_trace ();
+                       *data = ctm->data;
+                       return false;
+               }
+       }
+       if (cputrace.cyclecounter_post) {
+               int c = cputrace.cyclecounter_post;
+               cputrace.cyclecounter_post = 0;
+               check_trace ();
+               check_trace2 ();
+               x_do_cycles (c);
+               return false;
+       }
+       gui_message (L"CPU trace: GET %08x %d %d NOT FOUND!\n", addr, accessmode, size);
+       check_trace ();
+       *data = 0;
+       return false;
+}
+
+static uae_u32 cputracefunc_x_prefetch (int o)
+{
+       uae_u32 pc = m68k_getpc ();
+       set_trace (pc + o, 2, 2);
+       uae_u32 v = x2_prefetch (o);
+       add_trace (pc + o, v, 2, 2);
+       return v;
+}
+static uae_u32 cputracefunc2_x_prefetch (int o)
+{
+       uae_u32 v;
+       if (get_trace (m68k_getpc () + o, 2, 2, &v)) {
+               v = x2_prefetch (o);
+               check_trace2 ();
+       }
+       return v;
+}
+static uae_u32 cputracefunc_x_prefetch_long (int o)
+{
+       uae_u32 pc = m68k_getpc ();
+       set_trace (pc + o, 2, 4);
+       uae_u32 v = x2_prefetch_long (o);
+       add_trace (pc + o, v, 2, 4);
+       return v;
+}
+static uae_u32 cputracefunc2_x_prefetch_long (int o)
+{
+       uae_u32 v;
+       if (get_trace (m68k_getpc () + o, 2, 4, &v)) {
+               v = x2_prefetch_long (o);
+               check_trace2 ();
+       }
+       return v;
+}
+
+static uae_u32 cputracefunc_x_next_iword (void)
+{
+       uae_u32 pc = m68k_getpc ();
+       set_trace (pc, 2, 2);
+       uae_u32 v = x2_next_iword ();
+       add_trace (pc, v, 2, 2);
+       return v;
+}
+static uae_u32 cputracefunc_x_next_ilong (void)
+{
+       uae_u32 pc = m68k_getpc ();
+       set_trace (pc, 2, 4);
+       uae_u32 v = x2_next_ilong ();
+       add_trace (pc, v, 2, 4);
+       return v;
+}
+static uae_u32 cputracefunc2_x_next_iword (void)
+{
+       uae_u32 v;
+       if (get_trace (m68k_getpc (), 2, 2, &v)) {
+               v = x2_next_iword ();
+               check_trace2 ();
+       }
+       return v;
+}
+static uae_u32 cputracefunc2_x_next_ilong (void)
+{
+       uae_u32 v;
+       if (get_trace (m68k_getpc (), 2, 4, &v)) {
+               v = x2_next_ilong ();
+               check_trace2 ();
+       }
+       return v;
+}
+
+static uae_u32 cputracefunc_x_get_ilong (int o)
+{
+       uae_u32 pc = m68k_getpc ();
+       set_trace (pc + o, 2, 4);
+       uae_u32 v = x2_get_ilong (o);
+       add_trace (pc + o, v, 2, 4);
+       return v;
+}
+static uae_u32 cputracefunc_x_get_iword (int o)
+{
+       uae_u32 pc = m68k_getpc ();
+       set_trace (pc + o, 2, 2);
+       uae_u32 v = x2_get_iword (o);
+       add_trace (pc + o, v, 2, 2);
+       return v;
+}
+static uae_u32 cputracefunc_x_get_ibyte (int o)
+{
+       uae_u32 pc = m68k_getpc ();
+       set_trace (pc + o, 2, 1);
+       uae_u32 v = x2_get_ibyte (o);
+       add_trace (pc + o, v, 2, 1);
+       return v;
+}
+static uae_u32 cputracefunc2_x_get_ilong (int o)
+{
+       uae_u32 v;
+       if (get_trace (m68k_getpc () + o, 2, 4, &v)) {
+               v = x2_get_ilong (o);
+               check_trace2 ();
+       }
+       return v;
+}
+static uae_u32 cputracefunc2_x_get_iword (int o)
+{
+       uae_u32 v;
+       if (get_trace (m68k_getpc () + o, 2, 2, &v)) {
+               v = x2_get_iword (o);
+               check_trace2 ();
+       }
+       return v;
+}
+static uae_u32 cputracefunc2_x_get_ibyte (int o)
+{
+       uae_u32 v;
+       if (get_trace (m68k_getpc () + o, 2, 1, &v)) {
+               v = x2_get_ibyte (o);
+               check_trace2 ();
+       }
+       return v;
+}
+
+static uae_u32 cputracefunc_x_get_long (uaecptr o)
+{
+       set_trace (o, 0, 4);
+       uae_u32 v = x2_get_long (o);
+       add_trace (o, v, 0, 4);
+       return v;
+}
+static uae_u32 cputracefunc_x_get_word (uaecptr o)
+{
+       set_trace (o, 0, 2);
+       uae_u32 v = x2_get_word (o);
+       add_trace (o, v, 0, 2);
+       return v;
+}
+static uae_u32 cputracefunc_x_get_byte (uaecptr o)
+{
+       set_trace (o, 0, 1);
+       uae_u32 v = x2_get_byte (o);
+       add_trace (o, v, 0, 1);
+       return v;
+}
+static uae_u32 cputracefunc2_x_get_long (uaecptr o)
+{
+       uae_u32 v;
+       if (get_trace (o, 0, 4, &v)) {
+               v = x2_get_long (o);
+               check_trace2 ();
+       }
+       return v;
+}
+static uae_u32 cputracefunc2_x_get_word (uaecptr o)
+{
+       uae_u32 v;
+       if (get_trace (o, 0, 2, &v)) {
+               v = x2_get_word (o);
+               check_trace2 ();
+       }
+       return v;
+}
+static uae_u32 cputracefunc2_x_get_byte (uaecptr o)
+{
+       uae_u32 v;
+       if (get_trace (o, 0, 1, &v)) {
+               v = x2_get_byte (o);
+               check_trace2 ();
+       }
+       return v;
+}
 
-// shared memory access functions
+static void cputracefunc_x_put_long (uaecptr o, uae_u32 val)
+{
+       clear_trace ();
+       add_trace (o, val, 1, 4);
+       x2_put_long (o, val);
+}
+static void cputracefunc_x_put_word (uaecptr o, uae_u32 val)
+{
+       clear_trace ();
+       add_trace (o, val, 1, 2);
+       x2_put_word (o, val);
+}
+static void cputracefunc_x_put_byte (uaecptr o, uae_u32 val)
+{
+       clear_trace ();
+       add_trace (o, val, 1, 1);
+       x2_put_byte (o, val);
+}
+static void cputracefunc2_x_put_long (uaecptr o, uae_u32 val)
+{
+       uae_u32 v;
+       if (get_trace (o, 1, 4, &v)) {
+               x2_put_long (o, val);
+               check_trace2 ();
+       }
+       if (v != val)
+               write_log (L"cputracefunc2_x_put_long %d <> %d\n", v, val);
+}
+static void cputracefunc2_x_put_word (uaecptr o, uae_u32 val)
+{
+       uae_u32 v;
+       if (get_trace (o, 1, 2, &v)) {
+               x2_put_word (o, val);
+               check_trace2 ();
+       }
+       if (v != val)
+               write_log (L"cputracefunc2_x_put_word %d <> %d\n", v, val);
+}
+static void cputracefunc2_x_put_byte (uaecptr o, uae_u32 val)
+{
+       uae_u32 v;
+       if (get_trace (o, 1, 1, &v)) {
+               x2_put_byte (o, val);
+               check_trace2 ();
+       }
+       if (v != val)
+               write_log (L"cputracefunc2_x_put_byte %d <> %d\n", v, val);
+}
+
+static void cputracefunc_x_do_cycles (unsigned long cycles)
+{
+       while (cycles >= CYCLE_UNIT) {
+               cputrace.cyclecounter += CYCLE_UNIT;
+               cycles -= CYCLE_UNIT;
+               x2_do_cycles (CYCLE_UNIT);
+       }
+       if (cycles > 0) {
+               cputrace.cyclecounter += cycles;
+               x2_do_cycles (cycles);
+       }
+}
+static void cputracefunc_x_do_cycles_pre (unsigned long cycles)
+{
+       cputrace.cyclecounter_post = 0;
+       cputrace.cyclecounter_pre = 0;
+       while (cycles >= CYCLE_UNIT) {
+               cycles -= CYCLE_UNIT;
+               cputrace.cyclecounter_pre += CYCLE_UNIT;
+               x2_do_cycles (CYCLE_UNIT);
+       }
+       if (cycles > 0) {
+               x2_do_cycles (cycles);
+               cputrace.cyclecounter_pre += cycles;
+       }
+       cputrace.cyclecounter_pre = 0;
+}
+static void cputracefunc_x_do_cycles_post (unsigned long cycles, uae_u32 v)
+{
+       struct cputracememory *ctm = &cputrace.ctm[cputrace.memoryoffset - 1];
+       ctm->data = v;
+       cputrace.cyclecounter_post = 0;
+       cputrace.cyclecounter_pre = 0;
+       while (cycles >= CYCLE_UNIT) {
+               cycles -= CYCLE_UNIT;
+               cputrace.cyclecounter_post += CYCLE_UNIT;
+               x2_do_cycles (CYCLE_UNIT);
+       }
+       if (cycles > 0) {
+               x2_do_cycles (cycles);
+               cputrace.cyclecounter_post += cycles;
+       }
+       cputrace.cyclecounter_post = 0;
+}
+
+static void cputracefunc2_x_do_cycles (unsigned long cycles)
+{
+       if (cputrace.cyclecounter > cycles) {
+               cputrace.cyclecounter -= cycles;
+               return;
+       }
+       cycles -= cputrace.cyclecounter;
+       cputrace.cyclecounter = 0;
+       check_trace ();
+       x_do_cycles = x2_do_cycles;
+       if (cycles > 0)
+               x_do_cycles (cycles);
+}
+static void cputracefunc2_x_do_cycles_pre (unsigned long cycles)
+{
+       if (cputrace.cyclecounter_pre == -1) {
+               cputrace.cyclecounter_pre = 0;
+               check_trace ();
+               check_trace2 ();
+               return;
+       }
+       if (cputrace.cyclecounter_pre > cycles) {
+               cputrace.cyclecounter_pre -= cycles;
+               return;
+       }
+       cycles -= cputrace.cyclecounter_pre;
+       cputrace.cyclecounter_pre = 0;
+       check_trace ();
+       if (cycles > 0)
+               x_do_cycles (cycles);
+}
+static void cputracefunc2_x_do_cycles_post (unsigned long cycles, uae_u32 v)
+{
+       if (cputrace.cyclecounter_post > cycles) {
+               cputrace.cyclecounter_post -= cycles;
+               return;
+       }
+       cycles -= cputrace.cyclecounter_post;
+       cputrace.cyclecounter_post = 0;
+       check_trace ();
+       if (cycles > 0)
+               x_do_cycles (cycles);
+}
+
+static void do_cycles_post (unsigned long cycles, uae_u32 v)
+{
+       do_cycles (cycles);
+}
+static void do_cycles_ce_post (unsigned long cycles, uae_u32 v)
+{
+       do_cycles_ce (cycles);
+}
+
+// indirect memory access functions
 static void set_x_funcs (void)
 {
        if (currprefs.mmu_model) {
                x_prefetch = get_iword_mmu;
+               x_prefetch_long = get_ilong_mmu;
+               x_get_ilong = get_ilong_mmu;
+               x_get_iword = get_iword_mmu;
+               x_get_ibyte = get_ibyte_mmu;
                x_next_iword = next_iword_mmu;
                x_next_ilong = next_ilong_mmu;
                x_put_long = put_long_mmu;
@@ -160,8 +630,68 @@ static void set_x_funcs (void)
                x_get_long = get_long_mmu;
                x_get_word = get_word_mmu;
                x_get_byte = get_byte_mmu;
+               x_do_cycles = do_cycles;
+               x_do_cycles_pre = do_cycles;
+               x_do_cycles_post = do_cycles_post;
+       } else if (currprefs.cpu_model < 68020) {
+               if (currprefs.cpu_cycle_exact) {
+                       x_prefetch = get_word_ce000_prefetch;
+                       x_prefetch_long = NULL;
+                       x_get_ilong = NULL;
+                       x_get_iword = get_wordi_ce000;
+                       x_get_ibyte = NULL;
+                       x_next_iword = NULL;
+                       x_next_ilong = NULL;
+                       x_put_long = put_long_ce000;
+                       x_put_word = put_word_ce000;
+                       x_put_byte = put_byte_ce000;
+                       x_get_long = get_long_ce000;
+                       x_get_word = get_word_ce000;
+                       x_get_byte = get_byte_ce000;
+                       x_do_cycles = do_cycles_ce;
+                       x_do_cycles_pre = do_cycles_ce;
+                       x_do_cycles_post = do_cycles_ce_post;
+               } else if (currprefs.cpu_compatible) {
+                       x_prefetch = get_word_prefetch;
+                       x_prefetch_long = get_long_prefetch;
+                       x_get_ilong = NULL;
+                       x_get_iword = get_iword;
+                       x_get_ibyte = get_ibyte;
+                       x_next_iword = NULL;
+                       x_next_ilong = NULL;
+                       x_put_long = put_long;
+                       x_put_word = put_word;
+                       x_put_byte = put_byte;
+                       x_get_long = get_long;
+                       x_get_word = get_word;
+                       x_get_byte = get_byte;
+                       x_do_cycles = do_cycles;
+                       x_do_cycles_pre = do_cycles;
+                       x_do_cycles_post = do_cycles_post;
+               } else {
+                       x_prefetch = NULL;
+                       x_prefetch_long = NULL;
+                       x_get_ilong = get_ilong;
+                       x_get_iword = get_iword;
+                       x_get_ibyte = get_ibyte;
+                       x_next_iword = next_iword;
+                       x_next_ilong = next_ilong;
+                       x_put_long = put_long;
+                       x_put_word = put_word;
+                       x_put_byte = put_byte;
+                       x_get_long = get_long;
+                       x_get_word = get_word;
+                       x_get_byte = get_byte;
+                       x_do_cycles = do_cycles;
+                       x_do_cycles_pre = do_cycles;
+                       x_do_cycles_post = do_cycles_post;
+               }
        } else if (!currprefs.cpu_cycle_exact) {
-               x_prefetch = get_iword;
+               x_prefetch = NULL;
+               x_prefetch_long = NULL;
+               x_get_ilong = get_ilong;
+               x_get_iword = get_iword;
+               x_get_ibyte = get_ibyte;
                x_next_iword = next_iword;
                x_next_ilong = next_ilong;
                x_put_long = put_long;
@@ -170,18 +700,15 @@ static void set_x_funcs (void)
                x_get_long = get_long;
                x_get_word = get_word;
                x_get_byte = get_byte;
-       } else if (currprefs.cpu_model < 68020) {
-               x_prefetch = NULL;
-               x_next_iword = NULL;
-               x_next_ilong = NULL;
-               x_put_long = put_long_ce;
-               x_put_word = put_word_ce;
-               x_put_byte = put_byte_ce;
-               x_get_long = get_long_ce;
-               x_get_word = get_word_ce;
-               x_get_byte = get_byte_ce;
+               x_do_cycles = do_cycles;
+               x_do_cycles_pre = do_cycles;
+               x_do_cycles_post = do_cycles_post;
        } else if (currprefs.cpu_model == 68020) {
                x_prefetch = get_word_ce020_prefetch;
+               x_prefetch_long = NULL;
+               x_get_ilong = get_long_ce020_prefetch;
+               x_get_iword = get_word_ce020_prefetch;
+               x_get_ibyte = NULL;
                x_next_iword = next_iword_020ce;
                x_next_ilong = next_ilong_020ce;
                x_put_long = put_long_ce020;
@@ -190,8 +717,15 @@ static void set_x_funcs (void)
                x_get_long = get_long_ce020;
                x_get_word = get_word_ce020;
                x_get_byte = get_byte_ce020;
+               x_do_cycles = do_cycles_ce;
+               x_do_cycles_pre = do_cycles_ce;
+               x_do_cycles_post = do_cycles_ce_post;
        } else {
                x_prefetch = get_word_ce030_prefetch;
+               x_prefetch_long = NULL;
+               x_get_ilong = get_long_ce030_prefetch;
+               x_get_iword = get_word_ce030_prefetch;
+               x_get_ibyte = NULL;
                x_next_iword = next_iword_030ce;
                x_next_ilong = next_ilong_030ce;
                x_put_long = put_long_ce030;
@@ -200,16 +734,102 @@ static void set_x_funcs (void)
                x_get_long = get_long_ce030;
                x_get_word = get_word_ce030;
                x_get_byte = get_byte_ce030;
+               x_do_cycles = do_cycles_ce;
+               x_do_cycles_pre = do_cycles_ce;
+               x_do_cycles_post = do_cycles_ce_post;
+       }
+       x2_prefetch = x_prefetch;
+       x2_prefetch_long = x_prefetch_long;
+       x2_get_ilong = x_get_ilong;
+       x2_get_iword = x_get_iword;
+       x2_get_ibyte = x_get_ibyte;
+       x2_next_iword = x_next_iword;
+       x2_next_ilong = x_next_ilong;
+       x2_put_long = x_put_long;
+       x2_put_word = x_put_word;
+       x2_put_byte = x_put_byte;
+       x2_get_long = x_get_long;
+       x2_get_word = x_get_word;
+       x2_get_byte = x_get_byte;
+       x2_do_cycles = x_do_cycles;
+       x2_do_cycles_pre = x_do_cycles_pre;
+       x2_do_cycles_post = x_do_cycles_post;
+
+       if (cpu_tracer > 0) {
+               x_prefetch = cputracefunc_x_prefetch;
+               x_prefetch_long = cputracefunc_x_prefetch_long;
+               x_get_ilong = cputracefunc_x_get_ilong;
+               x_get_iword = cputracefunc_x_get_iword;
+               x_get_ibyte = cputracefunc_x_get_ibyte;
+               x_next_iword = cputracefunc_x_next_iword;
+               x_next_ilong = cputracefunc_x_next_ilong;
+               x_put_long = cputracefunc_x_put_long;
+               x_put_word = cputracefunc_x_put_word;
+               x_put_byte = cputracefunc_x_put_byte;
+               x_get_long = cputracefunc_x_get_long;
+               x_get_word = cputracefunc_x_get_word;
+               x_get_byte = cputracefunc_x_get_byte;
+               x_do_cycles = cputracefunc_x_do_cycles;
+               x_do_cycles_pre = cputracefunc_x_do_cycles_pre;
+               x_do_cycles_post = cputracefunc_x_do_cycles_post;
+       } else if (cpu_tracer < 0) {
+               if (!check_trace ()) {
+                       x_prefetch = cputracefunc2_x_prefetch;
+                       x_prefetch_long = cputracefunc2_x_prefetch_long;
+                       x_get_ilong = cputracefunc2_x_get_ilong;
+                       x_get_iword = cputracefunc2_x_get_iword;
+                       x_get_ibyte = cputracefunc2_x_get_ibyte;
+                       x_next_iword = cputracefunc2_x_next_iword;
+                       x_next_ilong = cputracefunc2_x_next_ilong;
+                       x_put_long = cputracefunc2_x_put_long;
+                       x_put_word = cputracefunc2_x_put_word;
+                       x_put_byte = cputracefunc2_x_put_byte;
+                       x_get_long = cputracefunc2_x_get_long;
+                       x_get_word = cputracefunc2_x_get_word;
+                       x_get_byte = cputracefunc2_x_get_byte;
+                       x_do_cycles = cputracefunc2_x_do_cycles;
+                       x_do_cycles_pre = cputracefunc2_x_do_cycles_pre;
+                       x_do_cycles_post = cputracefunc2_x_do_cycles_post;
+               }
        }
+}
 
+bool can_cpu_tracer (void)
+{
+       return (currprefs.cpu_model == 68000) && currprefs.cpu_cycle_exact;
+}
+
+bool is_cpu_tracer (void)
+{
+       return cpu_tracer > 0;
+}
+bool set_cpu_tracer (bool state)
+{
+       if (cpu_tracer < 0)
+               return false;
+       int old = cpu_tracer;
+       if (input_record)
+               state = true;
+       cpu_tracer = 0;
+       if (state && can_cpu_tracer ()) {
+               cpu_tracer = 1;
+               set_x_funcs ();
+               if (old != cpu_tracer)
+                       write_log (L"CPU tracer enabled\n");
+       }
+       if (old > 0 && state == false) {
+               set_x_funcs ();
+               write_log (L"CPU tracer disabled\n");
+       }
+       return is_cpu_tracer ();
 }
 
 static void set_cpu_caches (void)
 {
        int i;
 
-       for (i = 0; i < CPU_PIPELINE_MAX; i++)
-               regs.prefetch020addr[i] = 0xffffffff;
+       regs.prefetch020addr = 0xffffffff;
+       regs.cacheholdingaddr020 = 0xffffffff;
 
 #ifdef JIT
        if (currprefs.cachesize) {
@@ -275,8 +895,6 @@ STATIC_INLINE void count_instr (unsigned int opcode)
 {
 }
 
-static unsigned long REGPARAM3 op_illg_1 (uae_u32 opcode) REGPARAM;
-
 static unsigned long REGPARAM2 op_illg_1 (uae_u32 opcode)
 {
        op_illg (opcode);
@@ -406,13 +1024,18 @@ static void build_cpufunctbl (void)
        }
 }
 
-void fill_prefetch_slow (void)
+void fill_prefetch (void)
 {
        if (currprefs.mmu_model)
                return;
        regs.ir = x_get_word (m68k_getpc ());
        regs.irc = x_get_word (m68k_getpc () + 2);
 }
+static void fill_prefetch_quick (void)
+{
+       regs.ir = get_word (m68k_getpc ());
+       regs.irc = get_word (m68k_getpc () + 2);
+}
 
 unsigned long cycles_mask, cycles_val;
 
@@ -474,7 +1097,7 @@ void check_prefs_changed_cpu (void)
 
                        prefs_changed_cpu ();
                        if (!currprefs.cpu_compatible && changed_prefs.cpu_compatible)
-                               fill_prefetch_slow ();
+                               fill_prefetch_quick ();
                        build_cpufunctbl ();
                        changed = 1;
        }
@@ -567,8 +1190,6 @@ void init_m68k (void)
 
 struct regstruct regs, mmu_backup_regs;
 struct flag_struct regflags;
-static struct regstruct regs_backup[16];
-static int backup_pointer = 0;
 static long int m68kpc_offset;
 
 #define get_ibyte_1(o) get_byte (regs.pc + (regs.pc_p - regs.pc_oldp) + (o) + 1)
@@ -940,6 +1561,7 @@ uae_u32 REGPARAM2 get_bitfield (uae_u32 src, uae_u32 bdata[2], uae_s32 offset, i
                break;
        default:
                /* Panic? */
+               write_log (L"get_bitfield() can't happen %d\n", (offset + width + 7) >> 3);
                res = 0;
                break;
        }
@@ -970,6 +1592,9 @@ void REGPARAM2 put_bitfield (uae_u32 dst, uae_u32 bdata[2], uae_u32 val, uae_s32
                put_long (dst, bdata[0] | (val >> (offset - 32)));
                put_byte (dst + 4, bdata[1] | (val << (40 - offset)));
                break;
+       default:
+               write_log (L"put_bitfield() can't happen %d\n", (offset + 7) >> 3);
+               break;
        }
 }
 
@@ -1013,6 +1638,7 @@ uae_u32 REGPARAM2 x_get_bitfield (uae_u32 src, uae_u32 bdata[2], uae_s32 offset,
                break;
        default:
                /* Panic? */
+               write_log (L"x_get_bitfield() can't happen %d\n", (offset + width + 7) >> 3);
                res = 0;
                break;
        }
@@ -1040,6 +1666,9 @@ void REGPARAM2 x_put_bitfield (uae_u32 dst, uae_u32 bdata[2], uae_u32 val, uae_s
                x_put_long (dst, bdata[0] | (val >> (offset - 32)));
                x_put_byte (dst + 4, bdata[1] | (val << (40 - offset)));
                break;
+       default:
+               write_log (L"x_put_bitfield() can't happen %d\n", (offset + 7) >> 3);
+               break;
        }
 }
 
@@ -1129,36 +1758,11 @@ uae_u32 REGPARAM2 x_get_disp_ea_020 (uae_u32 base, uae_u32 dp)
        } else {
                v = base + (uae_s32)((uae_s8)dp) + regd;
        }
-       if (cycles)
-               do_cycles_ce020 (cycles);
+       if (cycles && currprefs.cpu_cycle_exact)
+               x_do_cycles (cycles * cpucycleunit);
        return v;
 }
 
-
-uae_u32 REGPARAM3 get_disp_ea_000 (uae_u32 base, uae_u32 dp) REGPARAM
-{
-       int reg = (dp >> 12) & 15;
-       uae_s32 regd = regs.regs[reg];
-#if 1
-       if ((dp & 0x800) == 0)
-               regd = (uae_s32)(uae_s16)regd;
-       return base + (uae_s8)dp + regd;
-#else
-       /* Branch-free code... benchmark this again now that
-       * things are no longer inline.  */
-       uae_s32 regd16;
-       uae_u32 mask;
-       mask = ((dp & 0x800) >> 11) - 1;
-       regd16 = (uae_s32)(uae_s16)regd;
-       regd16 &= mask;
-       mask = ~mask;
-       base += (uae_s8)dp;
-       regd &= mask;
-       regd |= regd16;
-       return base + regd;
-#endif
-}
-
 STATIC_INLINE int in_rom (uaecptr pc)
 {
        return (munge24 (pc) & 0xFFF80000) == 0xF80000;
@@ -1184,7 +1788,7 @@ void REGPARAM2 MakeFromSR (void)
        int olds = regs.s;
 
        if (currprefs.cpu_cycle_exact && currprefs.cpu_model >= 68020) {
-               do_cycles_ce (6 * CYCLE_UNIT);
+               x_do_cycles (6 * CYCLE_UNIT);
                regs.ce020memcycles = 0;
        }
 
@@ -1374,7 +1978,7 @@ Interrupt cycle diagram:
 
 */
 
-static void Exception_ce000 (int nr, uaecptr oldpc)
+static void Exception_ce000 (int nr)
 {
        uae_u32 currpc = m68k_getpc (), newpc;
        int sv = regs.s;
@@ -1390,7 +1994,7 @@ static void Exception_ce000 (int nr, uaecptr oldpc)
        interrupt = nr >= 24 && nr < 24 + 8;
 
        if (start)
-               do_cycles_ce000 (start);
+               x_do_cycles (start * cpucycleunit);
 
        exception_debug (nr);
        MakeSR ();
@@ -1405,40 +2009,40 @@ static void Exception_ce000 (int nr, uaecptr oldpc)
                mode |= last_writeaccess_for_exception_3 ? 0 : 16;
                m68k_areg (regs, 7) -= 14;
                /* fixme: bit3=I/N */
-               put_word_ce (m68k_areg (regs, 7) + 12, last_addr_for_exception_3);
-               put_word_ce (m68k_areg (regs, 7) + 8, regs.sr);
-               put_word_ce (m68k_areg (regs, 7) + 10, last_addr_for_exception_3 >> 16);
-               put_word_ce (m68k_areg (regs, 7) + 6, last_op_for_exception_3);
-               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_ce000 (2);
-               write_log (L"Exception %d (%x) at %x -> %x!\n", nr, oldpc, currpc, get_long (4 * nr));
+               x_put_word (m68k_areg (regs, 7) + 12, last_addr_for_exception_3);
+               x_put_word (m68k_areg (regs, 7) + 8, regs.sr);
+               x_put_word (m68k_areg (regs, 7) + 10, last_addr_for_exception_3 >> 16);
+               x_put_word (m68k_areg (regs, 7) + 6, last_op_for_exception_3);
+               x_put_word (m68k_areg (regs, 7) + 4, last_fault_for_exception_3);
+               x_put_word (m68k_areg (regs, 7) + 0, mode);
+               x_put_word (m68k_areg (regs, 7) + 2, last_fault_for_exception_3 >> 16);
+               x_do_cycles (2 * cpucycleunit);
+               write_log (L"Exception %d (%x) at %x -> %x!\n", nr, last_addr_for_exception_3, currpc, get_long (4 * nr));
                goto kludge_me_do;
        }
        m68k_areg (regs, 7) -= 6;
-       put_word_ce (m68k_areg (regs, 7) + 4, currpc); // write low address
+       x_put_word (m68k_areg (regs, 7) + 4, currpc); // write low address
        if (interrupt) {
                // fetch interrupt vector number
-               nr = get_byte_ce (0x00fffff1 | ((nr - 24) << 1));
-               do_cycles_ce000 (4);
+               nr = x_get_byte (0x00fffff1 | ((nr - 24) << 1));
+               x_do_cycles (4 * cpucycleunit);
        }
-       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
+       x_put_word (m68k_areg (regs, 7) + 0, regs.sr); // write SR
+       x_put_word (m68k_areg (regs, 7) + 2, currpc >> 16); // write high address
 kludge_me_do:
-       newpc = get_word_ce (4 * nr) << 16; // read high address
-       newpc |= get_word_ce (4 * nr + 2); // read low address
+       newpc = x_get_word (4 * nr) << 16; // read high address
+       newpc |= x_get_word (4 * nr + 2); // read low address
        if (newpc & 1) {
                if (nr == 2 || nr == 3)
                        uae_reset (1); /* there is nothing else we can do.. */
                else
-                       exception3 (regs.ir, m68k_getpc (), newpc);
+                       exception3 (regs.ir, newpc);
                return;
        }
        m68k_setpc (newpc);
-       regs.ir = get_word_ce (m68k_getpc ()); // prefetch 1
-       do_cycles_ce000 (2);
-       regs.irc = get_word_ce (m68k_getpc () + 2); // prefetch 2
+       regs.ir = x_get_word (m68k_getpc ()); // prefetch 1
+       x_do_cycles (2 * cpucycleunit);
+       regs.irc = x_get_word (m68k_getpc () + 2); // prefetch 2
 #ifdef JIT
        set_special (SPCFLAG_END_COMPILE);
 #endif
@@ -1446,9 +2050,9 @@ kludge_me_do:
 }
 #endif
 
-static void Exception_mmu (int nr, uaecptr oldpc)
+static void Exception_mmu (int nr)
 {
-       uae_u32 currpc = m68k_getpc (), newpc;
+       uae_u32 newpc;
        int sv = regs.s;
        int i;
 
@@ -1494,7 +2098,7 @@ static void Exception_mmu (int nr, uaecptr oldpc)
                m68k_areg (regs, 7) -= 2;
                put_word_mmu (m68k_areg (regs, 7), 0x7000 + nr * 4);
                m68k_areg (regs, 7) -= 4;
-               put_long_mmu (m68k_areg (regs, 7), oldpc);
+               put_long_mmu (m68k_areg (regs, 7), regs.instruction_pc);
                m68k_areg (regs, 7) -= 2;
                put_word_mmu (m68k_areg (regs, 7), regs.sr);
                goto kludge_me_do;
@@ -1521,12 +2125,11 @@ static void Exception_mmu (int nr, uaecptr oldpc)
                put_word_mmu (m68k_areg (regs, 7), ssw);
                m68k_areg (regs, 7) -= 2;
                put_word_mmu (m68k_areg (regs, 7), 0xb000 + nr * 4);
-               write_log (L"Exception %d (%x) at %x -> %x!\n", nr, oldpc, currpc, get_long (regs.vbr + 4*nr));
 
        } else if (nr ==5 || nr == 6 || nr == 7 || nr == 9) {
 
                m68k_areg (regs, 7) -= 4;
-               put_long_mmu (m68k_areg (regs, 7), oldpc);
+               put_long_mmu (m68k_areg (regs, 7), regs.instruction_pc);
                m68k_areg (regs, 7) -= 2;
                put_word_mmu (m68k_areg (regs, 7), 0x2000 + nr * 4);
 
@@ -1535,7 +2138,7 @@ static void Exception_mmu (int nr, uaecptr oldpc)
                m68k_areg (regs, 7) -= 2;
                put_word_mmu (m68k_areg (regs, 7), nr * 4);
                m68k_areg (regs, 7) -= 4;
-               put_long_mmu (m68k_areg (regs, 7), currpc);
+               put_long_mmu (m68k_areg (regs, 7), regs.instruction_pc);
                m68k_areg (regs, 7) -= 2;
                put_word_mmu (m68k_areg (regs, 7), regs.sr);
                regs.sr |= (1 << 13);
@@ -1551,7 +2154,7 @@ static void Exception_mmu (int nr, uaecptr oldpc)
 
        }
        m68k_areg (regs, 7) -= 4;
-       put_long_mmu (m68k_areg (regs, 7), currpc);
+       put_long_mmu (m68k_areg (regs, 7), regs.instruction_pc);
        m68k_areg (regs, 7) -= 2;
        put_word_mmu (m68k_areg (regs, 7), regs.sr);
 kludge_me_do:
@@ -1560,20 +2163,20 @@ kludge_me_do:
                if (nr == 2 || nr == 3)
                        uae_reset (1); /* there is nothing else we can do.. */
                else
-                       exception3 (regs.ir, m68k_getpc (), newpc);
+                       exception3 (regs.ir, newpc);
                return;
        }
        m68k_setpc (newpc);
 #ifdef JIT
        set_special (SPCFLAG_END_COMPILE);
 #endif
-       fill_prefetch_slow ();
+       fill_prefetch ();
        exception_trace (nr);
 }
 
-static void Exception_normal (int nr, uaecptr oldpc)
+static void Exception_normal (int nr)
 {
-       uae_u32 currpc = m68k_getpc (), newpc;
+       uae_u32 currpc, newpc;
        int sv = regs.s;
 
        if (nr >= 24 && nr < 24 + 8 && currprefs.cpu_model <= 68010)
@@ -1593,13 +2196,13 @@ static void Exception_normal (int nr, uaecptr oldpc)
                        mmu_set_super (regs.s != 0);
        }
        if (currprefs.cpu_model > 68000) {
+               currpc = regs.instruction_pc;
                if (nr == 2 || nr == 3) {
                        int i;
                        if (currprefs.cpu_model >= 68040) {
                                if (nr == 2) {
-                                       // bus error
                                        if (currprefs.mmu_model) {
-
+                                               // 68040 mmu bus error
                                                for (i = 0 ; i < 7 ; i++) {
                                                        m68k_areg (regs, 7) -= 4;
                                                        x_put_long (m68k_areg (regs, 7), 0);
@@ -1625,7 +2228,7 @@ static void Exception_normal (int nr, uaecptr oldpc)
                                                m68k_areg (regs, 7) -= 2;
                                                x_put_word (m68k_areg (regs, 7), 0x7000 + nr * 4);
                                                m68k_areg (regs, 7) -= 4;
-                                               x_put_long (m68k_areg (regs, 7), oldpc);
+                                               x_put_long (m68k_areg (regs, 7), regs.instruction_pc);
                                                m68k_areg (regs, 7) -= 2;
                                                x_put_word (m68k_areg (regs, 7), regs.sr);
                                                newpc = x_get_long (regs.vbr + 4 * nr);
@@ -1633,7 +2236,7 @@ static void Exception_normal (int nr, uaecptr oldpc)
                                                        if (nr == 2 || nr == 3)
                                                                uae_reset (1); /* there is nothing else we can do.. */
                                                        else
-                                                               exception3 (regs.ir, m68k_getpc (), newpc);
+                                                               exception3 (regs.ir, newpc);
                                                        return;
                                                }
                                                m68k_setpc (newpc);
@@ -1645,6 +2248,7 @@ static void Exception_normal (int nr, uaecptr oldpc)
 
                                        } else {
 
+                                               // 68040 bus error (not really, some garbage?)
                                                for (i = 0 ; i < 18 ; i++) {
                                                        m68k_areg (regs, 7) -= 2;
                                                        x_put_word (m68k_areg (regs, 7), 0);
@@ -1664,7 +2268,7 @@ static void Exception_normal (int nr, uaecptr oldpc)
                                                m68k_areg (regs, 7) -= 2;
                                                x_put_word (m68k_areg (regs, 7), 0x7000 + nr * 4);
                                                m68k_areg (regs, 7) -= 4;
-                                               x_put_long (m68k_areg (regs, 7), oldpc);
+                                               x_put_long (m68k_areg (regs, 7), regs.instruction_pc);
                                                m68k_areg (regs, 7) -= 2;
                                                x_put_word (m68k_areg (regs, 7), regs.sr);
                                                goto kludge_me_do;
@@ -1678,7 +2282,7 @@ static void Exception_normal (int nr, uaecptr oldpc)
                                        x_put_word (m68k_areg (regs, 7), 0x2000 + nr * 4);
                                }
                        } else {
-                               // address error
+                               // 68020 address error
                                uae_u16 ssw = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1);
                                ssw |= last_writeaccess_for_exception_3 ? 0 : 0x40;
                                ssw |= 0x20;
@@ -1699,10 +2303,10 @@ static void Exception_normal (int nr, uaecptr oldpc)
                                m68k_areg (regs, 7) -= 2;
                                x_put_word (m68k_areg (regs, 7), 0xb000 + nr * 4);
                        }
-                       write_log (L"Exception %d (%x) at %x -> %x!\n", nr, oldpc, currpc, x_get_long (regs.vbr + 4*nr));
+                       write_log (L"Exception %d (%x) at %x -> %x!\n", nr, regs.instruction_pc, currpc, x_get_long (regs.vbr + 4*nr));
                } else if (nr ==5 || nr == 6 || nr == 7 || nr == 9) {
                        m68k_areg (regs, 7) -= 4;
-                       x_put_long (m68k_areg (regs, 7), oldpc);
+                       x_put_long (m68k_areg (regs, 7), regs.instruction_pc);
                        m68k_areg (regs, 7) -= 2;
                        x_put_word (m68k_areg (regs, 7), 0x2000 + nr * 4);
                } else if (regs.m && nr >= 24 && nr < 32) { /* M + Interrupt */
@@ -1721,18 +2325,22 @@ static void Exception_normal (int nr, uaecptr oldpc)
                        m68k_areg (regs, 7) -= 2;
                        x_put_word (m68k_areg (regs, 7), nr * 4);
                }
-       } else if (nr == 2 || nr == 3) {
-               uae_u16 mode = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1);
-               mode |= last_writeaccess_for_exception_3 ? 0 : 16;
-               m68k_areg (regs, 7) -= 14;
-               /* fixme: bit3=I/N */
-               x_put_word (m68k_areg (regs, 7) + 0, mode);
-               x_put_long (m68k_areg (regs, 7) + 2, last_fault_for_exception_3);
-               x_put_word (m68k_areg (regs, 7) + 6, last_op_for_exception_3);
-               x_put_word (m68k_areg (regs, 7) + 8, regs.sr);
-               x_put_long (m68k_areg (regs, 7) + 10, last_addr_for_exception_3);
-               write_log (L"Exception %d (%x) at %x -> %x!\n", nr, oldpc, currpc, x_get_long (regs.vbr + 4*nr));
-               goto kludge_me_do;
+       } else {
+               currpc = m68k_getpc ();
+               if (nr == 2 || nr == 3) {
+                       // 68000 address error
+                       uae_u16 mode = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1);
+                       mode |= last_writeaccess_for_exception_3 ? 0 : 16;
+                       m68k_areg (regs, 7) -= 14;
+                       /* fixme: bit3=I/N */
+                       x_put_word (m68k_areg (regs, 7) + 0, mode);
+                       x_put_long (m68k_areg (regs, 7) + 2, last_fault_for_exception_3);
+                       x_put_word (m68k_areg (regs, 7) + 6, last_op_for_exception_3);
+                       x_put_word (m68k_areg (regs, 7) + 8, regs.sr);
+                       x_put_long (m68k_areg (regs, 7) + 10, last_addr_for_exception_3);
+                       write_log (L"Exception %d (%x) at %x -> %x!\n", nr, last_fault_for_exception_3, currpc, x_get_long (regs.vbr + 4*nr));
+                       goto kludge_me_do;
+               }
        }
        m68k_areg (regs, 7) -= 4;
        x_put_long (m68k_areg (regs, 7), currpc);
@@ -1744,28 +2352,35 @@ kludge_me_do:
                if (nr == 2 || nr == 3)
                        uae_reset (1); /* there is nothing else we can do.. */
                else
-                       exception3 (regs.ir, m68k_getpc (), newpc);
+                       exception3 (regs.ir, newpc);
                return;
        }
        m68k_setpc (newpc);
 #ifdef JIT
        set_special (SPCFLAG_END_COMPILE);
 #endif
-       fill_prefetch_slow ();
+       fill_prefetch ();
        exception_trace (nr);
 }
 
-void REGPARAM2 Exception (int nr, uaecptr oldpc)
+void REGPARAM2 Exception (int nr)
 {
+       regs.exception = nr;
+       if (cpu_tracer) {
+               cputrace.state = nr;
+       }
+
+       if (currprefs.cachesize)
+               regs.instruction_pc = m68k_getpc ();
 #ifdef CPUEMU_12
        if (currprefs.cpu_cycle_exact && currprefs.cpu_model == 68000)
-               Exception_ce000 (nr, oldpc);
+               Exception_ce000 (nr);
        else
 #endif
                if (currprefs.mmu_model)
-                       Exception_mmu (nr, oldpc);
+                       Exception_mmu (nr);
                else
-                       Exception_normal (nr, oldpc);
+                       Exception_normal (nr);
 
        if (debug_illegal && !in_rom (M68K_GETPC)) {
                int v = nr;
@@ -1774,6 +2389,10 @@ void REGPARAM2 Exception (int nr, uaecptr oldpc)
                        activate_debugger ();
                }
        }
+       regs.exception = 0;
+       if (cpu_tracer) {
+               cputrace.state = 0;
+       }
 }
 
 STATIC_INLINE void do_interrupt (int nr)
@@ -1781,11 +2400,18 @@ STATIC_INLINE void do_interrupt (int nr)
        if (debug_dma)
                record_dma_event (DMA_EVENT_CPUIRQ, current_hpos (), vpos);
 
+       if (inputrecord_debug & 2) {
+               if (input_record > 0)
+                       inprec_recorddebug_cpu (2);
+               else if (input_play > 0)
+                       inprec_playdebug_cpu (2);
+       }
+
        regs.stopped = 0;
        unset_special (SPCFLAG_STOP);
        assert (nr < 8 && nr >= 0);
 
-       Exception (nr + 24, 0);
+       Exception (nr + 24);
 
        regs.intmask = nr;
        doint ();
@@ -1987,11 +2613,11 @@ STATIC_INLINE int div_unsigned (uae_u32 src_hi, uae_u32 src_lo, uae_u32 div, uae
        return 0;
 }
 
-void m68k_divl (uae_u32 opcode, uae_u32 src, uae_u16 extra, uaecptr oldpc)
+void m68k_divl (uae_u32 opcode, uae_u32 src, uae_u16 extra)
 {
 #if defined (uae_s64)
        if (src == 0) {
-               Exception (5, oldpc);
+               Exception (5);
                return;
        }
        if (extra & 0x800) {
@@ -2046,7 +2672,7 @@ void m68k_divl (uae_u32 opcode, uae_u32 src, uae_u16 extra, uaecptr oldpc)
        }
 #else
        if (src == 0) {
-               Exception (5, oldpc);
+               Exception (5);
                return;
        }
        if (extra & 0x800) {
@@ -2220,7 +2846,7 @@ void m68k_reset (int hardreset)
        regs.spcflags = 0;
        regs.ipl = regs.ipl_pin = 0;
 #ifdef SAVESTATE
-       if (savestate_state == STATE_RESTORE || savestate_state == STATE_REWIND) {
+       if (isrestore ()) {
                m68k_setpc (regs.pc);
                SET_XFLG ((regs.sr >> 4) & 1);
                SET_NFLG ((regs.sr >> 3) & 1);
@@ -2295,7 +2921,7 @@ void m68k_reset (int hardreset)
                if (kickstart_rom)
                        regs.pcr |= 2; /* disable FPU */
        }
-       fill_prefetch_slow ();
+       fill_prefetch_quick ();
 }
 
 unsigned long REGPARAM2 op_illg (uae_u32 opcode)
@@ -2308,7 +2934,7 @@ unsigned long REGPARAM2 op_illg (uae_u32 opcode)
        if (cloanto_rom && (opcode & 0xF100) == 0x7100) {
                m68k_dreg (regs, (opcode >> 9) & 7) = (uae_s8)(opcode & 0xFF);
                m68k_incpc (2);
-               fill_prefetch_slow ();
+               fill_prefetch ();
                return 4;
        }
 
@@ -2324,7 +2950,7 @@ unsigned long REGPARAM2 op_illg (uae_u32 opcode)
                        uae_u16 arg = get_iword (2);
                        m68k_incpc (4);
                        ersatz_perform (arg);
-                       fill_prefetch_slow ();
+                       fill_prefetch ();
                        return 4;
                } else if (inrt) {
                        /* User-mode STOP replacement */
@@ -2337,7 +2963,7 @@ unsigned long REGPARAM2 op_illg (uae_u32 opcode)
                /* Calltrap. */
                m68k_incpc (2);
                m68k_handle_trap (opcode & 0xFFF);
-               fill_prefetch_slow ();
+               fill_prefetch ();
                return 4;
        }
 #endif
@@ -2347,7 +2973,7 @@ unsigned long REGPARAM2 op_illg (uae_u32 opcode)
                        write_log (L"B-Trap %x at %x (%p)\n", opcode, pc, regs.pc_p);
                        warned++;
                }
-               Exception (0xB, 0);
+               Exception (0xB);
                //activate_debugger ();
                return 4;
        }
@@ -2356,7 +2982,7 @@ unsigned long REGPARAM2 op_illg (uae_u32 opcode)
                        write_log (L"A-Trap %x at %x (%p)\n", opcode, pc, regs.pc_p);
                        warned++;
                }
-               Exception (0xA, 0);
+               Exception (0xA);
                //activate_debugger();
                return 4;
        }
@@ -2366,7 +2992,7 @@ unsigned long REGPARAM2 op_illg (uae_u32 opcode)
                //activate_debugger();
        }
 
-       Exception (4, 0);
+       Exception (4);
        return 4;
 }
 
@@ -2563,7 +3189,7 @@ static void do_trace (void)
                /* probably never used so why bother */
                /* We can afford this to be inefficient... */
                m68k_setpc (m68k_getpc ());
-               fill_prefetch_slow ();
+               fill_prefetch ();
                opcode = x_get_word (regs.pc);
                if (opcode == 0x4e73                    /* RTE */
                        || opcode == 0x4e74             /* RTD */
@@ -2592,25 +3218,16 @@ static void do_trace (void)
 
 
 // handle interrupt delay (few cycles)
-STATIC_INLINE int time_for_interrupt (void)
+STATIC_INLINE bool time_for_interrupt (void)
 {
-       if (regs.ipl > regs.intmask || regs.ipl == 7) {
-#if 0
-               if (regs.ipl == 3 && current_hpos () < 11) {
-                       write_log (L"%d\n", current_hpos ());
-                       activate_debugger ();
-               }
-#endif
-               return 1;
-       }
-       return 0;
+       return regs.ipl > regs.intmask || regs.ipl == 7;
 }
 
 void doint (void)
 {
        if (currprefs.cpu_cycle_exact) {
                regs.ipl_pin = intlev ();
-               set_special (SPCFLAG_INT);
+               unset_special (SPCFLAG_INT);
                return;
        }
        if (currprefs.cpu_compatible)
@@ -2623,6 +3240,7 @@ void doint (void)
 
 STATIC_INLINE int do_specialties (int cycles)
 {
+               regs.instruction_pc = m68k_getpc ();
 #ifdef ACTION_REPLAY
 #ifdef ACTION_REPLAY_HRTMON
        if ((regs.spcflags & SPCFLAG_ACTION_REPLAY) && hrtmon_flag != ACTION_REPLAY_INACTIVE) {
@@ -2673,21 +3291,21 @@ STATIC_INLINE int do_specialties (int cycles)
                                cycles = 0;
                } else
                        c = 4;
-               do_cycles (c * CYCLE_UNIT);
+               x_do_cycles (c * CYCLE_UNIT);
                if (regs.spcflags & SPCFLAG_COPPER)
                        do_copper ();
        }
 
        if (regs.spcflags & SPCFLAG_DOTRACE)
-               Exception (9, last_trace_ad);
+               Exception (9);
 
        if (regs.spcflags & SPCFLAG_TRAP) {
                unset_special (SPCFLAG_TRAP);
-               Exception (3, 0);
+               Exception (3);
        }
 
        while (regs.spcflags & SPCFLAG_STOP) {
-               do_cycles (currprefs.cpu_cycle_exact ? 2 * CYCLE_UNIT : 4 * CYCLE_UNIT);
+               x_do_cycles (currprefs.cpu_cycle_exact ? 2 * CYCLE_UNIT : 4 * CYCLE_UNIT);
                if (regs.spcflags & SPCFLAG_COPPER)
                        do_copper ();
 
@@ -2900,21 +3518,72 @@ static void m68k_run_1_ce (void)
 {
        struct regstruct *r = &regs;
 
-       ipl_fetch ();
+       if (cpu_tracer < 0) {
+               memcpy (&r->regs, &cputrace.regs, 16 * sizeof (uae_u32));
+               r->ir = cputrace.ir;
+               r->irc = cputrace.irc;
+               r->sr = cputrace.sr;
+               r->usp = cputrace.usp;
+               r->isp = cputrace.isp;
+               r->intmask = cputrace.intmask;
+               r->stopped = cputrace.stopped;
+               m68k_setpc (cputrace.pc);
+               if (cputrace.state > 1)
+                       Exception (cputrace.state);
+               else if (cputrace.state == 1)
+                       (*cpufunctbl[cputrace.opcode])(cputrace.opcode);
+               if (regs.stopped)
+                       set_special (SPCFLAG_STOP);
+               set_cpu_tracer (false);
+               goto cont;
+       }
+
+       set_cpu_tracer (false);
+
        for (;;) {
                uae_u32 opcode = r->ir;
 #if DEBUG_CD32CDTVIO
                out_cd32io (m68k_getpc ());
 #endif
+               if (cpu_tracer) {
+                       memcpy (&cputrace.regs, &r->regs, 16 * sizeof (uae_u32));
+                       cputrace.opcode = opcode;
+                       cputrace.ir = r->ir;
+                       cputrace.irc = r->irc;
+                       cputrace.sr = r->sr;
+                       cputrace.usp = r->usp;
+                       cputrace.isp = r->isp;
+                       cputrace.intmask = r->intmask;
+                       cputrace.stopped = r->stopped;
+                       cputrace.state = 1;
+                       cputrace.pc = m68k_getpc ();
+                       cputrace.memoryoffset = 0;
+                       cputrace.cyclecounter = cputrace.cyclecounter_pre = cputrace.cyclecounter_post = 0;
+                       cputrace.readcounter = cputrace.writecounter = 0;
+               }
+
+               if (inputrecord_debug & 4) {
+                       if (input_record > 0)
+                               inprec_recorddebug_cpu (1);
+                       else if (input_play > 0)
+                               inprec_playdebug_cpu (1);
+               }
+
                (*cpufunctbl[opcode])(opcode);
-               if (r->spcflags) {
+               if (cpu_tracer) {
+                       cputrace.state = 0;
+               }
+cont:
+               if (r->spcflags || time_for_interrupt ()) {
                        if (do_specialties (0))
                                return;
                }
+
                if (!currprefs.cpu_cycle_exact || currprefs.cpu_model > 68000)
                        return;
        }
 }
+
 #endif
 
 #ifdef JIT  /* Completely different run_2 replacement */
@@ -2933,7 +3602,6 @@ void exec_nostats (void)
        for (;;)
        {
                uae_u16 opcode = get_iword (0);
-
                cpu_cycles = (*cpufunctbl[opcode])(opcode);
 
                cpu_cycles &= cycles_mask;
@@ -3014,7 +3682,7 @@ static void m68k_run_2 (void)
 
 #else
 
-static void opcodedebug (uae_u32 pc, uae_u16 opcode)
+static void opcodedebug (uae_u32 pc, uae_u16 opcode, bool full)
 {
        struct mnemolookup *lookup;
        struct instr *dp;
@@ -3034,10 +3702,12 @@ static void opcodedebug (uae_u32 pc, uae_u16 opcode)
        }
        if (!fault) {
                TCHAR buf[100];
-               write_log (L"mmufixup=%d %04x %04x\n", mmufixup[0].reg, regs.wb3_status, regs.mmu_ssw);
+               if (full)
+                       write_log (L"mmufixup=%d %04x %04x\n", mmufixup[0].reg, regs.wb3_status, regs.mmu_ssw);
                m68k_disasm_2 (buf, sizeof buf / sizeof (TCHAR), addr, NULL, 1, NULL, NULL, 0);
                write_log (L"%s\n", buf);
-               m68k_dumpstate (stdout, NULL);
+               if (full)
+                       m68k_dumpstate (stdout, NULL);
        }
 }
 
@@ -3049,7 +3719,7 @@ static void m68k_run_mmu040 (void)
 retry:
        TRY (prb) {
                for (;;) {
-                       pc = regs.fault_pc = m68k_getpc ();
+                       pc = regs.instruction_pc = regs.instruction_pc = m68k_getpc ();
 #if 0
                        static int done;
                        if (pc == 0x16AF94) {
@@ -3075,7 +3745,8 @@ retry:
                                }
                        }
 #endif
-                       opcode = x_prefetch (0);
+
+                       opcode = get_iword_mmu (0);
                        count_instr (opcode);
                        do_cycles (cpu_cycles);
                        cpu_cycles = (*cpufunctbl[opcode])(opcode);
@@ -3089,12 +3760,13 @@ retry:
        } CATCH (prb) {
 
                if (currprefs.mmu_model == 68060) {
-                       regs.fault_pc = pc;
+                       regs.instruction_pc = pc;
                        if (mmufixup[1].reg >= 0) {
                                m68k_areg (regs, mmufixup[1].reg) = mmufixup[1].value;
                                mmufixup[1].reg = -1;
                        }
                } else {
+#if 0
                        if (regs.wb3_status & 0x80) {
                                // movem to memory?
                                if ((opcode & 0xff80) == 0x4880) {
@@ -3102,9 +3774,10 @@ retry:
                                        //write_log (L"MMU_SSW_CM\n");
                                }
                        }
+#endif
                }
 
-               //opcodedebug (regs.fault_pc, opcode);
+               //opcodedebug (pc, opcode, false);
 
                if (mmufixup[0].reg >= 0) {
                        m68k_areg (regs, mmufixup[0].reg) = mmufixup[0].value;
@@ -3112,7 +3785,7 @@ retry:
                }
                //activate_debugger ();
                TRY (prb2) {
-                       Exception (prb, regs.fault_pc);
+                       Exception (prb);
                } CATCH (prb2) {
                        write_log (L"MMU: double bus error, rebooting..\n");
                        regs.tcr = 0;
@@ -3129,21 +3802,71 @@ retry:
 
 /* "cycle exact" 68020/030  */
 #define MAX68020CYCLES 4
+
 static void m68k_run_2ce (void)
 {
        struct regstruct *r = &regs;
        int tmpcycles = MAX68020CYCLES;
 
+       if (cpu_tracer < 0) {
+               memcpy (&r->regs, &cputrace.regs, 16 * sizeof (uae_u32));
+               r->ir = cputrace.ir;
+               r->irc = cputrace.irc;
+               r->sr = cputrace.sr;
+               r->usp = cputrace.usp;
+               r->isp = cputrace.isp;
+               r->intmask = cputrace.intmask;
+               r->stopped = cputrace.stopped;
+               m68k_setpc (cputrace.pc);
+               if (cputrace.state > 1)
+                       Exception (cputrace.state);
+               else if (cputrace.state == 1)
+                       (*cpufunctbl[cputrace.opcode])(cputrace.opcode);
+               if (regs.stopped)
+                       set_special (SPCFLAG_STOP);
+               set_cpu_tracer (false);
+               goto cont;
+       }
+
+       set_cpu_tracer (false);
        ipl_fetch ();
+
        for (;;) {
+               r->instruction_pc = m68k_getpc ();
                uae_u32 opcode = x_prefetch (0);
+
+               if (cpu_tracer) {
+                       memcpy (&cputrace.regs, &r->regs, 16 * sizeof (uae_u32));
+                       cputrace.opcode = opcode;
+                       cputrace.ir = r->ir;
+                       cputrace.irc = r->irc;
+                       cputrace.sr = r->sr;
+                       cputrace.usp = r->usp;
+                       cputrace.isp = r->isp;
+                       cputrace.intmask = r->intmask;
+                       cputrace.stopped = r->stopped;
+                       cputrace.state = 1;
+                       cputrace.pc = m68k_getpc ();
+                       cputrace.memoryoffset = 0;
+                       cputrace.cyclecounter = cputrace.cyclecounter_pre = cputrace.cyclecounter_post = 0;
+                       cputrace.readcounter = cputrace.writecounter = 0;
+               }
+
+               if (inputrecord_debug & 4) {
+                       if (input_record > 0)
+                               inprec_recorddebug_cpu (1);
+                       else if (input_play > 0)
+                               inprec_playdebug_cpu (1);
+               }
+
                (*cpufunctbl[opcode])(opcode);
                if (r->ce020memcycles > 0) {
                        tmpcycles = CYCLE_UNIT * MAX68020CYCLES;
                        do_cycles_ce (r->ce020memcycles);
                        r->ce020memcycles = 0;
                }
-               if (r->spcflags) {
+cont:
+               if (r->spcflags || time_for_interrupt ()) {
                        if (do_specialties (0))
                                return;
                }
@@ -3163,7 +3886,7 @@ static void m68k_run_2p (void)
        struct regstruct *r = &regs;
 
        prefetch_pc = m68k_getpc ();
-       prefetch = get_longi (prefetch_pc);
+       prefetch = x_get_long (prefetch_pc);
        for (;;) {
                uae_u32 opcode;
                uae_u32 pc = m68k_getpc ();
@@ -3172,19 +3895,23 @@ static void m68k_run_2p (void)
                out_cd32io (m68k_getpc ());
 #endif
 
-               do_cycles (cpu_cycles);
+               x_do_cycles (cpu_cycles);
 
-               if (pc == prefetch_pc)
+               if (pc == prefetch_pc) {
                        opcode = prefetch >> 16;
-               else if (pc == prefetch_pc + 2)
+                       regs.instruction_pc = pc;
+               } else if (pc == prefetch_pc + 2) {
+                       regs.instruction_pc = pc + 2;
                        opcode = prefetch & 0xffff;
-               else
-                       opcode = get_wordi (pc);
+               } else {
+                       regs.instruction_pc = pc;
+                       opcode = x_get_word (pc);
+               }
 
                count_instr (opcode);
 
                prefetch_pc = m68k_getpc () + 2;
-               prefetch = get_longi (prefetch_pc);
+               prefetch = x_get_long (prefetch_pc);
                cpu_cycles = (*cpufunctbl[opcode])(opcode);
                cpu_cycles &= cycles_mask;
                cpu_cycles |= cycles_val;
@@ -3251,12 +3978,13 @@ static void exception2_handle (uaecptr addr, uaecptr fault)
        last_fault_for_exception_3 = fault;
        last_writeaccess_for_exception_3 = 0;
        last_instructionaccess_for_exception_3 = 0;
-       Exception (2, m68k_getpc ());
+       Exception (2);
 }
 
 void m68k_go (int may_quit)
 {
        int hardboot = 1;
+       int startup = 1;
 
        if (in_m68k_go || !may_quit) {
                write_log (L"Bug! m68k_go is not reentrant.\n");
@@ -3265,31 +3993,45 @@ void m68k_go (int may_quit)
 
        reset_frame_rate_hack ();
        update_68k_cycles ();
+       start_cycles = 0;
+
+       set_cpu_tracer (false);
 
        in_m68k_go++;
        for (;;) {
                void (*run_func)(void);
+
+               cputrace.state = -1;
+
+               if (currprefs.inprecfile[0] && input_play) {
+                       inprec_open (currprefs.inprecfile, NULL);
+                       changed_prefs.inprecfile[0] = currprefs.inprecfile[0] = 0;
+                       quit_program = 2;
+               }
+               if (input_play || input_record)
+                       inprec_startup ();
+
                if (quit_program > 0) {
                        int hardreset = (quit_program == 3 ? 1 : 0) | hardboot;
                        if (quit_program == 1)
                                break;
+                       int restored = 0;
 
+                       hsync_counter = 0;
+                       vsync_counter = 0;
                        quit_program = 0;
                        hardboot = 0;
 
-                       if (currprefs.inprecfile[0] && currprefs.inprecmode < 0) {
-                               inprec_open (currprefs.inprecfile, currprefs.inprecmode);
-                               changed_prefs.inprecmode = currprefs.inprecmode = 0;
-                               changed_prefs.inprecfile[0] = currprefs.inprecfile[0] = 0;
-                       }
-
 #ifdef SAVESTATE
+                       if (savestate_state == STATE_DORESTORE)
+                               savestate_state = STATE_RESTORE;
                        if (savestate_state == STATE_RESTORE)
                                restore_state (savestate_fname);
                        else if (savestate_state == STATE_REWIND)
                                savestate_rewind ();
 #endif
-                       customreset (hardreset);
+                       set_cycles (start_cycles);
+                       custom_reset (hardreset);
                        m68k_reset (hardreset);
                        if (hardreset) {
                                memory_hardreset ();
@@ -3297,28 +4039,41 @@ void m68k_go (int may_quit)
                        }
 #ifdef SAVESTATE
                        /* We may have been restoring state, but we're done now.  */
-                       if (savestate_state == STATE_RESTORE || savestate_state == STATE_REWIND) {
-                               map_overlay (1);
-                               fill_prefetch_slow (); /* compatibility with old state saves */
+                       if (isrestore ()) {
+                               if (debug_dma) {
+                                       record_dma_reset ();
+                                       record_dma_reset ();
+                               }
+                               savestate_restore_finish ();
                                memory_map_dump ();
+                               startup = 1;
+                               restored = 1;
                        }
-                       savestate_restore_finish ();
 #endif
-                       if (currprefs.inprecfile[0] && currprefs.inprecmode > 0) {
-                               inprec_open (currprefs.inprecfile, currprefs.inprecmode);
-                               changed_prefs.inprecmode = currprefs.inprecmode = 0;
-                               changed_prefs.inprecfile[0] = currprefs.inprecfile[0] = 0;
-                       }
-
-                       fill_prefetch_slow ();
                        if (currprefs.produce_sound == 0)
                                eventtab[ev_audio].active = 0;
-                       handle_active_events ();
-                       if (regs.spcflags)
-                               do_specialties (0);
                        m68k_setpc (regs.pc);
+                       check_prefs_changed_audio ();
+
+                       if (!restored || hsync_counter == 0)
+                               savestate_check ();
+                       if (input_record == INPREC_RECORD_START)
+                               input_record = INPREC_RECORD_NORMAL;
+               } else {
+                       if (input_record == INPREC_RECORD_START) {
+                               input_record = INPREC_RECORD_NORMAL;
+                               savestate_init ();
+                               hsync_counter = 0;
+                               vsync_counter = 0;
+                               savestate_check ();
+                       }
                }
 
+               if (changed_prefs.inprecfile[0] && input_record)
+                       inprec_prepare_record (savestate_fname[0] ? savestate_fname : NULL);
+
+               set_cpu_tracer (false);
+
 #ifdef DEBUGGER
                if (debugging)
                        debug ();
@@ -3347,8 +4102,11 @@ void m68k_go (int may_quit)
                        regs.spcflags |= of & (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE);
                }
 #endif
-       set_x_funcs ();
-       if (mmu_enabled && !currprefs.cachesize) {
+               set_x_funcs ();
+               if (startup)
+                       custom_prepare ();
+               startup = 0;
+               if (mmu_enabled && !currprefs.cachesize) {
                        run_func = m68k_run_mmu;
                } else {
                        run_func = currprefs.cpu_cycle_exact && currprefs.cpu_model == 68000 ? m68k_run_1_ce :
@@ -3901,6 +4659,37 @@ uae_u8 *restore_cpu (uae_u8 *src)
                if (khz > 0 && khz < 800000)
                        currprefs.m68k_speed = changed_prefs.m68k_speed = 0;
        }
+       set_cpu_caches ();
+       if (flags & 0x40000000) {
+               if (model == 68020) {
+                       for (int i = 0; i < CACHELINES020; i++) {
+                               caches020[i].data = restore_u32 ();
+                               caches020[i].tag = restore_u32 ();
+                               caches020[i].valid = restore_u8 () != 0;
+                       }
+                       regs.prefetch020addr = restore_u32 ();
+                       regs.cacheholdingaddr020 = restore_u32 ();
+                       regs.cacheholdingdata020 = restore_u32 ();
+                       for (int i = 0; i < CPU_PIPELINE_MAX; i++)
+                               regs.prefetch020[i] = restore_u16 ();
+               } else if (model == 68030) {
+                       for (int i = 0; i < CACHELINES030; i++) {
+                               for (int j = 0; j < 4; j++) {
+                                       icaches030[i].data[j] = restore_u32 ();
+                                       icaches030[i].valid[j] = restore_u8 () != 0;
+                               }
+                               icaches030[i].tag = restore_u32 ();
+                       }
+                       for (int i = 0; i < CACHELINES030; i++) {
+                               for (int j = 0; j < 4; j++) {
+                                       dcaches030[i].data[j] = restore_u32 ();
+                                       dcaches030[i].valid[j] = restore_u8 () != 0;
+                               }
+                               dcaches030[i].tag = restore_u32 ();
+                       }
+               }
+       }
+
        write_log (L"CPU: %d%s%03d, PC=%08X\n",
                model / 1000, flags & 1 ? L"EC" : L"", model % 1000, regs.pc);
 
@@ -3911,13 +4700,95 @@ void restore_cpu_finish (void)
 {
        init_m68k ();
        m68k_setpc (regs.pc);
-       set_cpu_caches ();
        doint ();
+       fill_prefetch_quick ();
+       set_cycles (start_cycles);
+       events_schedule ();
        if (regs.stopped)
                set_special (SPCFLAG_STOP);
        //activate_debugger ();
 }
 
+uae_u8 *save_cpu_trace (int *len, uae_u8 *dstptr)
+{
+       uae_u8 *dstbak, *dst;
+
+       if (cputrace.state <= 0)
+               return NULL;
+
+       if (dstptr)
+               dstbak = dst = dstptr;
+       else
+               dstbak = dst = xmalloc (uae_u8, 1000);
+
+       save_u32 (2);
+       save_u16 (cputrace.opcode);
+       for (int i = 0; i < 16; i++)
+               save_u32 (cputrace.regs[i]);
+       save_u32 (cputrace.pc);
+       save_u16 (cputrace.irc);
+       save_u16 (cputrace.ir);
+       save_u32 (cputrace.usp);
+       save_u32 (cputrace.isp);
+       save_u16 (cputrace.sr);
+       save_u16 (cputrace.intmask);
+       save_u16 (cputrace.stopped);
+       save_u16 (cputrace.state);
+       save_u32 (cputrace.cyclecounter);
+       save_u32 (cputrace.cyclecounter_pre);
+       save_u32 (cputrace.cyclecounter_post);
+       save_u32 (cputrace.readcounter);
+       save_u32 (cputrace.writecounter);
+       save_u32 (cputrace.memoryoffset);
+       write_log (L"CPUT SAVE: PC=%08x %08x %08x %08x %d %d %d\n",
+               cputrace.pc, cputrace.cyclecounter, cputrace.cyclecounter_pre, cputrace.cyclecounter_post,
+               cputrace.readcounter, cputrace.writecounter, cputrace.memoryoffset);
+       for (int i = 0; i < cputrace.memoryoffset; i++) {
+               save_u32 (cputrace.ctm[i].addr);
+               save_u32 (cputrace.ctm[i].data);
+               save_u32 (cputrace.ctm[i].mode);
+               write_log (L"CPUT%d: %08x %08x %08x\n", i, cputrace.ctm[i].addr, cputrace.ctm[i].data, cputrace.ctm[i].mode);
+       }
+       *len = dst - dstbak;
+       return dstbak;
+}
+
+uae_u8 *restore_cpu_trace (uae_u8 *src)
+{
+       cpu_tracer = 0;
+       cputrace.state = 0;
+       uae_u32 v = restore_u32 ();
+       if (v != 0 && v != 2)
+               return src;
+       cputrace.opcode = restore_u16 ();
+       for (int i = 0; i < 16; i++)
+               cputrace.regs[i] = restore_u32 ();
+       cputrace.pc = restore_u32 ();
+       cputrace.irc = restore_u16 ();
+       cputrace.ir = restore_u16 ();
+       cputrace.usp = restore_u32 ();
+       cputrace.isp = restore_u32 ();
+       cputrace.sr = restore_u16 ();
+       cputrace.intmask = restore_u16 ();
+       cputrace.stopped = restore_u16 ();
+       cputrace.state = restore_u16 ();
+       cputrace.cyclecounter = restore_u32 ();
+       cputrace.cyclecounter_pre = restore_u32 ();
+       cputrace.cyclecounter_post = restore_u32 ();
+       cputrace.readcounter = restore_u32 ();
+       cputrace.writecounter = restore_u32 ();
+       cputrace.memoryoffset = restore_u32 ();
+       for (int i = 0; i < cputrace.memoryoffset; i++) {
+               cputrace.ctm[i].addr = restore_u32 ();
+               cputrace.ctm[i].data = restore_u32 ();
+               cputrace.ctm[i].mode = restore_u32 ();
+       }
+       if (v && cputrace.state)
+               cpu_tracer = -1;
+
+       return src;
+}
+
 uae_u8 *restore_cpu_extra (uae_u8 *src)
 {
        restore_u32 ();
@@ -3975,7 +4846,7 @@ uae_u8 *save_cpu (int *len, uae_u8 *dstptr)
                dstbak = dst = xmalloc (uae_u8, 1000);
        model = currprefs.cpu_model;
        save_u32 (model);                                       /* MODEL */
-       save_u32 (0x80000000 | (currprefs.address_space_24 ? 1 : 0)); /* FLAGS */
+       save_u32 (0x80000000 | 0x40000000 | (currprefs.address_space_24 ? 1 : 0)); /* FLAGS */
        for (i = 0;i < 15; i++)
                save_u32 (regs.regs[i]);                /* D0-D7 A0-A6 */
        save_u32 (m68k_getpc ());                       /* PC */
@@ -4025,6 +4896,33 @@ uae_u8 *save_cpu (int *len, uae_u8 *dstptr)
        }
        save_u32 (khz); // clock rate in KHz: -1 = fastest possible
        save_u32 (0); // spare
+       if (model == 68020) {
+               for (int i = 0; i < CACHELINES020; i++) {
+                       save_u32 (caches020[i].data);
+                       save_u32 (caches020[i].tag);
+                       save_u8 (caches020[i].valid ? 1 : 0);
+               }
+               save_u32 (regs.prefetch020addr);
+               save_u32 (regs.cacheholdingaddr020);
+               save_u32 (regs.cacheholdingdata020);
+               for (int i = 0; i < CPU_PIPELINE_MAX; i++)
+                       save_u16 (regs.prefetch020[i]);
+       } else if (model == 68030) {
+               for (int i = 0; i < CACHELINES030; i++) {
+                       for (int j = 0; j < 4; j++) {
+                               save_u32 (icaches030[i].data[j]);
+                               save_u8 (icaches030[i].valid[j] ? 1 : 0);
+                       }
+                       save_u32 (icaches030[i].tag);
+               }
+               for (int i = 0; i < CACHELINES030; i++) {
+                       for (int j = 0; j < 4; j++) {
+                               save_u32 (dcaches030[i].data[j]);
+                               save_u8 (dcaches030[i].valid[j] ? 1 : 0);
+                       }
+                       save_u32 (dcaches030[i].tag);
+               }
+       }
        *len = dst - dstbak;
        return dstbak;
 }
@@ -4042,7 +4940,7 @@ uae_u8 *save_mmu (int *len, uae_u8 *dstptr)
        else
                dstbak = dst = xmalloc (uae_u8, 1000);
        save_u32 (model);       /* MODEL */
-       save_u32 (0);   /* FLAGS */
+       save_u32 (0);           /* FLAGS */
        *len = dst - dstbak;
        return dstbak;
 }
@@ -4059,29 +4957,32 @@ uae_u8 *restore_mmu (uae_u8 *src)
 
 #endif /* SAVESTATE */
 
-static void exception3f (uae_u32 opcode, uaecptr addr, uaecptr fault, int writeaccess, int instructionaccess)
+static void exception3f (uae_u32 opcode, uaecptr addr, int writeaccess, int instructionaccess)
 {
        if (currprefs.cpu_model >= 68040)
                addr &= ~1;
-       last_addr_for_exception_3 = addr;
-       last_fault_for_exception_3 = fault;
+       if (currprefs.cpu_model <= 68010)
+               last_addr_for_exception_3 = m68k_getpc ();
+       else
+               last_addr_for_exception_3 = regs.instruction_pc;
+       last_fault_for_exception_3 = addr;
        last_op_for_exception_3 = opcode;
        last_writeaccess_for_exception_3 = writeaccess;
        last_instructionaccess_for_exception_3 = instructionaccess;
-       Exception (3, fault);
+       Exception (3);
 }
 
-void exception3 (uae_u32 opcode, uaecptr addr, uaecptr fault)
+void exception3 (uae_u32 opcode, uaecptr addr)
 {
-       exception3f (opcode, addr, fault, 0, 0);
+       exception3f (opcode, addr, 0, 0);
 }
 
-void exception3i (uae_u32 opcode, uaecptr addr, uaecptr fault)
+void exception3i (uae_u32 opcode, uaecptr addr)
 {
-       exception3f (opcode, addr, fault, 0, 1);
+       exception3f (opcode, addr, 0, 1);
 }
 
-void exception2 (uaecptr addr, uaecptr fault)
+void exception2 (uaecptr addr)
 {
        write_log (L"delayed exception2!\n");
        regs.panic_pc = m68k_getpc ();
@@ -4092,7 +4993,7 @@ void exception2 (uaecptr addr, uaecptr fault)
 #ifdef JIT
        set_special (SPCFLAG_END_COMPILE);
 #endif
-       fill_prefetch_slow ();
+       fill_prefetch ();
 }
 
 void cpureset (void)
@@ -4102,7 +5003,7 @@ void cpureset (void)
        uae_u16 ins;
 
        if (currprefs.cpu_compatible || currprefs.cpu_cycle_exact) {
-               customreset (0);
+               custom_reset (0);
                return;
        }
        pc = m68k_getpc ();
@@ -4110,11 +5011,11 @@ void cpureset (void)
                addrbank *b = &get_mem_bank (pc);
                if (b->check (pc, 2 + 2)) {
                        /* We have memory, hope for the best.. */
-                       customreset (0);
+                       custom_reset (0);
                        return;
                }
                write_log (L"M68K RESET PC=%x, rebooting..\n", pc);
-               customreset (0);
+               custom_reset (0);
                m68k_setpc (ksboot);
                return;
        }
@@ -4124,14 +5025,14 @@ void cpureset (void)
                int reg = ins & 7;
                uae_u32 addr = m68k_areg (regs, reg);
                write_log (L"reset/jmp (ax) combination emulated -> %x\n", addr);
-               customreset (0);
+               custom_reset (0);
                if (addr < 0x80000)
                        addr += 0xf80000;
                m68k_setpc (addr - 2);
                return;
        }
        write_log (L"M68K RESET PC=%x, rebooting..\n", pc);
-       customreset (0);
+       custom_reset (0);
        m68k_setpc (ksboot);
 }
 
@@ -4154,9 +5055,9 @@ void m68k_resumestopped (void)
        regs.stopped = 0;
        if (currprefs.cpu_cycle_exact) {
                if (currprefs.cpu_model == 68000)
-                       do_cycles_ce000 (6);
+                       x_do_cycles (6 * cpucycleunit);
        }
-       fill_prefetch_slow ();
+       fill_prefetch ();
        unset_special (SPCFLAG_STOP);
 }
 
@@ -4311,8 +5212,8 @@ STATIC_INLINE void fill_cache040 (uae_u32 addr)
        for (i = 0; i < CACHELINES040; i++) {
                if (c->valid[i] && c->tag[i] == tag) {
                        // cache hit
-                       regs.prefetch020addr[0] = addr;
-                       regs.prefetch020data[0] = c->data[i][lws];
+                       regs.cacheholdingaddr020 = addr;
+                       regs.cacheholdingdata020 = c->data[i][lws];
                        return;
                }
        }
@@ -4327,12 +5228,12 @@ STATIC_INLINE void fill_cache040 (uae_u32 addr)
                        c->data[i][0] = data;
                }
        }
-       regs.prefetch020addr[0] = addr;
-       regs.prefetch020data[0] = data;
+       regs.cacheholdingaddr020 = addr;
+       regs.cacheholdingdata020 = data;
 }
 
 // this one is really simple and easy
-STATIC_INLINE void fill_icache020 (uae_u32 addr, int idx)
+static void fill_icache020 (uae_u32 addr)
 {
        int index;
        uae_u32 tag;
@@ -4345,8 +5246,8 @@ STATIC_INLINE void fill_icache020 (uae_u32 addr, int idx)
        c = &caches020[index];
        if (c->valid && c->tag == tag) {
                // cache hit
-               regs.prefetch020addr[idx] = addr;
-               regs.prefetch020data[idx] = c->data;
+               regs.cacheholdingaddr020 = addr;
+               regs.cacheholdingdata020 = c->data;
                return;
        }
        // cache miss
@@ -4356,38 +5257,35 @@ STATIC_INLINE void fill_icache020 (uae_u32 addr, int idx)
                c->valid = !!(regs.cacr & 1);
                c->data = data;
        }
-       regs.prefetch020addr[idx] = addr;
-       regs.prefetch020data[idx] = data;
+       regs.cacheholdingaddr020 = addr;
+       regs.cacheholdingdata020 = data;
 }
 
 uae_u32 get_word_ce020_prefetch (int o)
 {
        uae_u32 pc = m68k_getpc () + o;
 
-       for (;;) {
-               for (int i = 0; i < 2; i++) {
-                       if (pc == regs.prefetch020addr[0]) {
-                               uae_u32 v = regs.prefetch020data[0] >> 16;
-                               fill_icache020 (regs.prefetch020addr[0] + 4, 1);
-                               return v;
-                       }
-                       if (pc == regs.prefetch020addr[0] + 2) {
-                               uae_u32 v = regs.prefetch020data[0] & 0xffff;
-                               if (regs.prefetch020addr[1] == regs.prefetch020addr[0] + 4) {
-                                       regs.prefetch020addr[0] = regs.prefetch020addr[1];
-                                       regs.prefetch020data[0] = regs.prefetch020data[1];
-                                       fill_icache020 (regs.prefetch020addr[0] + 4, 1);
-                               } else {
-                                       fill_icache020 (pc + 4, 0);
-                                       fill_icache020 (regs.prefetch020addr[0] + 4, 1);
-                               }
-                               return v;
-                       }
-                       regs.prefetch020addr[0] = regs.prefetch020addr[1];
-                       regs.prefetch020data[0] = regs.prefetch020data[1];
-               }
-               fill_icache020 (pc + 0, 0);
-               fill_icache020 (pc + 4, 1);
+       if (pc == regs.prefetch020addr) {
+               uae_u32 v = regs.prefetch020[0];
+               regs.prefetch020[0] = regs.prefetch020[1];
+               regs.prefetch020[1] = regs.prefetch020[2];
+               pc += 4 + 2;
+               if (regs.cacheholdingaddr020 != (pc & ~3))
+                       fill_icache020 (pc);
+               regs.prefetch020[2] = (regs.cacheholdingaddr020 == pc) ? (regs.cacheholdingdata020 >> 16) : (regs.cacheholdingdata020 >> 0);
+               regs.prefetch020addr += 2;
+               return v;
+       } else {
+               regs.prefetch020addr = pc;
+               fill_icache020 (pc);
+               regs.prefetch020[0] = (regs.cacheholdingaddr020 == pc) ? (regs.cacheholdingdata020 >> 16) : (regs.cacheholdingdata020 >> 0);
+               pc += 2;
+               fill_icache020 (pc);
+               regs.prefetch020[1] = (regs.cacheholdingaddr020 == pc) ? (regs.cacheholdingdata020 >> 16) : (regs.cacheholdingdata020 >> 0);
+               pc += 2;
+               fill_icache020 (pc);
+               regs.prefetch020[2] = (regs.cacheholdingaddr020 == pc) ? (regs.cacheholdingdata020 >> 16) : (regs.cacheholdingdata020 >> 0);
+               return get_word_ce020_prefetch (o);
        }
 }
 
@@ -4417,7 +5315,7 @@ STATIC_INLINE void update_cache030 (struct cache030 *c, uae_u32 val, uae_u32 tag
        c->data[lws] = val;
 }
 
-STATIC_INLINE void fill_icache030 (uae_u32 addr, int idx)
+STATIC_INLINE void fill_icache030 (uae_u32 addr)
 {
        int lws;
        uae_u32 tag;
@@ -4425,11 +5323,13 @@ STATIC_INLINE void fill_icache030 (uae_u32 addr, int idx)
        struct cache030 *c;
 
        addr &= ~3;
+       if (addr == regs.cacheholdingaddr020)
+               return;
        c = getcache030 (icaches030, addr, &tag, &lws);
        if (c->valid[lws] && c->tag == tag) {
                // cache hit
-               regs.prefetch020addr[idx] = addr;
-               regs.prefetch020data[idx] = c->data[lws];
+               regs.cacheholdingaddr020 = addr;
+               regs.cacheholdingdata020 = c->data[lws];
                return;
        }
        // cache miss
@@ -4446,8 +5346,8 @@ STATIC_INLINE void fill_icache030 (uae_u32 addr, int idx)
                }
 #endif
        }
-       regs.prefetch020addr[idx] = addr;
-       regs.prefetch020data[idx] = data;
+       regs.cacheholdingaddr020 = addr;
+       regs.cacheholdingdata020 = data;
 }
 
 STATIC_INLINE bool cancache030 (uaecptr addr)
@@ -4599,34 +5499,30 @@ uae_u32 get_word_ce030_prefetch (int o)
 {
        uae_u32 pc = m68k_getpc () + o;
 
-       for (;;) {
-               for (int i = 0; i < 2; i++) {
-                       if (pc == regs.prefetch020addr[0]) {
-                               uae_u32 v = regs.prefetch020data[0] >> 16;
-                               fill_icache030 (regs.prefetch020addr[0] + 4, 1);
-                               return v;
-                       }
-                       if (pc == regs.prefetch020addr[0] + 2) {
-                               uae_u32 v = regs.prefetch020data[0] & 0xffff;
-                               if (regs.prefetch020addr[1] == regs.prefetch020addr[0] + 4) {
-                                       regs.prefetch020addr[0] = regs.prefetch020addr[1];
-                                       regs.prefetch020data[0] = regs.prefetch020data[1];
-                                       fill_icache030 (regs.prefetch020addr[0] + 4, 1);
-                               } else {
-                                       fill_icache030 (pc + 4, 0);
-                                       fill_icache030 (regs.prefetch020addr[0] + 4, 1);
-                               }
-                               return v;
-                       }
-                       regs.prefetch020addr[0] = regs.prefetch020addr[1];
-                       regs.prefetch020data[0] = regs.prefetch020data[1];
-               }
-               fill_icache030 (pc + 0, 0);
-               fill_icache030 (pc + 4, 1);
+       if (pc == regs.prefetch020addr) {
+               uae_u32 v = regs.prefetch020[0];
+               regs.prefetch020[0] = regs.prefetch020[1];
+               regs.prefetch020[1] = regs.prefetch020[2];
+               pc += 4 + 2;
+               fill_icache030 (pc);
+               regs.prefetch020[2] = (regs.cacheholdingaddr020 == pc) ? (regs.cacheholdingdata020 >> 16) : (regs.cacheholdingdata020 >> 0);
+               regs.prefetch020addr += 2;
+               fill_icache030 (pc + 4);
+               return v;
+       } else {
+               regs.prefetch020addr = pc;
+               fill_icache030 (pc);
+               regs.prefetch020[0] = (regs.cacheholdingaddr020 == pc) ? (regs.cacheholdingdata020 >> 16) : (regs.cacheholdingdata020 >> 0);
+               pc += 2;
+               fill_icache030 (pc);
+               regs.prefetch020[1] = (regs.cacheholdingaddr020 == pc) ? (regs.cacheholdingdata020 >> 16) : (regs.cacheholdingdata020 >> 0);
+               pc += 2;
+               fill_icache030 (pc);
+               regs.prefetch020[2] = (regs.cacheholdingaddr020 == pc) ? (regs.cacheholdingdata020 >> 16) : (regs.cacheholdingdata020 >> 0);
+               return get_word_ce030_prefetch (o);
        }
 }
 
-
 void flush_dcache (uaecptr addr, int size)
 {
        if (!currprefs.cpu_cycle_exact)
@@ -4641,21 +5537,6 @@ void flush_dcache (uaecptr addr, int size)
        }
 }
 
-void do_cycles_ce020 (int clocks)
-{
-       do_cycles_ce (clocks * cpucycleunit);
-}
-void do_cycles_ce020_mem (int clocks)
-{
-       regs.ce020memcycles -= clocks * cpucycleunit;
-       do_cycles_ce (clocks * cpucycleunit);
-}
-
-void do_cycles_ce000 (int clocks)
-{
-       do_cycles_ce (clocks * cpucycleunit);
-}
-
 void m68k_do_rte_mmu (uaecptr a7)
 {
        uae_u16 ssr = get_word_mmu (a7 + 8 + 4);
index 15a675b571234372c245d9d97afd8eb4cf90df3c..f508ca798c0f871e7998671f9df8fddc0a38d019 100644 (file)
@@ -1020,5 +1020,5 @@ struct device_functions devicefunc_win32_aspi = {
        L"ASPI",
        open_scsi_bus, close_scsi_bus, open_scsi_device, close_scsi_device, info_device,
        execscsicmd_out, execscsicmd_in, execscsicmd_direct,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, check_isatapi, 0
+       0, 0, 0, 0, 0, 0, 0, 0, 0, check_isatapi, 0, 0
 };
index 0523f68198f20b954fd324201614ef93b77fb439..7126a83601d082dc95f5895df5842adff8c7de55 100644 (file)
@@ -1052,6 +1052,27 @@ static int ismedia (struct dev_info_ioctl *ciw, int unitnum)
        return fetch_geometry (ciw, unitnum, &ciw->di);
 }
 
+static int eject (int unitnum, bool eject)
+{
+       DWORD len;
+       struct dev_info_ioctl *ciw = unitisopen (unitnum);
+
+       if (!ciw)
+               return 0;
+       if (!unitisopen (unitnum))
+               return 0;
+       cdda_stop (ciw);
+       if (!open_createfile (ciw, 0))
+               return 0;
+       int ret = 0;
+       seterrormode (ciw);
+       if (!DeviceIoControl (ciw->h, eject ? IOCTL_STORAGE_EJECT_MEDIA : IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, NULL, 0, &len, NULL)) {
+               ret = 1;
+       }
+       reseterrormode (ciw);
+       return ret;
+}
+
 /* read toc */
 static int ioctl_command_toc (int unitnum, struct cd_toc_head *tocout)
 {
@@ -1374,13 +1395,27 @@ void win32_ioctl_media_change (TCHAR driveletter, int insert)
        }
 }
 
+static int ioctl_scsiemu (int unitnum, uae_u8 *cmd)
+{
+       uae_u8 c = cmd[0];
+       if (c == 0x1b) {
+               int mode = cmd[4] & 3;
+               if (mode == 2)
+                       eject (unitnum, true);
+               else if (mode == 3)
+                       eject (unitnum, false);
+               return 1;
+       }
+       return -1;
+}
+
 struct device_functions devicefunc_win32_ioctl = {
        L"IOCTL",
        open_bus, close_bus, open_device, close_device, info_device,
        0, 0, 0,
        ioctl_command_pause, ioctl_command_stop, ioctl_command_play, ioctl_command_volume, ioctl_command_qcode,
        ioctl_command_toc, ioctl_command_read, ioctl_command_rawread, ioctl_command_write,
-       0, ioctl_ismedia
+       0, ioctl_ismedia, ioctl_scsiemu
 };
 
 #endif
index ec1e35c732990d1ca4842af51aa81d992062c946..8991b7bf92feefabc9ca8d23bebab35bb8318492 100644 (file)
@@ -870,5 +870,5 @@ struct device_functions devicefunc_win32_spti = {
        L"SPTI",
        open_scsi_bus, close_scsi_bus, open_scsi_device, close_scsi_device, info_device,
        execscsicmd_out, execscsicmd_in, execscsicmd_direct,
-       0, 0, 0, 0, 0, 0, 0, 0, 0, check_isatapi, 0
+       0, 0, 0, 0, 0, 0, 0, 0, 0, check_isatapi, 0, 0
 };
index 4b44db241717a9dec808c959393ff6a29650229f..f4a5e9fa0a2d1f02e93c7c845bc054853739a1b3 100644 (file)
 //  5: generate unformatted data
 //  6: generate unformatted data, that changes each revolution
 //  7: directly use source memory buffer supplied with LockImageMemory
-//  8: flakey data is created on one revolution, updated with each lock
+//  8: flakey/weak data is created on one revolution, updated with each lock
 //  9: ...Info.type holds the expected structure type
 // 10: alternate density map as fractions
 // 11: overlap position is in bits
 // 12: tracklen is in bits, and the track buffer is bit sized
+// 13: track overlap or weak data is never updated, just initialized
+// 14: set weak bit generator seed value
 #define DI_LOCK_INDEX    DF_0
 #define DI_LOCK_ALIGN    DF_1
 #define DI_LOCK_DENVAR   DF_2
@@ -31,6 +33,8 @@
 #define DI_LOCK_DENALT   DF_10
 #define DI_LOCK_OVLBIT   DF_11
 #define DI_LOCK_TRKBIT   DF_12
+#define DI_LOCK_NOUPDATE DF_13
+#define DI_LOCK_SETWSEED DF_14
 
 #define CAPS_MAXPLATFORM 4
 #define CAPS_MTRS 5
@@ -112,6 +116,24 @@ struct CapsTrackInfoT1 {
 
 typedef struct CapsTrackInfoT1 *PCAPSTRACKINFOT1;
 
+// disk track information block
+struct CapsTrackInfoT2 {
+       UDWORD type;       // track type
+       UDWORD cylinder;   // cylinder#
+       UDWORD head;       // head#
+       UDWORD sectorcnt;  // available sectors
+       PUBYTE trackbuf;   // track buffer memory 
+       UDWORD tracklen;   // track buffer memory length
+       UDWORD timelen;    // timing buffer length
+       PUDWORD timebuf;   // timing buffer
+       SDWORD overlap;    // overlap position
+       UDWORD startbit;   // start position of the decoding
+       UDWORD wseed;      // weak bit generator data
+       UDWORD weakcnt;    // number of weak data areas
+};
+
+typedef struct CapsTrackInfoT2 *PCAPSTRACKINFOT2;
+
 #pragma pack(pop)
 
 // image type
@@ -122,10 +144,16 @@ enum {
 
 // platform IDs, not about configuration, but intended use
 enum {
-       ciipNA=0,    // invalid platform (dummy entry)
-       ciipAmiga,   // Amiga
-       ciipAtariST, // Atari ST
-       ciipPC       // PC
+       ciipNA=0, // invalid platform (dummy entry)
+       ciipAmiga,
+       ciipAtariST,
+       ciipPC,
+       ciipAmstradCPC,
+       ciipSpectrum,
+       ciipSamCoupe,
+       ciipArchimedes,
+       ciipC64,
+       ciipAtari8
 };
 
 // track type
index b8a458e050e0a5e5a2c6ecdb1e35655e8e4660f7..0fe7059cee0ca28d059637bddabcb3b8cb9297e9 100644 (file)
@@ -10,6 +10,7 @@
 #include "zfile.h"
 #include "gui.h"
 #include "win32.h"
+#include "uae.h"
 
 #include "ComType.h"
 #include "CapsAPI.h"
@@ -18,8 +19,7 @@ static SDWORD caps_cont[4]= {-1, -1, -1, -1};
 static int caps_locked[4];
 static int caps_flags = DI_LOCK_DENVAR|DI_LOCK_DENNOISE|DI_LOCK_NOISE|DI_LOCK_UPDATEFD|DI_LOCK_TYPE|DI_LOCK_OVLBIT;
 static struct CapsVersionInfo cvi;
-static bool oldlib;
-#define LIB_TYPE 1
+static bool oldlib, canseed;
 
 typedef SDWORD (__cdecl* CAPSINIT)(void);
 static CAPSINIT pCAPSInit;
@@ -85,12 +85,13 @@ int caps_init (void)
        pCAPSUnlockAllTracks = (CAPSUNLOCKALLTRACKS)GetProcAddress (h, "CAPSUnlockAllTracks");
        pCAPSGetVersionInfo = (CAPSGETVERSIONINFO)GetProcAddress (h, "CAPSGetVersionInfo");
        init = 1;
-       cvi.type = LIB_TYPE;
+       cvi.type = 1;
        pCAPSGetVersionInfo (&cvi, 0);
        write_log (L"CAPS: library version %d.%d (flags=%08X)\n", cvi.release, cvi.revision, cvi.flag);
        oldlib = (cvi.flag & (DI_LOCK_TRKBIT | DI_LOCK_OVLBIT)) != (DI_LOCK_TRKBIT | DI_LOCK_OVLBIT);
        if (!oldlib)
                caps_flags |= DI_LOCK_TRKBIT | DI_LOCK_OVLBIT;
+       canseed = (cvi.flag & DI_LOCK_SETWSEED) != 0;
        for (i = 0; i < 4; i++)
                caps_cont[i] = pCAPSAddImage ();
        return 1;
@@ -142,7 +143,7 @@ int caps_loadimage (struct zfile *zf, int drv, int *num_tracks)
 
        if (cvi.release < 4) { // pre-4.x bug workaround
                struct CapsTrackInfoT1 cit;
-               cit.type = LIB_TYPE;
+               cit.type = 1;
                if (pCAPSLockTrack ((PCAPSTRACKINFO)&cit, caps_cont[drv], 0, 0, caps_flags) == imgeIncompatible) {
                        if (!notified)
                                notify_user (NUMSG_OLDCAPS);
@@ -195,13 +196,29 @@ static void mfmcopy (uae_u16 *mfm, uae_u8 *data, int len)
        }
 }
 
+static int load (struct CapsTrackInfoT2 *ci, int drv, int track)
+{
+       int flags;
+       
+       ci->type = 1;
+       flags = caps_flags;
+
+       if (canseed) {
+               flags |= DI_LOCK_SETWSEED;
+               ci->type = 2;
+               ci->wseed = uaerand ();
+       }
+       if (pCAPSLockTrack ((PCAPSTRACKINFO)ci, caps_cont[drv], track / 2, track & 1, flags) != imgeOk)
+               return 0;
+       return 1;
+}
+
 int caps_loadrevolution (uae_u16 *mfmbuf, int drv, int track, int *tracklength)
 {
        int len;
-       struct CapsTrackInfoT1 ci;
+       struct CapsTrackInfoT2 ci;
 
-       ci.type = LIB_TYPE;
-       if (pCAPSLockTrack ((PCAPSTRACKINFO)&ci, caps_cont[drv], track / 2, track & 1, caps_flags) != imgeOk)
+       if (!load (&ci, drv, track))
                return 0;
        if (oldlib)
                len = ci.tracklen * 8;
@@ -215,12 +232,11 @@ int caps_loadrevolution (uae_u16 *mfmbuf, int drv, int track, int *tracklength)
 int caps_loadtrack (uae_u16 *mfmbuf, uae_u16 *tracktiming, int drv, int track, int *tracklength, int *multirev, int *gapoffset)
 {
        int len;
-       struct CapsTrackInfoT1 ci;
+       struct CapsTrackInfoT2 ci;
 
-       ci.type = LIB_TYPE;
        if (tracktiming)
                *tracktiming = 0;
-       if (pCAPSLockTrack ((PCAPSTRACKINFO)&ci, caps_cont[drv], track / 2, track & 1, caps_flags) != imgeOk)
+       if (!load (&ci, drv, track))
                return 0;
        *multirev = (ci.type & CTIT_FLAG_FLAKEY) ? 1 : 0;
        if (oldlib) {
index 9c6db138894abefcd549cd0bc41d3f7a05694b0b..9c6988a06925cf8a59b2e3ccdc52d780a1564c31 100644 (file)
@@ -436,7 +436,7 @@ static void ShowMisc(void)
                free(p2);
        }
        for (i = 0; i < 4; i++) {
-               p = p2 = save_disk (i, &len, NULL);
+               p = p2 = save_disk (i, &len, NULL, false);
                ULBS(L"");
                ULBS(L"Drive DF%d: (%s)", i, (p[4] & 2) ? "disabled" : "enabled");
                ULBS(L"ID %08X  Motor %s  Cylinder %2d  MFMPOS %d",
index cc070da858db1d90e98fc6351f0a2693d370b9f0..e29785149528480c85b42966f0b680f6e5387a87 100644 (file)
@@ -137,6 +137,39 @@ int dinput_winmousemode (void)
        return 0;
 }
 
+#if 0
+static LRESULT CALLBACK LowLevelKeyboardProc (int nCode, WPARAM wParam, LPARAM lParam)
+{
+       write_log (L"*");
+       if (nCode >= 0) {
+               KBDLLHOOKSTRUCT *k = (KBDLLHOOKSTRUCT*)lParam;
+               int vk = k->vkCode;
+               int sc = k->scanCode;
+               write_log (L"%02x %02x\n", vk, sc);
+       }
+       return CallNextHookEx (NULL, nCode, wParam, lParam);
+}
+
+static HHOOK kbhook;
+static void lock_kb (void)
+{
+       if (kbhook)
+               return;
+       kbhook = SetWindowsHookEx (WH_KEYBOARD_LL, LowLevelKeyboardProc, hInst, 0);
+       if (!kbhook)
+               write_log (L"SetWindowsHookEx %d\n", GetLastError ());
+       else
+               write_log (L"***************************\n");
+}
+static void unlock_kb (void)
+{
+       if (!kbhook)
+               return;
+       write_log (L"!!!!!!!!!!!!!!!!!!!!!!!!\n");
+       UnhookWindowsHookEx (kbhook);
+       kbhook = NULL;
+}
+#endif
 
 static BYTE ledkeystate[256];
 
@@ -2247,6 +2280,7 @@ static int acquire_kb (int num, int flags)
                set_leds (oldusedleds);
        }
 
+       //lock_kb ();
        setcoop (&di_keyboard[num], DISCL_NOWINKEY | DISCL_FOREGROUND | DISCL_EXCLUSIVE, L"keyboard");
        kb_do_refresh = ~0;
        di_keyboard[num].acquired = -1;
@@ -2292,6 +2326,7 @@ static void unacquire_kb (int num)
                }
 #endif
        }
+       //unlock_kb ();
 }
 
 static int refresh_kb (LPDIRECTINPUTDEVICE8 lpdi, int num)
index 24672cf3117137b44ed0f7b26e5deb8bf0cd9878..8f325089e1d5998933d49c54d90b2e97a1bc12da 100644 (file)
@@ -180,6 +180,10 @@ static struct uae_input_device_kbr_default keytrans[] = {
 static int kb_np[] = { DIK_NUMPAD4, -1, DIK_NUMPAD6, -1, DIK_NUMPAD8, -1, DIK_NUMPAD2, -1, DIK_NUMPAD0, DIK_NUMPAD5, -1, DIK_DECIMAL, DIK_NUMPADENTER, -1, -1 };
 static int kb_ck[] = { DIK_LEFT, -1, DIK_RIGHT, -1, DIK_UP, -1, DIK_DOWN, -1, DIK_RCONTROL, DIK_RMENU, -1, DIK_RSHIFT, -1, -1 };
 static int kb_se[] = { DIK_A, -1, DIK_D, -1, DIK_W, -1, DIK_S, -1, DIK_LMENU, -1, DIK_LSHIFT, -1, -1 };
+static int kb_np3[] = { DIK_NUMPAD4, -1, DIK_NUMPAD6, -1, DIK_NUMPAD8, -1, DIK_NUMPAD2, -1, DIK_NUMPAD0, DIK_NUMPAD5, -1, DIK_DECIMAL, -1, DIK_NUMPADENTER, -1, -1 };
+static int kb_ck3[] = { DIK_LEFT, -1, DIK_RIGHT, -1, DIK_UP, -1, DIK_DOWN, -1, DIK_RCONTROL, -1, DIK_RSHIFT, -1, DIK_RMENU, -1, -1 };
+static int kb_se3[] = { DIK_A, -1, DIK_D, -1, DIK_W, -1, DIK_S, -1, DIK_LMENU, -1, DIK_LSHIFT, -1, DIK_LCONTROL, -1, -1 };
+
 
 static int kb_cd32_np[] = { DIK_NUMPAD4, -1, DIK_NUMPAD6, -1, DIK_NUMPAD8, -1, DIK_NUMPAD2, -1, DIK_NUMPAD0, DIK_NUMPAD5, DIK_NUMPAD1, -1, DIK_DECIMAL, DIK_NUMPAD3, -1, DIK_NUMPAD7, -1, DIK_NUMPAD9, -1, DIK_DIVIDE, -1, DIK_SUBTRACT, -1, DIK_MULTIPLY, -1, -1 };
 static int kb_cd32_ck[] = { DIK_LEFT, -1, DIK_RIGHT, -1, DIK_UP, -1, DIK_DOWN, -1, DIK_RCONTROL, -1, DIK_RMENU, -1, DIK_NUMPAD7, -1, DIK_NUMPAD9, -1, DIK_DIVIDE, -1, DIK_SUBTRACT, -1, DIK_MULTIPLY, -1, -1 };
@@ -192,7 +196,11 @@ static int kb_xa2[] = { DIK_D, -1, DIK_G, -1, DIK_R, -1, DIK_F, -1, DIK_A, -1, D
 static int kb_arcadia[] = { DIK_F2, -1, DIK_1, -1, DIK_2, -1, DIK_5, -1, DIK_6, -1, -1 };
 static int kb_arcadiaxa[] = { DIK_1, -1, DIK_2, -1, DIK_3, -1, DIK_4, -1, DIK_6, -1, DIK_LBRACKET, DIK_LSHIFT, -1, DIK_RBRACKET, -1, DIK_C, -1, DIK_5, -1, DIK_Z, -1, DIK_X, -1, -1 };
 
-static int *kbmaps[] = { kb_np, kb_ck, kb_se, kb_cd32_np, kb_cd32_ck, kb_cd32_se, kb_xa1, kb_xa2, kb_arcadia, kb_arcadiaxa, kb_cdtv };
+static int *kbmaps[] = {
+       kb_np, kb_ck, kb_se, kb_np3, kb_ck3, kb_se3,
+       kb_cd32_np, kb_cd32_ck, kb_cd32_se,
+       kb_xa1, kb_xa2, kb_arcadia, kb_arcadiaxa, kb_cdtv
+};
 
 extern int ispressed (int key);
 
index 3ddb979a7e4c73c791416a8b1df4e8fa3a58cd95..8ebc3d79aa493122f59fd7541ac9578c2f6b09bb 100644 (file)
@@ -382,14 +382,16 @@ int reginitializeinit (const TCHAR *ppath)
        if (!ppath) {
                int ok = 0;
                TCHAR *posn;
-               _tcscpy (path, _wpgmptr);
+               path[0] = 0;
+               GetFullPathName (_wpgmptr, sizeof path / sizeof (TCHAR), path, NULL);
                if (_tcslen (path) > 4 && !_tcsicmp (path + _tcslen (path) - 4, L".exe")) {
                        _tcscpy (path + _tcslen (path) - 3, L"ini");
                        if (GetFileAttributes (path) != INVALID_FILE_ATTRIBUTES)
                                ok = 1;
                }
                if (!ok) {
-                       _tcscpy (path, _wpgmptr);
+                       path[0] = 0;
+                       GetFullPathName (_wpgmptr, sizeof path / sizeof (TCHAR), path, NULL);
                        if((posn = _tcsrchr (path, '\\')))
                                posn[1] = 0;
                        _tcscat (path, L"winuae.ini");
index 400772a883cbf68216f6e543cdc85d73f8f9cf2f..322bdbe01de336498c43b0f4207de5d19398eefb 100644 (file)
 #define IDS_AUTOSCALE_CENTER            365
 #define IDS_AUTOSCALE_MAX               366
 #define IDS_AUTOSCALE_TV                367
+#define IDS_JOYMODE_GAMEPAD             368
+#define IDS_AUTOSCALE_DEFAULT           369
 #define IDS_QS_MODELS                   1000
 #define IDS_QS_MODEL_A500               1001
 #define IDS_QS_MODEL_A500P              1002
 #define IDC_LORES                       1176
 #define IDC_LORES_SMOOTHED              1179
 #define IDC_FLICKERFIXER                1180
+#define IDC_LORES_SMOOTHED2             1181
+#define IDC_AUTORESOLUTION              1181
 #define IDC_FRAMERATE                   1185
 #define IDC_RATETEXT                    1186
 #define IDC_XSIZE                       1187
 #define IDC_HIGHPRIORITY                1530
 #define IDC_MINIMIZED_NOSOUND           1530
 #define IDC_MINIMIZED_PAUSE             1531
-#define IDC_STATE_CAPTURE               1532
+#define IDC_STATEREC_RECORD             1532
 #define IDC_KBLED_USB                   1533
+#define IDC_STATEREC_CAPTURE2           1533
 #define IDC_SER_SHARED                  1553
 #define IDC_SER_CTSRTS                  1554
 #define IDC_SER_DIRECT                  1555
 #define IDC_SAMPLERIPPER_ACTIVATED      1616
 #define IDC_AVIOUTPUT_BORDER_TRIM       1617
 #define IDC_FILTERVZ                    1617
-#define IDC_INPREC_RECORD               1617
 #define IDC_AVIOUTPUT_AUDIO_STATIC      1618
 #define IDC_FILTERHO                    1618
 #define IDC_AVIOUTPUT_VIDEO_STATIC      1619
 #define IDC_FILTERVO                    1619
 #define IDC_AVIOUTPUT_8BIT              1620
-#define IDC_INPREC_PLAY                 1620
 #define IDC_FILTERASPECT                1620
+#define IDC_STATEREC_PLAY               1620
 #define IDC_AVIOUTPUT_24BIT             1621
 #define IDC_FILTERASPECT2               1621
+#define IDC_STATEREC_SAVE               1621
 #define IDC_AVIOUTPUT_WIDTH             1622
 #define IDC_AVIOUTPUT_HEIGHT            1623
 #define IDC_AVIOUTPUT_FRAME             1624
 #define IDC_ACTIVE_PRI                  1644
 #define IDC_MINIMIZED_PRIORITY          1645
 #define IDC_AVIOUTPUT_FRAMELIMITER      1645
-#define IDC_STATE_RATE                  1646
-#define IDC_INPREC_PLAYMODE             1646
-#define IDC_STATE_BUFFERSIZE            1647
+#define IDC_STATEREC_RATE               1646
 #define IDC_SOUNDDRIVESELECT            1647
 #define IDC_PANELTREE                   1647
 #define IDC_AVIOUTPUT_NOSOUNDOUTPUT     1647
 #define IDC_AVIOUTPUT_ORIGINALSIZE2     1650
 #define IDC_SCREENSHOT_ORIGINALSIZE     1650
 #define IDC_SOUNDCARDLIST               1651
+#define IDC_STATE_BUFFERSIZE2           1651
+#define IDC_STATEREC_BUFFERSIZE         1651
 #define IDC_SOUNDFREQ                   1652
+#define IDC_STATEREC_AUTOPLAY           1652
 #define IDC_SOUNDFREQTXT                1653
 #define IDC_PANEL_FRAME                 1653
 #define IDC_SOUNDFILTERTXT              1654
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NO_MFC                     1
 #define _APS_3D_CONTROLS                     1
-#define _APS_NEXT_RESOURCE_VALUE        356
+#define _APS_NEXT_RESOURCE_VALUE        370
 #define _APS_NEXT_COMMAND_VALUE         40050
 #define _APS_NEXT_CONTROL_VALUE         1808
 #define _APS_NEXT_SYMED_VALUE           101
index fd9443ebba651ffd8781b7c8f6ed853cc3028de0..a239e15a005be3db9b8e77ff17a6e265c8075b6c 100644 (file)
@@ -121,7 +121,7 @@ BEGIN
     EDITTEXT        IDC_XSIZE,59,48,48,12,ES_NUMBER\r
     EDITTEXT        IDC_YSIZE,114,48,47,12,ES_NUMBER\r
     GROUPBOX        "Settings",IDC_SETTINGSTEXT,12,73,199,137\r
-    CONTROL         "Blacker than black",IDC_BLACKER_THAN_BLACK,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,19,125,92,10\r
+    CONTROL         "Blacker than black",IDC_BLACKER_THAN_BLACK,"Button",BS_AUTOCHECKBOX | BS_LEFT | WS_TABSTOP,17,125,92,10\r
     LTEXT           "Refresh:",IDC_REFRESHTEXT,18,173,28,8\r
     CONTROL         "Slider1",IDC_FRAMERATE,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,47,168,75,20\r
     EDITTEXT        IDC_RATETEXT,124,172,77,12,ES_CENTER | ES_READONLY\r
@@ -138,7 +138,7 @@ BEGIN
     CONTROL         "",IDC_FRAMERATE2,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,47,188,127,20\r
     EDITTEXT        IDC_RATE2TEXT,175,192,26,12,ES_CENTER | ES_READONLY\r
     COMBOBOX        IDC_RESOLUTIONDEPTH,134,27,46,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP\r
-    CONTROL         "Filtered low resolution",IDC_LORES_SMOOTHED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,125,89,10\r
+    CONTROL         "Filtered low resolution",IDC_LORES_SMOOTHED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,120,125,89,10\r
     COMBOBOX        IDC_SCREENMODE_NATIVE,100,85,102,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP\r
     COMBOBOX        IDC_SCREENMODE_RTG,100,103,102,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP\r
     RTEXT           "Native mode:",IDC_STATIC,19,85,59,15,SS_CENTERIMAGE\r
@@ -146,10 +146,11 @@ BEGIN
     PUSHBUTTON      "Reset to defaults",IDC_DA_RESET,212,218,73,14\r
     RTEXT           "Resolution:",IDC_STATIC,27,152,59,15,SS_CENTERIMAGE\r
     COMBOBOX        IDC_LORES,100,152,102,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP\r
-    CONTROL         "Remove interlace artifacts",IDC_FLICKERFIXER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,139,99,10\r
+    CONTROL         "Remove interlace artifacts",IDC_FLICKERFIXER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,139,99,10\r
     RTEXT           "Windowed:",IDC_STATIC,17,46,40,15,SS_CENTERIMAGE\r
     RTEXT           "Fullscreen:",IDC_STATIC,17,19,40,15,SS_CENTERIMAGE\r
     COMBOBOX        IDC_DISPLAY_BUFFERCNT,187,47,87,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP\r
+    CONTROL         "Resolution autoswitch",IDC_AUTORESOLUTION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,120,139,89,10\r
 END\r
 \r
 IDD_MEMORY DIALOGEX 0, 0, 300, 182\r
@@ -480,32 +481,27 @@ IDD_MISC1 DIALOGEX 0, 0, 300, 237
 STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD\r
 FONT 8, "MS Sans Serif", 0, 0, 0x1\r
 BEGIN\r
-    GROUPBOX        "Miscellaneous Options",IDC_STATIC,8,2,290,136\r
+    GROUPBOX        "Miscellaneous Options",IDC_STATIC,4,2,293,165\r
     CONTROL         "Untrap = middle button",IDC_JULIAN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,19,110,10\r
     CONTROL         "Show GUI on startup",IDC_SHOWGUI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,43,109,10\r
-    CONTROL         "Native OSD",IDC_SHOWLEDS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,138,95,76,10\r
+    CONTROL         "Native on-screen display",IDC_SHOWLEDS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,139,109,10\r
     CONTROL         "Don't show taskbar button",IDC_NOTASKBARBUTTON,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,67,109,10\r
     CONTROL         "Use CTRL-F11 to quit",IDC_CTRLF11,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,55,110,10\r
-    GROUPBOX        "Keyboard LEDs",IDC_STATIC,7,140,85,94\r
-    COMBOBOX        IDC_KBLED1,22,154,56,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
-    COMBOBOX        IDC_KBLED2,22,173,56,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
-    COMBOBOX        IDC_KBLED3,22,193,56,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
-    GROUPBOX        "Logging",IDC_STATIC,97,140,202,25\r
-    CONTROL         "Create log file",IDC_CREATELOGFILE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,107,151,72,10\r
-    CONTROL         "Illegal memory accesses",IDC_ILLEGAL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,189,151,95,10\r
-    GROUPBOX        "State Files",IDC_STATIC,98,167,201,68\r
-    PUSHBUTTON      "Load state...",IDC_DOLOADSTATE,105,180,49,14\r
-    PUSHBUTTON      "Save state...",IDC_DOSAVESTATE,105,208,49,14\r
-    CONTROL         "Enable state recording",IDC_STATE_CAPTURE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,200,182,88,10\r
-    RTEXT           "Recording rate (seconds):",IDC_STATIC,157,199,86,10,SS_CENTERIMAGE | WS_TABSTOP\r
-    COMBOBOX        IDC_STATE_RATE,248,197,38,65,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP\r
-    RTEXT           "Recording buffer (MB):",IDC_STATIC,160,219,83,10,SS_CENTERIMAGE | WS_TABSTOP\r
-    COMBOBOX        IDC_STATE_BUFFERSIZE,248,217,38,65,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP\r
+    GROUPBOX        "Keyboard LEDs",IDC_STATIC,3,207,294,29\r
+    COMBOBOX        IDC_KBLED1,10,218,56,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
+    COMBOBOX        IDC_KBLED2,78,218,56,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
+    COMBOBOX        IDC_KBLED3,145,218,56,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
+    GROUPBOX        "Logging",IDC_STATIC,4,167,151,38\r
+    CONTROL         "Create log file",IDC_CREATELOGFILE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,41,176,72,10\r
+    CONTROL         "Illegal memory accesses",IDC_ILLEGAL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,41,188,95,10\r
+    GROUPBOX        "State Files",IDC_STATIC,162,167,135,38\r
+    PUSHBUTTON      "Load state...",IDC_DOLOADSTATE,175,182,49,14\r
+    PUSHBUTTON      "Save state...",IDC_DOSAVESTATE,235,182,49,14\r
     CONTROL         "Always on top",IDC_ALWAYSONTOP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,79,110,10\r
-    CONTROL         "USB mode",IDC_KBLED_USB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,22,216,64,10\r
+    CONTROL         "USB mode",IDC_KBLED_USB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,217,219,64,10\r
     COMBOBOX        IDC_SCSIMODE,213,26,80,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
-    COMBOBOX        IDC_LANGUAGE,153,117,122,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
-    GROUPBOX        "Language",IDC_STATIC,138,107,154,27\r
+    COMBOBOX        IDC_LANGUAGE,153,144,122,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\r
+    GROUPBOX        "Language",IDC_STATIC,138,134,154,27\r
     CONTROL         "Disable screensaver",IDC_POWERSAVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,91,109,10\r
     COMBOBOX        IDC_DD_SURFACETYPE,213,78,79,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP\r
     RTEXT           "DirectDraw display buffer:",IDC_STATIC,112,79,97,10,SS_CENTERIMAGE\r
@@ -513,7 +509,7 @@ BEGIN
     CONTROL         "Synchronize clock",IDC_CLOCKSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,103,111,10\r
     CONTROL         "Faster RTG [] Enables less accurate custom chipset emulation mode when Picasso96 is enabled.",IDC_FASTERRTG,\r
                     "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,19,115,111,10\r
-    CONTROL         "RTG OSD",IDC_SHOWLEDSRTG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,227,95,63,10\r
+    CONTROL         "RTG on-screen display",IDC_SHOWLEDSRTG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,151,109,10\r
     RTEXT           "Graphics API:",IDC_STATIC,130,62,79,10,SS_CENTERIMAGE\r
     COMBOBOX        IDC_DXMODE,213,60,79,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP\r
     CONTROL         "Minimize when focus is lost",IDC_FOCUSMINIMIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,19,31,110,10\r
@@ -686,11 +682,11 @@ BEGIN
     CONTROL         "A1000 Agnus (8361/8367)",IDC_CS_DIPAGNUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,187,159,107,10\r
 END\r
 \r
-IDD_AVIOUTPUT DIALOGEX 0, 0, 288, 217\r
+IDD_AVIOUTPUT DIALOGEX 0, 0, 288, 236\r
 STYLE DS_LOCALEDIT | DS_SETFONT | DS_CONTROL | WS_CHILD\r
 FONT 8, "MS Sans Serif", 0, 0, 0x1\r
 BEGIN\r
-    GROUPBOX        "Output Properties",IDC_STATIC,5,0,274,126\r
+    GROUPBOX        "Output Properties",IDC_STATIC,5,0,274,115\r
     EDITTEXT        IDC_AVIOUTPUT_FILETEXT,15,15,226,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER,WS_EX_CLIENTEDGE\r
     PUSHBUTTON      "...",IDC_AVIOUTPUT_FILE,249,15,19,12\r
     CONTROL         "Audio",IDC_AVIOUTPUT_AUDIO,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE | BS_FLAT | WS_TABSTOP,15,33,39,14\r
@@ -698,23 +694,28 @@ BEGIN
     CONTROL         "Video",IDC_AVIOUTPUT_VIDEO,"Button",BS_AUTOCHECKBOX | BS_PUSHLIKE | BS_FLAT | WS_TABSTOP,15,50,39,14\r
     CONTROL         "",IDC_AVIOUTPUT_VIDEO_STATIC,"Static",SS_LEFTNOWORDWRAP | SS_CENTERIMAGE | SS_SUNKEN | WS_GROUP,59,51,209,13\r
     CONTROL         "Disable frame rate limit",IDC_AVIOUTPUT_FRAMELIMITER,\r
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,71,122,10\r
-    CONTROL         "AVI output enabled",IDC_AVIOUTPUT_ACTIVATED,"Button",BS_AUTORADIOBUTTON | BS_PUSHLIKE | BS_FLAT,15,103,108,14\r
-    PUSHBUTTON      "Save screenshot",IDC_SCREENSHOT,16,141,77,14\r
-    GROUPBOX        "Ripper",IDC_STATIC,5,127,274,49\r
-    PUSHBUTTON      "Pro Wizard 1.62",IDC_PROWIZARD,192,141,77,14,WS_DISABLED\r
-    CONTROL         "Sample ripper",IDC_SAMPLERIPPER_ACTIVATED,"Button",BS_AUTORADIOBUTTON | BS_PUSHLIKE | BS_FLAT,192,159,77,14\r
-    GROUPBOX        "Input Recorder",IDC_STATIC,5,178,274,33\r
-    CONTROL         "Record",IDC_INPREC_RECORD,"Button",BS_AUTORADIOBUTTON | BS_PUSHLIKE | BS_FLAT,192,190,77,14\r
-    CONTROL         "Playback",IDC_INPREC_PLAY,"Button",BS_AUTORADIOBUTTON | BS_PUSHLIKE | BS_FLAT,16,190,77,14\r
-    CONTROL         "Alt. playback mode",IDC_INPREC_PLAYMODE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,103,192,78,10\r
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,69,122,10\r
+    CONTROL         "AVI output enabled",IDC_AVIOUTPUT_ACTIVATED,"Button",BS_AUTORADIOBUTTON | BS_PUSHLIKE | BS_FLAT,15,94,108,14\r
+    PUSHBUTTON      "Save screenshot",IDC_SCREENSHOT,16,129,77,14\r
+    GROUPBOX        "Ripper",IDC_STATIC,5,115,274,49\r
+    PUSHBUTTON      "Pro Wizard 1.62",IDC_PROWIZARD,192,129,77,14,WS_DISABLED\r
+    CONTROL         "Sample ripper",IDC_SAMPLERIPPER_ACTIVATED,"Button",BS_AUTORADIOBUTTON | BS_PUSHLIKE | BS_FLAT,192,146,77,14\r
+    GROUPBOX        "Re-recorder",IDC_STATIC,5,165,274,70\r
+    CONTROL         "Play recording",IDC_STATEREC_PLAY,"Button",BS_AUTORADIOBUTTON | BS_PUSHLIKE | BS_FLAT,15,177,77,14\r
     CONTROL         "Disable sound output",IDC_AVIOUTPUT_NOSOUNDOUTPUT,\r
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,88,123,10\r
-    CONTROL         "Disable sound sync",IDC_AVIOUTPUT_NOSOUNDSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,147,88,120,10\r
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,81,123,10\r
+    CONTROL         "Disable sound sync",IDC_AVIOUTPUT_NOSOUNDSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,147,81,120,10\r
     CONTROL         "Capture before filtering",IDC_AVIOUTPUT_ORIGINALSIZE,\r
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,147,71,120,10\r
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,147,69,120,10\r
     CONTROL         "Take screenshot before filtering",IDC_SCREENSHOT_ORIGINALSIZE,\r
-                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,160,162,10\r
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,148,162,10\r
+    RTEXT           "Recording rate (seconds):",IDC_STATIC,12,218,86,10,SS_CENTERIMAGE | WS_TABSTOP\r
+    COMBOBOX        IDC_STATEREC_RATE,103,216,38,65,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP\r
+    RTEXT           "Recording buffers:",IDC_STATIC,148,218,75,10,SS_CENTERIMAGE | WS_TABSTOP\r
+    COMBOBOX        IDC_STATEREC_BUFFERSIZE,229,216,38,65,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP\r
+    CONTROL         "Re-recording enabled",IDC_STATEREC_RECORD,"Button",BS_AUTORADIOBUTTON | BS_PUSHLIKE | BS_FLAT,160,177,108,14\r
+    PUSHBUTTON      "Save recording",IDC_STATEREC_SAVE,160,195,108,14\r
+    CONTROL         "Automatic replay",IDC_STATEREC_AUTOPLAY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,200,129,10\r
 END\r
 \r
 IDD_INPUT DIALOGEX 0, 0, 300, 242\r
@@ -1058,8 +1059,8 @@ END
 //\r
 \r
 VS_VERSION_INFO VERSIONINFO\r
- FILEVERSION 2,3,0,0\r
- PRODUCTVERSION 2,3,0,0\r
+ FILEVERSION 2,3,1,0\r
+ PRODUCTVERSION 2,3,1,0\r
  FILEFLAGSMASK 0x3fL\r
 #ifdef _DEBUG\r
  FILEFLAGS 0x1L\r
@@ -1075,12 +1076,12 @@ BEGIN
         BLOCK "040904b0"\r
         BEGIN\r
             VALUE "FileDescription", "WinUAE"\r
-            VALUE "FileVersion", "2.3.0.0"\r
+            VALUE "FileVersion", "2.3.1.0"\r
             VALUE "InternalName", "WinUAE"\r
             VALUE "LegalCopyright", "© 1996-2010 under the GNU Public License (GPL)"\r
             VALUE "OriginalFilename", "WinUAE.exe"\r
             VALUE "ProductName", "WinUAE"\r
-            VALUE "ProductVersion", "2.3.0.0"\r
+            VALUE "ProductVersion", "2.3.1.0"\r
         END\r
     END\r
     BLOCK "VarFileInfo"\r
@@ -1260,6 +1261,10 @@ BEGIN
     BEGIN\r
     END\r
 \r
+    IDD_AVIOUTPUT, DIALOG\r
+    BEGIN\r
+    END\r
+\r
     IDD_INPUT, DIALOG\r
     BEGIN\r
     END\r
@@ -1644,7 +1649,7 @@ BEGIN
     IDS_TABLET_BOTH_CURSORS "Show both cursors"\r
     IDS_TABLET_NATIVE_CURSOR "Show native cursor only"\r
     IDS_TABLET_HOST_CURSOR  "Show host cursor only"\r
-    IDS_AUTOSCALE_DISABLED  "No Autoscaling"\r
+    IDS_AUTOSCALE_DISABLED  "No scaling"\r
     IDS_AUTOSCALE_SCALING   "Automatic scaling"\r
     IDS_AUTOSCALE_RESIZE    "Automatic resize"\r
     IDS_PRINTER_ASCII       "ASCII-Only"\r
@@ -1671,6 +1676,12 @@ BEGIN
     IDS_AUTOSCALE_TV        "Fullscreen (TV)"\r
 END\r
 \r
+STRINGTABLE\r
+BEGIN\r
+    IDS_JOYMODE_GAMEPAD     "Gamepad"\r
+    IDS_AUTOSCALE_DEFAULT   "Default"\r
+END\r
+\r
 #endif    // English resources\r
 /////////////////////////////////////////////////////////////////////////////\r
 \r
index 41b07b35657c70ed0d4916a6761e56350fadcde3..844f39fabe1b3e1fc3c50df26a747c0eef81003a 100644 (file)
@@ -477,7 +477,7 @@ static void set_screenmode (struct RPScreenMode *sm, struct uae_prefs *p)
                        p->gfx_size_fs.height = disp->rect.bottom - disp->rect.top;
                }
 
-               p->gfx_filter = rp_filter_default;
+               //p->gfx_filter = rp_filter_default;
                p->gfx_filter_horiz_zoom_mult = 1000;
                p->gfx_filter_vert_zoom_mult = 1000;
                //p->gfx_filter_autoscale = 0;
@@ -665,12 +665,12 @@ static LRESULT CALLBACK RPHostMsgFunction2 (UINT uMessage, WPARAM wParam, LPARAM
                        TCHAR *s = (TCHAR*)pData;
                        DWORD ret = FALSE;
                        if (s == NULL) {
-                               savestate_initsave (NULL, 0, TRUE);
+                               savestate_initsave (NULL, 0, TRUE, true);
                                return 1;
                        }
                        if (vpos == 0) {
-                               savestate_initsave (L"", 1, TRUE);
-                               save_state (s, L"AF2008");
+                               savestate_initsave (L"", 1, TRUE, true);
+                               save_state (s, L"AmigaForever");
                                ret = 1;
                        } else {
                                //savestate_initsave (s, 1, TRUE);
@@ -825,6 +825,7 @@ void rp_fixup_options (struct uae_prefs *p)
        rp_filter_default = rp_filter = currprefs.gfx_filter;
        if (rp_filter == 0)
                rp_filter = UAE_FILTER_NULL;
+       //p->gfx_api = 0;
 
        fixup_size (p);
        get_screenmode (&sm, p);
index ff568d3c0538847f521bd141552313edc96bd44f..1c94b71ea1e28d07f4595f42820a8ab7ebe2253f 100644 (file)
 #define HAVE_WINDOWS_H 1
 
 #define FSDB_DIR_SEPARATOR '\\'
+#define FSDB_DIR_SEPARATOR_S L"\\"
index f9093e684d9593ffa7bfc2b24a282515d9332812..2d32073d975b56323e3993e321e4185a34362109 100644 (file)
@@ -85,6 +85,7 @@
 #include "direct3d.h"
 #include "clipboard_win32.h"
 #include "blkdev.h"
+#include "inputrecord.h"
 #ifdef RETROPLATFORM
 #include "rp.h"
 #include "cloanto/RetroPlatformIPC.h"
@@ -92,6 +93,7 @@
 
 extern int harddrive_dangerous, do_rdbdump, aspi_allow_all, no_rawinput;
 extern int force_directsound;
+extern int log_a2065, a2065_promiscuous;
 int log_scsi, log_net, uaelib_debug;
 int pissoff_value = 25000;
 unsigned int fpucontrol;
@@ -269,7 +271,7 @@ frame_time_t read_processor_time (void)
 
        cnt++;
        if (cnt > 1000000) {
-               write_log(L"**************\n");
+               write_log (L"**************\n");
                cnt = 0;
        }
 #endif
@@ -463,6 +465,7 @@ static void setmaintitle (HWND hwnd)
                return;
 #endif
        txt[0] = 0;
+       inprec_getstatus (txt);
        if (config_filename[0]) {
                _tcscat (txt, L"[");
                _tcscat (txt, config_filename);
@@ -488,6 +491,11 @@ static void setmaintitle (HWND hwnd)
        SetWindowText (hwnd, txt);
 }
 
+void refreshtitle (void)
+{
+       if (isfullscreen () == 0)
+               setmaintitle (hMainWnd);
+}
 
 #ifndef AVIOUTPUT
 static int avioutput_video = 0;
@@ -562,8 +570,10 @@ void setmouseactive (int active)
 
        if (mouseactive > 0)
                focus = 1;
+
        if (focus) {
                int donotfocus = 0;
+               HWND f = GetFocus ();
                HWND fw = GetForegroundWindow ();
                HWND w1 = hAmigaWnd;
                HWND w2 = hMainWnd;
@@ -572,16 +582,11 @@ void setmouseactive (int active)
                if (rp_isactive ())
                        w3 = rp_getparent ();
 #endif
-               if (isfullscreen () > 0 || (!(fw == w1 || fw == w2))) {
-                       if (SetForegroundWindow (w2) == FALSE) {
-                               if (SetForegroundWindow (w1) == FALSE) {
-                                       if (w3 == NULL || SetForegroundWindow (w3) == FALSE) {
-                                               donotfocus = 1;
-                                               write_log (L"wanted focus but SetForegroundWindow() failed\n");
-                                       }
-                               }
-                       }
-               }
+               if (f != w1 && f != w2)
+                       donotfocus = 1;
+               if (w3 != NULL && f == w3)
+                       donotfocus = 0;
+
 #ifdef RETROPLATFORM
                if (rp_isactive () && isfullscreen () == 0)
                        donotfocus = 0;
@@ -589,10 +594,11 @@ void setmouseactive (int active)
                if (isfullscreen () > 0)
                        donotfocus = 0;
                if (donotfocus) {
-                       focus = 0;
+                       //focus = 0;
                        mouseactive = 0;
                }
        }
+
        if (mouseactive) {
                if (focus) {
                        if (!showcursor) {
@@ -743,6 +749,7 @@ void minimizewindow (void)
 void disablecapture (void)
 {
        setmouseactive (0);
+       focus = 0;
 }
 
 void gui_gameport_button_change (int port, int button, int onoff)
@@ -1752,6 +1759,7 @@ int handle_msgpump (void)
                TranslateMessage (&msg);
                DispatchMessage (&msg);
        }
+       while (checkIPC (globalipc, &currprefs));
        return got;
 }
 
@@ -1792,11 +1800,13 @@ void handle_events (void)
                if (quit_program)
                        break;
        }
+#if 0
        while (PeekMessage (&msg, 0, 0, 0, PM_REMOVE)) {
                TranslateMessage (&msg);
                DispatchMessage (&msg);
        }
        while (checkIPC (globalipc, &currprefs));
+#endif
        if (was_paused) {
                resumepaused (was_paused);
                sound_closed = 0;
@@ -2293,6 +2303,23 @@ void fullpath (TCHAR *path, int size)
                GetFullPathName (tmp, size, path, NULL);
        }
 }
+void getpathpart (TCHAR *outpath, int size, const TCHAR *inpath)
+{
+       _tcscpy (outpath, inpath);
+       TCHAR *p = _tcsrchr (outpath, '\\');
+       if (p)
+               p[0] = 0;
+       fixtrailing (outpath);
+}
+void getfilepart (TCHAR *out, int size, const TCHAR *path)
+{
+       out[0] = 0;
+       const TCHAR *p = _tcsrchr (path, '\\');
+       if (p)
+               _tcscpy (out, p + 1);
+       else
+               _tcscpy (out, path);
+}
 
 typedef DWORD (STDAPICALLTYPE *PFN_GetKey)(LPVOID lpvBuffer, DWORD dwSize);
 uae_u8 *target_load_keyfile (struct uae_prefs *p, const TCHAR *path, int *sizep, TCHAR *name)
@@ -3063,6 +3090,10 @@ void fetch_statefilepath (TCHAR *out, int size)
 {
        fetch_path (L"StatefilePath", out, size);
 }
+void fetch_inputfilepath (TCHAR *out, int size)
+{
+       fetch_path (L"InputPath", out, size);
+}
 void fetch_datapath (TCHAR *out, int size)
 {
        fetch_path (NULL, out, size);
@@ -4134,7 +4165,7 @@ static void getstartpaths (void)
        if (!_tcscmp (prevpath, L"AMIGAFOREVERDATA"))
                path_type = PATH_TYPE_AMIGAFOREVERDATA;
 
-       _tcscpy (start_path_exe, _wpgmptr);
+       GetFullPathName (_wpgmptr, sizeof start_path_exe / sizeof (TCHAR), start_path_exe, NULL);
        if((posn = _tcsrchr (start_path_exe, '\\')))
                posn[1] = 0;
 
@@ -4156,8 +4187,9 @@ static void getstartpaths (void)
                        ispath = true;
                if (!ispath) {
                        if (SUCCEEDED (SHGetFolderPath (NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, tmp))) {
+                               GetFullPathName (tmp, sizeof tmp / sizeof (TCHAR), tmp2, NULL);
                                // installed in Program Files?
-                               if (_tcsnicmp (tmp, start_path_exe, _tcslen (tmp)) == 0) {
+                               if (_tcsnicmp (tmp, tmp2, _tcslen (tmp)) == 0) {
                                        if (SUCCEEDED (SHGetFolderPath (NULL, CSIDL_COMMON_DOCUMENTS, NULL, SHGFP_TYPE_CURRENT, tmp))) {
                                                fixtrailing (tmp);
                                                _tcscpy (tmp2, tmp);
@@ -4353,7 +4385,9 @@ static TCHAR *getdefaultini (void)
 {
        FILE *f;
        TCHAR path[MAX_DPATH], orgpath[MAX_DPATH];
-       _tcscpy (path, _wpgmptr);
+       path[0] = 0;
+       if (!GetFullPathName (_wpgmptr, sizeof path / sizeof (TCHAR), path, NULL))
+               _tcscpy (path, _wpgmptr);
        TCHAR *posn;
        if((posn = _tcsrchr (path, '\\')))
                posn[1] = 0;
@@ -4453,6 +4487,18 @@ static int parseargs (const TCHAR *argx, const TCHAR *np, const TCHAR *np2)
                log_net = 1;
                return 1;
        }
+       if (!_tcscmp (arg, L"a2065log")) {
+               log_a2065 = 1;
+               return 1;
+       }
+       if (!_tcscmp (arg, L"a2065log2")) {
+               log_a2065 = 2;
+               return 1;
+       }
+       if (!_tcscmp (arg, L"a2065_promiscuous")) {
+               a2065_promiscuous = 1;
+               return 1;
+       }
        if (!_tcscmp (arg, L"seriallog")) {
                log_uaeserial = 1;
                return 1;
@@ -4591,6 +4637,10 @@ static int parseargs (const TCHAR *argx, const TCHAR *np, const TCHAR *np2)
                pissoff_value = getval (np);
                return 2;
        }
+       if (!_tcscmp (arg, L"inputrecorddebug")) {
+               inputrecord_debug = getval (np);
+               return 2;
+       }
 #ifdef RETROPLATFORM
        if (!_tcscmp (arg, L"rphost")) {
                rp_param = my_strdup (np);
@@ -4793,12 +4843,11 @@ static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR
                for (i = 0; argv2[i]; i++)
                        write_log (L"%d: '%s'\n", i + 1, argv2[i]);
        }
-       if (WIN32_RegisterClasses () && WIN32_InitLibraries () && DirectDraw_Start (NULL)) {
+       if (WIN32_RegisterClasses () && WIN32_InitLibraries ()) {
                DEVMODE devmode;
                DWORD i;
 
                WIN32_HandleRegistryStuff ();
-               DirectDraw_Release ();
                write_log (L"Enumerating display devices.. \n");
                enumeratedisplays (multi_display);
                write_log (L"Sorting devices and modes..\n");
@@ -5028,7 +5077,8 @@ LONG WINAPI WIN32_ExceptionFilter (struct _EXCEPTION_POINTERS *pExceptionPointer
                                                if (ppc != regs.pc_p) {
                                                        prevpc = (uae_u8*)ppc;
                                                }
-                                               exception2 (opc, (uaecptr)p);
+                                               m68k_setpc ((uaecptr)p);
+                                               exception2 (opc);
                                                lRet = EXCEPTION_CONTINUE_EXECUTION;
                                        }
                        }
index 2e3e109085726ac69e8c933646ec2195887328bb..606ae212075fa7b56fb262ec47741badc93872ac 100644 (file)
 #define GETBDM(x) (((x) - ((x / 10000) * 10000)) / 100)
 #define GETBDD(x) ((x) % 100)
 
-#define WINUAEPUBLICBETA 0
+#define WINUAEPUBLICBETA 1
 #define LANG_DLL 1
 
-#define WINUAEBETA L""
-#define WINUAEDATE MAKEBD(2010, 9, 24)
+#define WINUAEBETA L"1"
+#define WINUAEDATE MAKEBD(2010, 10, 23)
 #define WINUAEEXTRA L""
 #define WINUAEREV L""
 
index 852a6035bc5293b8bd204766b951bfe14e82d0e7..9fa8aadac7f4f469682d69d7e512f92db807f57d 100644 (file)
@@ -43,6 +43,7 @@ struct uae_filter uaefilters[] =
 
 static int filteroffsetx, filteroffsety, filterxmult = 1000, filterymult = 1000;
 static int dst_width, dst_height, amiga_width, amiga_height, amiga_depth, dst_depth, scale;
+static int dst_width2, dst_height2, amiga_width2, amiga_height2, amiga_depth2, dst_depth2;
 static int temp_width, temp_height;
 uae_u8 *bufmem_ptr;
 static LPDIRECTDRAWSURFACE7 tempsurf;
@@ -51,6 +52,7 @@ static int cleartemp;
 static uae_u32 rc[256], gc[256], bc[256];
 static int deskw, deskh;
 static int d3d;
+static bool inited;
 
 void getfilteroffset (int *dx, int *dy, int *mx, int *my)
 {
@@ -188,8 +190,10 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height
        SetRect (zr, 0, 0, 0, 0);
        dr->left = (temp_width - aws) /2;
        dr->top =  (temp_height - ahs) / 2;
-       dr->left -= (dst_width - aws) / 2;
-       dr->top -= (dst_height - ahs) / 2;
+       if (currprefs.gfx_xcenter_pos < 0)
+               dr->left -= (dst_width - aws) / 2;
+       if (currprefs.gfx_ycenter_pos < 0)
+               dr->top -= (dst_height - ahs) / 2;
        dr->right = dr->left + dst_width;
        dr->bottom = dr->top + dst_height;
 
@@ -210,20 +214,39 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height
                dstratio = srcratio;
        }
 
-       if (currprefs.gfx_filter_autoscale) {
+       int scalemode = currprefs.gfx_filter_autoscale;
+
+       if (scalemode == AUTOSCALE_STATIC_AUTO) {
+               if (currprefs.gfx_afullscreen) {
+                       scalemode = AUTOSCALE_STATIC_NOMINAL;
+               } else {
+                       int w1 = (800 / 2) << currprefs.gfx_resolution;
+                       int w2 = (640 / 2) << currprefs.gfx_resolution;
+                       int h1 = (600 / 2) << currprefs.gfx_vresolution;
+                       int h2 = (480 / 2) << currprefs.gfx_vresolution;
+                       int w = currprefs.gfx_size_win.width;
+                       int h = currprefs.gfx_size_win.height;
+                       if (w <= w1 && h <= h1 && w >= w2 && h >= h2)
+                               scalemode = AUTOSCALE_NONE;
+                       else
+                               scalemode = AUTOSCALE_STATIC_NOMINAL;
+               }
+       }
+
+       if (scalemode) {
                int cw, ch, cx, cy, cv;
                static int oxmult, oymult;
 
                filterxmult = 1000 / scale;
                filterymult = 1000 / scale;
 
-               if (currprefs.gfx_filter_autoscale == AUTOSCALE_STATIC_MAX || currprefs.gfx_filter_autoscale == AUTOSCALE_STATIC_NOMINAL) {
+               if (scalemode == AUTOSCALE_STATIC_MAX || scalemode == AUTOSCALE_STATIC_NOMINAL) {
                        cw = (752 / 2) << currprefs.gfx_resolution;
                        ch = (572 / 2) << currprefs.gfx_vresolution;
                        cx = 0;
                        cy = 0;
                        cv = 1;
-                       if (currprefs.gfx_filter_autoscale == AUTOSCALE_STATIC_NOMINAL) {
+                       if (scalemode == AUTOSCALE_STATIC_NOMINAL) {
                                cw -= 80;
                                ch -= 50;
                                cx = 56;
@@ -236,7 +259,7 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height
                if (cv) {
                        int diff;
 
-                       if (currprefs.gfx_filter_autoscale == AUTOSCALE_CENTER) {
+                       if (scalemode == AUTOSCALE_CENTER) {
 
                                int ww = cw * scale;
                                int hh = ch * scale;
@@ -248,7 +271,8 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height
                                OffsetRect (zr, cx * scale - (dst_width - ww) / 2, cy * scale - (dst_height - hh) / 2);
                                goto cont;
 
-                       } else if (currprefs.gfx_filter_autoscale == AUTOSCALE_RESIZE && isfullscreen () == 0 && !currprefs.gfx_filteroverlay[0]) {
+                       } else if (scalemode == AUTOSCALE_RESIZE && isfullscreen () == 0 && !currprefs.gfx_filteroverlay[0]) {
+
                                static int lastresize = 0;
                                static int lastdelay = 1;
                                static int ocw, och, ocx, ocy, lcw, lch, lcx, lcy;
@@ -520,6 +544,13 @@ void S2X_configure (int rb, int gb, int bb, int rs, int gs, int bs)
        bufmem_ptr = 0;
 }
 
+void S2X_reset (void)
+{
+       if (!inited)
+               return;
+       S2X_init (dst_width2, dst_height2, amiga_width2, amiga_height2, dst_depth2, amiga_depth2);
+}
+
 void S2X_free (void)
 {
        changed_prefs.leds_on_screen = currprefs.leds_on_screen = currprefs.leds_on_screen & ~STATUSLINE_TARGET;
@@ -535,6 +566,7 @@ void S2X_free (void)
        filterxmult = 1000;
        filterymult = 1000;
        scale = 1;
+       inited = false;
 }
 
 void S2X_init (int dw, int dh, int aw, int ah, int ad, int dd)
@@ -542,6 +574,14 @@ void S2X_init (int dw, int dh, int aw, int ah, int ad, int dd)
        int flags = 0;
        int res_shift;
 
+       dst_width2 = dw;
+       dst_height2 = dh;
+       dst_depth2 = dd;
+       amiga_width2 = aw;
+       amiga_height2 = ah;
+       amiga_depth2 = ad;
+
+
        S2X_free ();
        d3d = currprefs.gfx_api;
        changed_prefs.leds_on_screen = currprefs.leds_on_screen = currprefs.leds_on_screen | STATUSLINE_TARGET;
@@ -614,7 +654,7 @@ void S2X_init (int dw, int dh, int aw, int ah, int ad, int dd)
        }
        if (!tempsurf && !d3d)
                write_log (L"DDRAW: failed to create temp surface (%dx%d)\n", temp_width, temp_height);
-
+       inited = true;
 }
 
 void S2X_render (void)
index b599aa5b9c26650fa2b2a329b2a8c679e29e7b9d..4eb705912540f1a56e5034ab86668664f925fd82 100644 (file)
@@ -405,7 +405,7 @@ struct netdriverdata *uaenet_enumerate (struct netdriverdata **out, const TCHAR
                                        tc->mac[0], tc->mac[1], tc->mac[2],
                                        tc->mac[3], tc->mac[4], tc->mac[5], cnt++);
                                tc->active = 1;
-                               tc->mtu = 1500;
+                               tc->mtu = 1522;
                                tc->name = au (d->name);
                                tc->desc = au (d->description);
                        } else {
index 750af36c9c7c517a1d48224f9f56b1b05e751d08..48fe2d79cdcc13496af5c9ead1b2e618a55aae86 100644 (file)
@@ -631,73 +631,77 @@ void sortdisplays (void)
                md1->DisplayModes = xmalloc (struct PicassoResolution, MAX_PICASSO_MODES);
                md1->DisplayModes[0].depth = -1;
                md1->disabled = 1;
-               if (DirectDraw_Start (md1->primary ? NULL : &md1->guid)) {
-                       if (SUCCEEDED (DirectDraw_GetDisplayMode ())) {
-                               int w = DirectDraw_CurrentWidth ();
-                               int h = DirectDraw_CurrentHeight ();
-                               int b = DirectDraw_GetCurrentDepth ();
-                               int maxw = 0, maxh = 0;
-
-                               DirectDraw_EnumDisplayModes (DDEDM_REFRESHRATES, modesCallback, md1);
-                               idx2 = 0;
-                               while (md1->DisplayModes[idx2].depth >= 0) {
-                                       struct PicassoResolution *pr = &md1->DisplayModes[idx2];
-                                       if (pr->res.width > maxw)
-                                               maxw = pr->res.width;
-                                       if (pr->res.height > maxh)
-                                               maxh = pr->res.height;
-                                       idx2++;
-                               }
-                               write_log (L"Desktop: W=%d H=%d B=%d. MaxW=%d MaxH=%d CXVS=%d CYVS=%d\n", w, h, b, maxw, maxh,
-                                       GetSystemMetrics (SM_CXVIRTUALSCREEN), GetSystemMetrics (SM_CYVIRTUALSCREEN));
-                               idx = 0;
-                               for (;;) {
-                                       int found;
-                                       DEVMODE dm;
-                                       dm.dmSize = sizeof dm;
-                                       dm.dmDriverExtra = 0;
-                                       if (!EnumDisplaySettingsEx (md1->primary ? NULL : md1->name3, idx, &dm, EDS_RAWMODE))
-                                               break;
-                                       idx2 = 0;
-                                       found = 0;
-                                       while (md1->DisplayModes[idx2].depth >= 0 && !found) {
-                                               struct PicassoResolution *pr = &md1->DisplayModes[idx2];
-                                               if (pr->res.width == dm.dmPelsWidth && pr->res.height == dm.dmPelsHeight && pr->depth == dm.dmBitsPerPel / 8) {
-                                                       for (i = 0; pr->refresh[i]; i++) {
-                                                               if (pr->refresh[i] == dm.dmDisplayFrequency) {
-                                                                       found = 1;
-                                                                       break;
-                                                               }
-                                                       }
+               int w = GetSystemMetrics (SM_CXSCREEN);
+               int h = GetSystemMetrics (SM_CYSCREEN);
+               HDC hdc = GetDC (NULL);
+               int b = 0;
+               
+               if (hdc) {
+                       b = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
+                       ReleaseDC (NULL, hdc);
+               }
+
+               int maxw = 0, maxh = 0;
+               if (DirectDraw_Start (NULL)) {
+                       DirectDraw_EnumDisplayModes (DDEDM_REFRESHRATES, modesCallback, md1);
+                       idx2 = 0;
+                       while (md1->DisplayModes[idx2].depth >= 0) {
+                               struct PicassoResolution *pr = &md1->DisplayModes[idx2];
+                               if (pr->res.width > maxw)
+                                       maxw = pr->res.width;
+                               if (pr->res.height > maxh)
+                                       maxh = pr->res.height;
+                               idx2++;
+                       }
+                       DirectDraw_Release ();
+               }
+               write_log (L"Desktop: W=%d H=%d B=%d. MaxW=%d MaxH=%d CXVS=%d CYVS=%d\n", w, h, b, maxw, maxh,
+                       GetSystemMetrics (SM_CXVIRTUALSCREEN), GetSystemMetrics (SM_CYVIRTUALSCREEN));
+               idx = 0;
+               for (;;) {
+                       int found;
+                       DEVMODE dm;
+                       dm.dmSize = sizeof dm;
+                       dm.dmDriverExtra = 0;
+                       if (!EnumDisplaySettingsEx (md1->primary ? NULL : md1->name3, idx, &dm, EDS_RAWMODE))
+                               break;
+                       idx2 = 0;
+                       found = 0;
+                       while (md1->DisplayModes[idx2].depth >= 0 && !found) {
+                               struct PicassoResolution *pr = &md1->DisplayModes[idx2];
+                               if (pr->res.width == dm.dmPelsWidth && pr->res.height == dm.dmPelsHeight && pr->depth == dm.dmBitsPerPel / 8) {
+                                       for (i = 0; pr->refresh[i]; i++) {
+                                               if (pr->refresh[i] == dm.dmDisplayFrequency) {
+                                                       found = 1;
+                                                       break;
                                                }
-                                               idx2++;
                                        }
-                                       if (!found && dm.dmBitsPerPel > 8) {
-                                               int freq = 0;
+                               }
+                               idx2++;
+                       }
+                       if (!found && dm.dmBitsPerPel > 8) {
+                               int freq = 0;
 #if 0
-                                               write_log (L"EnumDisplaySettings(%dx%dx%d %dHz %08x)\n",
-                                                       dm.dmPelsWidth, dm.dmPelsHeight, dm.dmBitsPerPel, dm.dmDisplayFrequency, dm.dmFields);
+                               write_log (L"EnumDisplaySettings(%dx%dx%d %dHz %08x)\n",
+                                       dm.dmPelsWidth, dm.dmPelsHeight, dm.dmBitsPerPel, dm.dmDisplayFrequency, dm.dmFields);
 #endif
-                                               if (dm.dmFields & DM_DISPLAYFREQUENCY) {
-                                                       freq = dm.dmDisplayFrequency;
-                                                       if (freq < 10)
-                                                               freq = 0;
-                                               }
-                                               if (freq < 75 && dm.dmPelsWidth <= maxw && dm.dmPelsHeight <= maxh) {
-                                                       if ((dm.dmFields & DM_PELSWIDTH) && (dm.dmFields & DM_PELSHEIGHT) && (dm.dmFields & DM_BITSPERPEL))
-                                                               addmode (md1, dm.dmPelsWidth, dm.dmPelsHeight, dm.dmBitsPerPel, freq, 1);
-                                               }
-                                       }
-                                       idx++;
+                               if (dm.dmFields & DM_DISPLAYFREQUENCY) {
+                                       freq = dm.dmDisplayFrequency;
+                                       if (freq < 10)
+                                               freq = 0;
+                               }
+                               if (freq < 75 && dm.dmPelsWidth <= maxw && dm.dmPelsHeight <= maxh) {
+                                       if ((dm.dmFields & DM_PELSWIDTH) && (dm.dmFields & DM_PELSHEIGHT) && (dm.dmFields & DM_BITSPERPEL))
+                                               addmode (md1, dm.dmPelsWidth, dm.dmPelsHeight, dm.dmBitsPerPel, freq, 1);
                                }
-                               //dhack();
-                               sortmodes (md1);
-                               modesList (md1);
-                               DirectDraw_Release ();
-                               if (md1->DisplayModes[0].depth >= 0)
-                                       md1->disabled = 0;
                        }
+                       idx++;
                }
+               //dhack();
+               sortmodes (md1);
+               modesList (md1);
+               if (md1->DisplayModes[0].depth >= 0)
+               md1->disabled = 0;
                i = 0;
                while (md1->DisplayModes[i].depth > 0)
                        i++;
@@ -1289,8 +1293,8 @@ int check_prefs_changed_gfx (void)
        c |= currprefs.gfx_filter_gamma != changed_prefs.gfx_filter_gamma ? (1|8) : 0;
        //c |= currprefs.gfx_filter_ != changed_prefs.gfx_filter_ ? (1|8) : 0;
 
-       c |= currprefs.gfx_resolution != changed_prefs.gfx_resolution ? (2 | 8) : 0;
-       c |= currprefs.gfx_vresolution != changed_prefs.gfx_vresolution ? (2 | 8) : 0;
+       c |= currprefs.gfx_resolution != changed_prefs.gfx_resolution ? (128) : 0;
+       c |= currprefs.gfx_vresolution != changed_prefs.gfx_vresolution ? (128) : 0;
        c |= currprefs.gfx_scanlines != changed_prefs.gfx_scanlines ? (2 | 8) : 0;
 
        c |= currprefs.gfx_lores_mode != changed_prefs.gfx_lores_mode ? (2 | 8) : 0;
@@ -1379,6 +1383,14 @@ int check_prefs_changed_gfx (void)
                        DirectDraw_Fill (NULL, 0);
                        DirectDraw_BlitToPrimary (NULL);
                }
+               if (c & 128) {
+                       if (currprefs.gfx_autoresolution) {
+                               c |= 2 | 8;
+                       } else {
+                               drawing_init ();
+                               S2X_reset ();
+                       }
+               }
                if ((c & 16) || ((c & 8) && keepfsmode)) {
                        if (reopen (c & 2))
                                c |= 2;
@@ -1398,7 +1410,7 @@ int check_prefs_changed_gfx (void)
 
        if (currprefs.chipset_refreshrate != changed_prefs.chipset_refreshrate) {
                currprefs.chipset_refreshrate = changed_prefs.chipset_refreshrate;
-               init_hz ();
+               init_hz_full ();
                return 1;
        }
 
@@ -2466,10 +2478,19 @@ static BOOL doInit (void)
                } else {
 #endif
                        currentmode->native_depth = currentmode->current_depth;
+                       gfxvidinfo.gfx_resolution_reserved = currprefs.gfx_resolution;
+                       gfxvidinfo.gfx_vresolution_reserved = currprefs.gfx_vresolution;
 #if defined (GFXFILTER)
                        if (currentmode->flags & (DM_D3D | DM_SWSCALE)) {
-                               currentmode->amiga_width = AMIGA_WIDTH_MAX << currprefs.gfx_resolution;
-                               currentmode->amiga_height = AMIGA_HEIGHT_MAX << currprefs.gfx_vresolution;
+                               if (!currprefs.gfx_autoresolution) {
+                                       currentmode->amiga_width = AMIGA_WIDTH_MAX << currprefs.gfx_resolution;
+                                       currentmode->amiga_height = AMIGA_HEIGHT_MAX << currprefs.gfx_vresolution;
+                               } else {
+                                       gfxvidinfo.gfx_resolution_reserved = currprefs.gfx_resolution == RES_SUPERHIRES ? RES_SUPERHIRES : RES_HIRES;
+                                       gfxvidinfo.gfx_vresolution_reserved = VRES_DOUBLE;
+                                       currentmode->amiga_width = AMIGA_WIDTH_MAX << gfxvidinfo.gfx_resolution_reserved;
+                                       currentmode->amiga_height = AMIGA_HEIGHT_MAX << gfxvidinfo.gfx_vresolution_reserved;
+                               }
                                if (currprefs.gfx_resolution == RES_SUPERHIRES)
                                        currentmode->amiga_height *= 2;
                                if (currentmode->amiga_height > 960)
index 7563051e3ebc3865dd6b1288b55d7d4e35ee2355..97a76565a294c27bd704b68a1a28705a89a1e5e2 100644 (file)
@@ -48,6 +48,7 @@
 #include "filesys.h"
 #include "autoconf.h"
 #include "inputdevice.h"
+#include "inputrecord.h"
 #include "xwin.h"
 #include "keyboard.h"
 #include "zfile.h"
@@ -1280,7 +1281,7 @@ static int addrom (UAEREG *fkey, struct romdata *rd, const TCHAR *name)
        return 1;
 }
 
-static int isromext (const TCHAR *path)
+static int isromext (const TCHAR *path, bool deepscan)
 {
        const TCHAR *ext;
        int i;
@@ -1297,6 +1298,8 @@ static int isromext (const TCHAR *path)
                return 1;
        if (_tcslen (ext) >= 2 && toupper(ext[0]) == 'U' && isdigit (ext[1]))
                return 1;
+       if (!deepscan)
+               return 0;
        for (i = 0; uae_archive_extensions[i]; i++) {
                if (!_tcsicmp (ext, uae_archive_extensions[i]))
                        return 1;
@@ -1379,7 +1382,7 @@ static int scan_rom_2 (struct zfile *f, void *vrsd)
        struct romdata *rd;
 
        scan_rom_hook (NULL, 0);
-       if (!isromext (path))
+       if (!isromext (path, true))
                return 0;
        rd = scan_single_rom_2 (f);
        if (rd) {
@@ -1396,13 +1399,13 @@ static int scan_rom_2 (struct zfile *f, void *vrsd)
        return 0;
 }
 
-static int scan_rom (const TCHAR *path, UAEREG *fkey)
+static int scan_rom (const TCHAR *path, UAEREG *fkey, bool deepscan)
 {
        struct romscandata rsd = { fkey, 0 };
        struct romdata *rd;
        int cnt = 0;
 
-       if (!isromext (path)) {
+       if (!isromext (path, deepscan)) {
                //write_log("ROMSCAN: skipping file '%s', unknown extension\n", path);
                return 0;
        }
@@ -1499,7 +1502,7 @@ static void show_rom_list (void)
        free (p);
 }
 
-static int scan_roms_2 (UAEREG *fkey, const TCHAR *path)
+static int scan_roms_2 (UAEREG *fkey, const TCHAR *path, bool deepscan)
 {
        TCHAR buf[MAX_DPATH];
        WIN32_FIND_DATA find_data;
@@ -1521,7 +1524,7 @@ static int scan_roms_2 (UAEREG *fkey, const TCHAR *path)
                _tcscpy (tmppath, path);
                _tcscat (tmppath, find_data.cFileName);
                if (!(find_data.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY |FILE_ATTRIBUTE_SYSTEM)) && find_data.nFileSizeLow < 10000000) {
-                       if (scan_rom (tmppath, fkey))
+                       if (scan_rom (tmppath, fkey, deepscan))
                                ret = 1;
                }
                if (!scan_rom_hook (NULL, 0) || FindNextFile (handle, &find_data) == 0) {
@@ -1538,6 +1541,7 @@ static int scan_roms_3 (UAEREG *fkey, TCHAR **paths, const TCHAR *path)
 {
        int i, ret;
        TCHAR pathp[MAX_DPATH];
+       bool deepscan = true;
 
        ret = 0;
        scan_rom_hook (NULL, 0);
@@ -1546,12 +1550,12 @@ static int scan_roms_3 (UAEREG *fkey, TCHAR **paths, const TCHAR *path)
        if (!pathp[0])
                return ret;
        if (_tcsicmp (pathp, start_path_exe) == 0)
-               return ret;
+               deepscan = false; // do not scan root dir archives
        for (i = 0; i < MAX_ROM_PATHS; i++) {
                if (paths[i] && !_tcsicmp (paths[i], pathp))
                        return ret;
        }
-       ret = scan_roms_2 (fkey, pathp);
+       ret = scan_roms_2 (fkey, pathp, deepscan);
        for (i = 0; i < MAX_ROM_PATHS; i++) {
                if (!paths[i]) {
                        paths[i] = my_strdup(pathp);
@@ -2121,14 +2125,14 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs
                WIN32GUI_LoadUIString (IDS_ADF, szFormat, MAX_DPATH);
                _stprintf (szFilter, L"%s ", szFormat);
                memcpy (szFilter + _tcslen (szFilter), DISK_FORMAT_STRING, sizeof (DISK_FORMAT_STRING) + sizeof (TCHAR));
-               defext = L"ADF";
+               defext = L"adf";
                break;
        case 1:
                WIN32GUI_LoadUIString (IDS_CHOOSEBLANK, szTitle, MAX_DPATH);
                WIN32GUI_LoadUIString (IDS_ADF, szFormat, MAX_DPATH);
                _stprintf (szFilter, L"%s ", szFormat);
                memcpy (szFilter + _tcslen (szFilter), L"(*.adf)\0*.adf\0", 15 * sizeof (TCHAR));
-               defext = L"ADF";
+               defext = L"adf";
                break;
        case 2:
        case 3:
@@ -2136,7 +2140,7 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs
                WIN32GUI_LoadUIString (IDS_HDF, szFormat, MAX_DPATH);
                _stprintf (szFilter, L"%s ", szFormat);
                memcpy (szFilter + _tcslen (szFilter),  HDF_FORMAT_STRING, sizeof (HDF_FORMAT_STRING) + sizeof (TCHAR));
-               defext = L"HDF";
+               defext = L"hdf";
                break;
        case 4:
        case 5:
@@ -2144,21 +2148,21 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs
                WIN32GUI_LoadUIString (IDS_UAE, szFormat, MAX_DPATH );
                _stprintf (szFilter, L"%s ", szFormat);
                memcpy (szFilter + _tcslen (szFilter), L"(*.uae)\0*.uae\0", 15 * sizeof (TCHAR));
-               defext = L"UAE";
+               defext = L"uae";
                break;
        case 6:
                WIN32GUI_LoadUIString (IDS_SELECTROM, szTitle, MAX_DPATH);
                WIN32GUI_LoadUIString (IDS_ROM, szFormat, MAX_DPATH);
                _stprintf (szFilter, L"%s ", szFormat);
                memcpy (szFilter + _tcslen (szFilter), ROM_FORMAT_STRING, sizeof (ROM_FORMAT_STRING) + sizeof (TCHAR));
-               defext = L"ROM";
+               defext = L"rom";
                break;
        case 7:
                WIN32GUI_LoadUIString (IDS_SELECTKEY, szTitle, MAX_DPATH);
                WIN32GUI_LoadUIString (IDS_KEY, szFormat, MAX_DPATH);
                _stprintf (szFilter, L"%s ", szFormat);
                memcpy (szFilter + _tcslen (szFilter), L"(*.key)\0*.key\0", 15 * sizeof (TCHAR));
-               defext = L"KEY";
+               defext = L"key";
                break;
        case 15:
        case 16:
@@ -2166,7 +2170,7 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs
                WIN32GUI_LoadUIString (IDS_INP, szFormat, MAX_DPATH);
                _stprintf (szFilter, L"%s ", szFormat);
                memcpy (szFilter + _tcslen (szFilter), INP_FORMAT_STRING, sizeof (INP_FORMAT_STRING) + sizeof (TCHAR));
-               defext = L"IMP";
+               defext = L"inp";
                break;
        case 9:
        case 10:
@@ -2203,14 +2207,14 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs
                        *p = 0;
                        all = 0;
                }
-               defext = L"USS";
+               defext = L"uss";
                break;
        case 11:
                WIN32GUI_LoadUIString (IDS_SELECTFLASH, szTitle, MAX_DPATH);
                WIN32GUI_LoadUIString (IDS_FLASH, szFormat, MAX_DPATH);
                _stprintf (szFilter, L"%s ", szFormat);
                memcpy (szFilter + _tcslen (szFilter), L"(*.nvr)\0*.nvr\0", 15 * sizeof (TCHAR));
-               defext = L"NVR";
+               defext = L"nvr";
                break;
        case 8:
        default:
@@ -2235,7 +2239,7 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs
                WIN32GUI_LoadUIString (IDS_CD, szFormat, MAX_DPATH);
                _stprintf (szFilter, L"%s ", szFormat);
                memcpy (szFilter + _tcslen (szFilter), CD_FORMAT_STRING, sizeof (CD_FORMAT_STRING) + sizeof (TCHAR));
-               defext = L"CUE";
+               defext = L"cue";
                break;
        }
        if (all) {
@@ -2338,8 +2342,10 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs
                        selectdisk (prefs, hDlg, 3, IDC_DF3TEXT, full_path);
                        break;
                case IDC_DOSAVESTATE:
+                       savestate_initsave (full_path, openFileName.nFilterIndex, FALSE, true);
+                       break;
                case IDC_DOLOADSTATE:
-                       savestate_initsave (full_path, openFileName.nFilterIndex, FALSE);
+                       savestate_initsave (full_path, openFileName.nFilterIndex, FALSE, false);
                        break;
                case IDC_CREATE:
                        {
@@ -2386,13 +2392,11 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs
                        _tcscpy (workprefs.cartfile, full_path);
                        fullpath (workprefs.cartfile, MAX_DPATH);
                        break;
-               case IDC_INPREC_PLAY:
+               case IDC_STATEREC_PLAY:
+               case IDC_STATEREC_RECORD:
+               case IDC_STATEREC_SAVE:
                        _tcscpy (workprefs.inprecfile, full_path);
-                       workprefs.inprecmode = ischecked (hDlg, IDC_INPREC_PLAYMODE) ? -1 : -2;
-                       break;
-               case IDC_INPREC_RECORD:
                        _tcscpy (workprefs.inprecfile, full_path);
-                       workprefs.inprecmode = 1;
                        break;
                }
                if (!nosavepath || 1) {
@@ -5702,6 +5706,8 @@ static void values_to_displaydlg (HWND hDlg)
        CheckDlgButton (hDlg, IDC_XCENTER, workprefs.gfx_xcenter);
        CheckDlgButton (hDlg, IDC_YCENTER, workprefs.gfx_ycenter);
 
+       CheckDlgButton (hDlg, IDC_AUTORESOLUTION, workprefs.gfx_autoresolution);
+
        SendDlgItemMessage(hDlg, IDC_DISPLAY_BUFFERCNT, CB_RESETCONTENT, 0, 0);
        WIN32GUI_LoadUIString(IDS_BUFFER_SINGLE, buffer, sizeof buffer / sizeof (TCHAR));
        SendDlgItemMessage(hDlg, IDC_DISPLAY_BUFFERCNT, CB_ADDSTRING, 0, (LPARAM)buffer);
@@ -5800,6 +5806,7 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l
                workprefs.chipset_refreshrate = 0;
        workprefs.gfx_xcenter = ischecked (hDlg, IDC_XCENTER) ? 2 : 0; /* Smart centering */
        workprefs.gfx_ycenter = ischecked (hDlg, IDC_YCENTER) ? 2 : 0; /* Smart centering */
+       workprefs.gfx_autoresolution = ischecked (hDlg, IDC_AUTORESOLUTION);
 
        if (msg == WM_COMMAND && HIWORD (wParam) == CBN_SELCHANGE)
        {
@@ -7169,16 +7176,11 @@ static void enable_for_miscdlg (HWND hDlg)
                ew (hDlg, IDC_DOSAVESTATE, TRUE);
                ew (hDlg, IDC_SCSIMODE, FALSE);
                ew (hDlg, IDC_CLOCKSYNC, FALSE);
-               ew (hDlg, IDC_STATE_CAPTURE, FALSE);
-               ew (hDlg, IDC_STATE_RATE, FALSE);
-               ew (hDlg, IDC_STATE_BUFFERSIZE, FALSE);
        } else {
 #if !defined (SCSIEMU)
                EnableWindow (GetDlgItem(hDlg, IDC_SCSIMODE), TRUE);
 #endif
                ew (hDlg, IDC_DOSAVESTATE, FALSE);
-               ew (hDlg, IDC_STATE_RATE, workprefs.statecapture ? TRUE : FALSE);
-               ew (hDlg, IDC_STATE_BUFFERSIZE, workprefs.statecapture ? TRUE : FALSE);
        }
        ew (hDlg, IDC_ASSOCIATELIST, !rp_isactive ());
        ew (hDlg, IDC_ASSOCIATE_ON, !rp_isactive ());
@@ -7305,8 +7307,6 @@ static void misc_setlang (int v)
 
 static void values_to_miscdlg (HWND hDlg)
 {
-       TCHAR txt[100];
-
        if (currentpage == MISC1_ID) {
 
                CheckDlgButton (hDlg, IDC_FOCUSMINIMIZE, workprefs.win32_minimize_inactive);
@@ -7321,7 +7321,6 @@ static void values_to_miscdlg (HWND hDlg)
                CheckDlgButton (hDlg, IDC_ALWAYSONTOP, workprefs.win32_alwaysontop);
                CheckDlgButton (hDlg, IDC_CLOCKSYNC, workprefs.tod_hack);
                CheckDlgButton (hDlg, IDC_POWERSAVE, workprefs.win32_powersavedisabled);
-               CheckDlgButton (hDlg, IDC_STATE_CAPTURE, workprefs.statecapture);
                CheckDlgButton (hDlg, IDC_FASTERRTG, workprefs.picasso96_nocustom);
 
                misc_kbled (hDlg, IDC_KBLED1, workprefs.keyboard_leds[0]);
@@ -7329,24 +7328,6 @@ static void values_to_miscdlg (HWND hDlg)
                misc_kbled (hDlg, IDC_KBLED3, workprefs.keyboard_leds[2]);
                CheckDlgButton (hDlg, IDC_KBLED_USB, workprefs.win32_kbledmode);
 
-               SendDlgItemMessage (hDlg, IDC_STATE_RATE, CB_RESETCONTENT, 0, 0);
-               SendDlgItemMessage (hDlg, IDC_STATE_RATE, CB_ADDSTRING, 0, (LPARAM)L"1");
-               SendDlgItemMessage (hDlg, IDC_STATE_RATE, CB_ADDSTRING, 0, (LPARAM)L"5");
-               SendDlgItemMessage (hDlg, IDC_STATE_RATE, CB_ADDSTRING, 0, (LPARAM)L"10");
-               SendDlgItemMessage (hDlg, IDC_STATE_RATE, CB_ADDSTRING, 0, (LPARAM)L"20");
-               SendDlgItemMessage (hDlg, IDC_STATE_RATE, CB_ADDSTRING, 0, (LPARAM)L"30");
-               _stprintf (txt, L"%d", workprefs.statecapturerate / 50);
-               SendDlgItemMessage( hDlg, IDC_STATE_RATE, WM_SETTEXT, 0, (LPARAM)txt);
-
-               SendDlgItemMessage (hDlg, IDC_STATE_BUFFERSIZE, CB_RESETCONTENT, 0, 0);
-               SendDlgItemMessage (hDlg, IDC_STATE_BUFFERSIZE, CB_ADDSTRING, 0, (LPARAM)L"5");
-               SendDlgItemMessage (hDlg, IDC_STATE_BUFFERSIZE, CB_ADDSTRING, 0, (LPARAM)L"10");
-               SendDlgItemMessage (hDlg, IDC_STATE_BUFFERSIZE, CB_ADDSTRING, 0, (LPARAM)L"20");
-               SendDlgItemMessage (hDlg, IDC_STATE_BUFFERSIZE, CB_ADDSTRING, 0, (LPARAM)L"50");
-               SendDlgItemMessage (hDlg, IDC_STATE_BUFFERSIZE, CB_ADDSTRING, 0, (LPARAM)L"100");
-               _stprintf (txt, L"%d", workprefs.statecapturebuffersize / (1024 * 1024));
-               SendDlgItemMessage( hDlg, IDC_STATE_BUFFERSIZE, WM_SETTEXT, 0, (LPARAM)txt);
-
                misc_scsi (hDlg);
                misc_lang (hDlg);
 
@@ -7355,6 +7336,13 @@ static void values_to_miscdlg (HWND hDlg)
                SendDlgItemMessage (hDlg, IDC_DXMODE, CB_ADDSTRING, 0, (LPARAM)L"Direct3D");
                SendDlgItemMessage (hDlg, IDC_DXMODE, CB_SETCURSEL, workprefs.gfx_api, 0);
 
+               SendDlgItemMessage (hDlg, IDC_DD_SURFACETYPE, CB_RESETCONTENT, 0, 0);
+               SendDlgItemMessage (hDlg, IDC_DD_SURFACETYPE, CB_ADDSTRING, 0, (LPARAM)L"NonLocalVRAM");
+               SendDlgItemMessage (hDlg, IDC_DD_SURFACETYPE, CB_ADDSTRING, 0, (LPARAM)L"DefaultRAM *");
+               SendDlgItemMessage (hDlg, IDC_DD_SURFACETYPE, CB_ADDSTRING, 0, (LPARAM)L"LocalVRAM");
+               SendDlgItemMessage (hDlg, IDC_DD_SURFACETYPE, CB_ADDSTRING, 0, (LPARAM)L"SystemRAM");
+               SendDlgItemMessage (hDlg, IDC_DD_SURFACETYPE, CB_SETCURSEL, ddforceram, 0);
+
                SendDlgItemMessage (hDlg, IDC_WINDOWEDMODE, CB_RESETCONTENT, 0, 0);
                SendDlgItemMessage (hDlg, IDC_WINDOWEDMODE, CB_ADDSTRING, 0, (LPARAM)L"Borderless");
                SendDlgItemMessage (hDlg, IDC_WINDOWEDMODE, CB_ADDSTRING, 0, (LPARAM)L"Minimal");
@@ -7364,13 +7352,6 @@ static void values_to_miscdlg (HWND hDlg)
                        workprefs.win32_borderless ? 0 : (workprefs.win32_statusbar + 1),
                        0);
 
-               SendDlgItemMessage (hDlg, IDC_DD_SURFACETYPE, CB_RESETCONTENT, 0, 0);
-               SendDlgItemMessage (hDlg, IDC_DD_SURFACETYPE, CB_ADDSTRING, 0, (LPARAM)L"NonLocalVRAM");
-               SendDlgItemMessage (hDlg, IDC_DD_SURFACETYPE, CB_ADDSTRING, 0, (LPARAM)L"DefaultRAM *");
-               SendDlgItemMessage (hDlg, IDC_DD_SURFACETYPE, CB_ADDSTRING, 0, (LPARAM)L"LocalVRAM");
-               SendDlgItemMessage (hDlg, IDC_DD_SURFACETYPE, CB_ADDSTRING, 0, (LPARAM)L"SystemRAM");
-               SendDlgItemMessage (hDlg, IDC_DD_SURFACETYPE, CB_SETCURSEL, ddforceram, 0);
-
        } else if (currentpage == MISC2_ID) {
 
                CheckDlgButton (hDlg, IDC_INACTIVE_PAUSE, workprefs.win32_inactive_pause);
@@ -7386,7 +7367,6 @@ static void values_to_miscdlg (HWND hDlg)
 
 static INT_PTR MiscDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 {
-       TCHAR txt[100];
        int v, i;
        static int recursive;
 
@@ -7455,13 +7435,6 @@ static INT_PTR MiscDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
                                case IDC_KBLED3:
                                        misc_getkbled (hDlg, IDC_KBLED3, 2);
                                        break;
-                               case IDC_STATE_RATE:
-                                       getcbn (hDlg, IDC_STATE_RATE, txt, sizeof (txt) / sizeof (TCHAR));
-                                       workprefs.statecapturerate = _tstol (txt) * 50;
-                                       break;
-                               case IDC_STATE_BUFFERSIZE:
-                                       getcbn (hDlg, IDC_STATE_BUFFERSIZE, txt, sizeof (txt) / sizeof (TCHAR));
-                                       break;
                                case IDC_LANGUAGE:
                                        if (HIWORD (wParam) == CBN_SELENDOK) {
                                                v = SendDlgItemMessage (hDlg, IDC_LANGUAGE, CB_GETCURSEL, 0, 0L);
@@ -7529,10 +7502,6 @@ static INT_PTR MiscDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
                        if (DiskSelection(hDlg, wParam, 10, &workprefs, 0))
                                savestate_state = STATE_DORESTORE;
                        break;
-               case IDC_STATE_CAPTURE:
-                       workprefs.statecapture = ischecked (hDlg, IDC_STATE_CAPTURE);
-                       enable_for_miscdlg (hDlg);
-                       break;
                case IDC_ILLEGAL:
                        workprefs.illegal_mem = ischecked (hDlg, IDC_ILLEGAL);
                        break;
@@ -10961,6 +10930,8 @@ static INT_PTR CALLBACK GamePortsDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
                        SendDlgItemMessage (hDlg, id, CB_ADDSTRING, 0, (LPARAM)tmp);
                        WIN32GUI_LoadUIString (IDS_JOYMODE_JOYSTICK, tmp, MAX_DPATH);
                        SendDlgItemMessage (hDlg, id, CB_ADDSTRING, 0, (LPARAM)tmp);
+                       WIN32GUI_LoadUIString (IDS_JOYMODE_GAMEPAD, tmp, MAX_DPATH);
+                       SendDlgItemMessage (hDlg, id, CB_ADDSTRING, 0, (LPARAM)tmp);
                        WIN32GUI_LoadUIString (IDS_JOYMODE_JOYSTICKANALOG, tmp, MAX_DPATH);
                        SendDlgItemMessage (hDlg, id, CB_ADDSTRING, 0, (LPARAM)tmp);
                        WIN32GUI_LoadUIString (IDS_JOYMODE_MOUSE_CDTV, tmp, MAX_DPATH);
@@ -12228,6 +12199,8 @@ static void values_to_hw3ddlg (HWND hDlg)
        SendDlgItemMessage (hDlg, IDC_FILTERAUTOSCALE, CB_RESETCONTENT, 0, 0L);
        WIN32GUI_LoadUIString (IDS_AUTOSCALE_DISABLED, txt, sizeof (txt) / sizeof (TCHAR));
        SendDlgItemMessage (hDlg, IDC_FILTERAUTOSCALE, CB_ADDSTRING, 0, (LPARAM)txt);
+       WIN32GUI_LoadUIString (IDS_AUTOSCALE_DEFAULT, txt, sizeof (txt) / sizeof (TCHAR));
+       SendDlgItemMessage (hDlg, IDC_FILTERAUTOSCALE, CB_ADDSTRING, 0, (LPARAM)txt);
        WIN32GUI_LoadUIString (IDS_AUTOSCALE_TV, txt, sizeof (txt) / sizeof (TCHAR));
        SendDlgItemMessage (hDlg, IDC_FILTERAUTOSCALE, CB_ADDSTRING, 0, (LPARAM)txt);
        WIN32GUI_LoadUIString (IDS_AUTOSCALE_MAX, txt, sizeof (txt) / sizeof (TCHAR));
@@ -12834,6 +12807,9 @@ static void values_to_avioutputdlg (HWND hDlg)
        CheckDlgButton (hDlg, IDC_AVIOUTPUT_ACTIVATED, avioutput_requested ? BST_CHECKED : BST_UNCHECKED);
        CheckDlgButton (hDlg, IDC_SCREENSHOT_ORIGINALSIZE, screenshot_originalsize ? TRUE : FALSE);
        CheckDlgButton (hDlg, IDC_SAMPLERIPPER_ACTIVATED, sampleripper_enabled ? BST_CHECKED : BST_UNCHECKED);
+       CheckDlgButton (hDlg, IDC_STATEREC_RECORD, input_record ? BST_CHECKED : BST_UNCHECKED);
+       CheckDlgButton (hDlg, IDC_STATEREC_PLAY, input_play ? BST_CHECKED : BST_UNCHECKED);
+       CheckDlgButton (hDlg, IDC_STATEREC_AUTOPLAY, workprefs.inprec_autoplay ? BST_CHECKED : BST_UNCHECKED);
 }
 
 static void values_from_avioutputdlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -12864,6 +12840,9 @@ static void enable_for_avioutputdlg (HWND hDlg)
                ew (hDlg, IDC_AVIOUTPUT_AUDIO_STATIC, TRUE);
        }
 
+       ew (hDlg, IDC_STATEREC_RATE, !input_record && full_property_sheet ? TRUE : FALSE);
+       ew (hDlg, IDC_STATEREC_BUFFERSIZE, !input_record && full_property_sheet ? TRUE : FALSE);
+
        if (avioutput_audio == AVIAUDIO_WAV) {
                _tcscpy (tmp, L"Wave (internal)");
        } else {
@@ -12893,11 +12872,11 @@ static void enable_for_avioutputdlg (HWND hDlg)
 
        ew (hDlg, IDC_AVIOUTPUT_ACTIVATED, (!avioutput_audio && !avioutput_video) ? FALSE : TRUE);
 
-       ew (hDlg, IDC_INPREC_RECORD, input_recording >= 0);
-       CheckDlgButton (hDlg, IDC_INPREC_RECORD, input_recording > 0 ? BST_CHECKED : BST_UNCHECKED);
-       ew (hDlg, IDC_INPREC_PLAY, input_recording <= 0);
-       CheckDlgButton (hDlg, IDC_INPREC_PLAY, input_recording < 0 ? BST_CHECKED : BST_UNCHECKED);
-       ew (hDlg, IDC_INPREC_PLAYMODE, input_recording == 0);
+       CheckDlgButton (hDlg, IDC_STATEREC_RECORD, input_record ? BST_CHECKED : BST_UNCHECKED);
+       CheckDlgButton (hDlg, IDC_STATEREC_PLAY, input_play ? BST_CHECKED : BST_UNCHECKED);
+       ew (hDlg, IDC_STATEREC_RECORD, !(input_play == INPREC_PLAY_NORMAL && full_property_sheet));
+       ew (hDlg, IDC_STATEREC_SAVE, input_record == INPREC_RECORD_RERECORD || input_record == INPREC_RECORD_PLAYING);
+       ew (hDlg, IDC_STATEREC_PLAY, input_record != INPREC_RECORD_RERECORD);
 }
 
 static INT_PTR CALLBACK AVIOutputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -12917,6 +12896,30 @@ static INT_PTR CALLBACK AVIOutputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
                        fetch_path (L"VideoPath", avioutput_filename, sizeof (avioutput_filename) / sizeof (TCHAR));
                        _tcscat (avioutput_filename, L"output.avi");
                }
+               SendDlgItemMessage (hDlg, IDC_STATEREC_RATE, CB_RESETCONTENT, 0, 0);
+               SendDlgItemMessage (hDlg, IDC_STATEREC_RATE, CB_ADDSTRING, 0, (LPARAM)L"-");
+               SendDlgItemMessage (hDlg, IDC_STATEREC_RATE, CB_ADDSTRING, 0, (LPARAM)L"1");
+               SendDlgItemMessage (hDlg, IDC_STATEREC_RATE, CB_ADDSTRING, 0, (LPARAM)L"2");
+               SendDlgItemMessage (hDlg, IDC_STATEREC_RATE, CB_ADDSTRING, 0, (LPARAM)L"5");
+               SendDlgItemMessage (hDlg, IDC_STATEREC_RATE, CB_ADDSTRING, 0, (LPARAM)L"10");
+               SendDlgItemMessage (hDlg, IDC_STATEREC_RATE, CB_ADDSTRING, 0, (LPARAM)L"20");
+               SendDlgItemMessage (hDlg, IDC_STATEREC_RATE, CB_ADDSTRING, 0, (LPARAM)L"30");
+               SendDlgItemMessage (hDlg, IDC_STATEREC_RATE, CB_ADDSTRING, 0, (LPARAM)L"60");
+               SendDlgItemMessage (hDlg, IDC_STATEREC_RATE, CB_SETCURSEL, 0, 0);
+               if (workprefs.statecapturerate > 0) {
+                       _stprintf (tmp, L"%d", workprefs.statecapturerate / 50);
+                       SendDlgItemMessage( hDlg, IDC_STATEREC_RATE, WM_SETTEXT, 0, (LPARAM)tmp);
+               }
+
+               SendDlgItemMessage (hDlg, IDC_STATEREC_BUFFERSIZE, CB_RESETCONTENT, 0, 0);
+               SendDlgItemMessage (hDlg, IDC_STATEREC_BUFFERSIZE, CB_ADDSTRING, 0, (LPARAM)L"50");
+               SendDlgItemMessage (hDlg, IDC_STATEREC_BUFFERSIZE, CB_ADDSTRING, 0, (LPARAM)L"100");
+               SendDlgItemMessage (hDlg, IDC_STATEREC_BUFFERSIZE, CB_ADDSTRING, 0, (LPARAM)L"500");
+               SendDlgItemMessage (hDlg, IDC_STATEREC_BUFFERSIZE, CB_ADDSTRING, 0, (LPARAM)L"1000");
+               SendDlgItemMessage (hDlg, IDC_STATEREC_BUFFERSIZE, CB_ADDSTRING, 0, (LPARAM)L"10000");
+               _stprintf (tmp, L"%d", workprefs.statecapturebuffersize);
+               SendDlgItemMessage( hDlg, IDC_STATEREC_BUFFERSIZE, WM_SETTEXT, 0, (LPARAM)tmp);
+               
 
        case WM_USER:
                recursive++;
@@ -12939,12 +12942,9 @@ static INT_PTR CALLBACK AVIOutputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
 
                if(recursive > 0)
                        break;
-
                recursive++;
-
                switch(wParam)
                {
-
                case IDC_AVIOUTPUT_FRAMELIMITER:
                        avioutput_framelimiter = ischecked (hDlg, IDC_AVIOUTPUT_FRAMELIMITER) ? 0 : 1;
                        AVIOutput_SetSettings ();
@@ -12965,22 +12965,47 @@ static INT_PTR CALLBACK AVIOutputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
                        screenshot_originalsize = ischecked (hDlg, IDC_SCREENSHOT_ORIGINALSIZE) ? 1 : 0;
                        regsetint (NULL, L"Screenshot_Original", screenshot_originalsize);
                        break;
-
-               case IDC_INPREC_PLAYMODE:
+               case IDC_STATEREC_SAVE:
+                       if (input_record > INPREC_RECORD_NORMAL) {
+                               if (DiskSelection (hDlg, wParam, 16, &workprefs, NULL)) {
+                                       TCHAR tmp[MAX_DPATH];
+                                       _tcscpy (tmp, workprefs.inprecfile);
+                                       _tcscat (tmp, L".uss");
+                                       inprec_save (workprefs.inprecfile, tmp);
+                                       statefile_save_recording (tmp);
+                                       workprefs.inprecfile[0] = 0;
+                               }
+                       }
                        break;
-               case IDC_INPREC_RECORD:
-                       if (input_recording)
-                               inprec_close ();
-                       else
-                               DiskSelection (hDlg, wParam, 16, &workprefs, NULL);
+               case IDC_STATEREC_RECORD:
+               {
+                       if (input_play) {
+                               inprec_playtorecord ();
+                       } else if (input_record) {
+                               inprec_close (true);
+                       } else {
+                               input_record = INPREC_RECORD_START;
+                               set_special (SPCFLAG_MODE_CHANGE);
+                       }
                        break;
-               case IDC_INPREC_PLAY:
-                       if (input_recording)
-                               inprec_close ();
-                       else
-                               DiskSelection (hDlg, wParam, 15, &workprefs, NULL);
+               }
+               case IDC_STATEREC_AUTOPLAY:
+                       workprefs.inprec_autoplay = ischecked (hDlg, IDC_STATEREC_AUTOPLAY) ? 1 : 0;
+                       break;
+               case IDC_STATEREC_PLAY:
+                       if (input_record)
+                               inprec_close (true);
+                       if (input_play) {
+                               inprec_close (true);
+                       } else {
+                               inprec_close (true);
+                               if (DiskSelection (hDlg, wParam, 15, &workprefs, NULL)) {
+                                       input_play = INPREC_PLAY_NORMAL;
+                                       _tcscpy (currprefs.inprecfile, workprefs.inprecfile);
+                                       set_special (SPCFLAG_MODE_CHANGE);
+                               }
+                       }
                        break;
-
 #ifdef PROWIZARD
                case IDC_PROWIZARD:
                        moduleripper ();
@@ -12993,15 +13018,12 @@ static INT_PTR CALLBACK AVIOutputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
 
                case IDC_AVIOUTPUT_ACTIVATED:
                        avioutput_requested = !avioutput_requested;
-                       SendMessage (hDlg, WM_HSCROLL, (WPARAM) NULL, (LPARAM) NULL);
                        if (!avioutput_requested)
                                AVIOutput_End ();
                        break;
-
                case IDC_SCREENSHOT:
                        screenshot(1, 0);
                        break;
-
                case IDC_AVIOUTPUT_AUDIO:
                        {
                                if (avioutput_enabled)
@@ -13014,7 +13036,6 @@ static INT_PTR CALLBACK AVIOutputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
                                }
                                break;
                        }
-
                case IDC_AVIOUTPUT_VIDEO:
                        {
                                if (avioutput_enabled)
@@ -13030,7 +13051,6 @@ static INT_PTR CALLBACK AVIOutputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
                                enable_for_avioutputdlg (hDlg);
                                break;
                        }
-
                case IDC_AVIOUTPUT_FILE:
                        {
                                OPENFILENAME ofn;
@@ -13063,7 +13083,23 @@ static INT_PTR CALLBACK AVIOutputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP
                                }
                                break;
                        }
-
+               }
+               if (HIWORD (wParam) == CBN_SELENDOK || HIWORD (wParam) == CBN_KILLFOCUS || HIWORD (wParam) == CBN_EDITCHANGE)  {
+                       switch (LOWORD (wParam))
+                       {
+                               case IDC_STATEREC_RATE:
+                                       getcbn (hDlg, IDC_STATEREC_RATE, tmp, sizeof tmp / sizeof (TCHAR));
+                                       workprefs.statecapturerate = _tstol (tmp) * 50;
+                                       if (workprefs.statecapturerate <= 0)
+                                               workprefs.statecapturerate = -1;
+                                       break;
+                               case IDC_STATEREC_BUFFERSIZE:
+                                       getcbn (hDlg, IDC_STATEREC_BUFFERSIZE, tmp, sizeof tmp / sizeof (TCHAR));
+                                       workprefs.statecapturebuffersize = _tstol (tmp);
+                                       if (workprefs.statecapturebuffersize <= 0)
+                                               workprefs.statecapturebuffersize = 100;
+                                       break;
+                       }
                }
 
                values_from_avioutputdlg (hDlg, msg, wParam, lParam);
index e4646355531829ea2e40f9ba242cc392a7c76fa4..1d2aa945265e899463fc6fe570592b1a7df2ea6e 100644 (file)
     <ClCompile Include="..\..\archivers\wrp\warp.cpp" />
     <ClCompile Include="..\..\archivers\zip\unzip.cpp" />
     <ClCompile Include="..\..\cpuemu_21.cpp" />
+    <ClCompile Include="..\..\inputrecord.cpp" />
+    <ClCompile Include="..\..\statusline.cpp" />
     <ClCompile Include="..\ahidsound_dsonly.cpp" />
     <ClCompile Include="..\ahidsound_new.cpp" />
     <ClCompile Include="..\avioutput.cpp" />
index 52500e767181ac208ad8c6510f5bd5ec83c7e432..e413e83b9ef69b3a7516c2aabca5710b2454c89f 100644 (file)
     <ClCompile Include="..\cda_play.cpp">
       <Filter>win32</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\inputrecord.cpp">
+      <Filter>common</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\statusline.cpp">
+      <Filter>common</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\resources\35floppy.ico">
index 26e5aff3b804b8e39988a931b5dd2b04abdf1325..77c0c21bf6a8956501e9819b3b2a41e3f2507504 100644 (file)
@@ -1,4 +1,85 @@
 
+Beta 1
+
+!!!!!! NOTE: Re-recorder discussion will be opened later in another thread. All posts related to new input recorder
+in this thread will disappear. !!!!!
+
+- directory filesystem ACTION_LOCK_RECORD and ACTION_FREE_RECORD dos packets implemented (very rarely used)
+- CDTV CDA playback didn't work if play ending track was set to last track (Prehistorik CDTV)
+- reset CD support internal flags when reseting or loading new configuration
+- save chipset extra setting to statefile, previously state restore always restored full
+  advanced chipset configuration and reset chipset extra setting
+- 3-stage 68020 cycle-exact prefetch pipeline (not much difference compared to old one)
+- do not emulate very small audio periods exactly in non-cycle exact modes, this combined with
+  very short samples used huge amounts of CPU power (used by some stupid audio routines) (2.3.0)
+- when restoring state, sound was initialized after first frame, could have caused glitches
+  or missing sound if audio registers were modified during first frame
+- mouse counters (JOYxDAT) were not restored from statefile, fixes random statefile restore mouse jump
+- VPOSW ECS/AGA-only LOL-bit (long line) is hardwired to zero (can't be modified) in standard PAL mode
+- SCSI emulation START/STOP UNIT translated to physical drive load/eject command
+- combined volume and period modulation was broken in 2.3 audio update (probably never used in real world..)
+- added "gamepad" device type to gameports panel, has two differences compared to "joystick", 3 buttons
+  mapped and pullup resistors emulated (most Amiga compatible gamepads have pullups). It is not possible
+  to have pullups automatically in joystick mode because it can break some badly programmed single-button
+  games, some detect always pressed button in this situation.. (fixes Aladdin and other games that
+  only have working 2nd button if buttons have pullup resistors)
+- allow scanning of plain roms (no archives) in winuae root directory
+- A2065 statefile support (autoconfig location saved), max allowed transmit size was too small, big packets
+  were silently dropped, random lost transmit interrupts, broadcast packets being ignored if NIC chip
+  hardware multicast filter was disabled
+- change emulated board filesystem and Z3 board IDs because of ID conflicts with QuickNet Z2 board (2011/2)
+- set default filter to 1x (was FS) and enable new "default" scaling method that only scales if window
+  size is set to "large enough" or so small that image wouldn't fit, always scales in fullscreen modes.
+- "autoresolution" checkbox added to Display panel, automatically selects lowest used resolution setting
+  (lores screen = lores/nondoubled, lores and hires at the same time = hires/nondoubled etc..) Positioning
+  may not work correctly yet, glitches possible.. Enable some autoscaling settings if you don't want changing
+  display size..
+- do not attempt to steal focus in magic mouse mode if WinUAE is not active, it only messes up focus state
+- A500 power led fade tricks should really work now
+- less accurate CIA register access timing in JIT modes (not really much point in accuracy..)
+- "re-recorder" implemented (completely rewritten combined input/state recorder). More information
+  coming later.
+
+- many statefile related changes for input/state recorder compatibility, may break something else..
+  - WARNING: statefiles created with betas may not be compatible with future versions!
+  - save current track's data and density in statefile if disk drive motor was active (regenerated
+    raw track data/density after state restore may not be identical if using ipf or fdi images)
+  - state save/restore while disk DMA is active is now fully supported
+  - save strings in utf8 (should have been done long time ago during unicode updates..)
+  - useless DMAC chunk was saved in non-CDTV configurations (2.3.0)
+  - CD state chunks were saved even if selected configuration didn't have any CD drives (2.3.0)
+  - 68020 cache and prefetch pipeline saved and restored
+  - debugger memory watchpoints saved and restored
+  - save active (very rare) interrupt delays (interrupts that have been triggered but have not yet
+    been noticed by Paula)
+  - mid-instruction CPU state save support, restored state CPU state is now exactly same
+    as when state was saved (68000 CE only, 68020 CE later), previously current instruction
+    was simply restarted (this was really complex and non-trivial task, it is only easy if you
+    accept much higher CPU usage. Which isn't good idea...)
+  - full blitter statefile support in cycle exact mode, state capture/input recorder only currently.
+  This saves blitter emulation variables, not real hardware state (internal statemachine state, latches,
+  counters etc..) because internal structure is unknown. State capture only because it requires 100%
+  identical state after restore (normal blitter state forces current blit to finish). This is not
+  enabled in normal state saving because it is very difficult to keep state saving compatibility
+  between versions when state is hardcoded to current emulation implementation.
+
+- input recorder and state recorder completely rewritten and merged, it is now "re-recorder"
+  - desynch issues fixed
+  - input recording file is linked to statefile, statefile is automatically loaded with input file
+  - statefile/inputfile pair plus including all used disk images will be saved to disk when
+    "save recording" button is clicked (does not stop recording, can be saved multiple times)
+  - buffer size configuration replaced with number of states buffered (circular buffer)
+  - rewind operation change, less than 0.5s from latest state: remove newest state and jump to
+    previous state, more than 0.5s from last state: jump to newest save
+  - "rewind" = "Load previous state capture checkpoint" input event or "Load current state capture
+    cheakpoint" = "rewind" to newest capture checkpoint, never earlier
+  - rewind restore graphics glitches fixed
+  - cdtv/cd32 support (state recorder only, cd timing is not compatible with input recorder)
+  - automatic in-memory input recording, rewind automatically starts input recorder playback (if enabled),
+    any user input event (or end of input data) restarts recording.
+  - save checkpoints manually by using "Save state capture checkpoint" input event
+
+
 Final 2.3.0
 
 Beta 20 (RC3):
index e65ac284bded0eb318845199f0b6f5bfb5d2f7b8..dd20d17d06b93471ccacf2f9c5afea41ab081da9 100644 (file)
@@ -367,8 +367,8 @@ static TCHAR *writets (void)
        p += _tcslen (p);
        _stprintf (p, L"%03d", tb.millitm);
        p += _tcslen (p);
-       if (timeframes || (vpos > 0 && current_hpos () > 0))
-               _stprintf (p, L" [%d %03dx%03d]", timeframes, current_hpos (), vpos);
+       if (vsync_counter != 0xffffffff)
+               _stprintf (p, L" [%d %03dx%03d]", vsync_counter, current_hpos (), vpos);
        _tcscat (p, L": ");
        return out;
 }
index c25c82f99647e64391ffddad48bbe8d01dd09f4f..6d24567afe6c83aaea993349fccd8f36c714bbc9 100644 (file)
 #include "gui.h"
 #include "audio.h"
 #include "filesys.h"
+#include "inputrecord.h"
+#include "disk.h"
 
 int savestate_state = 0;
+bool savestate_first_capture;
+
+static bool new_blitter = false;
 
-#define MAX_STATERECORDS 1024 /* must be power of 2 */
-struct staterecord {
-       uae_u8 *start;
-       uae_u8 *end;
-       uae_u8 *next;
-       uae_u8 *cpu;
-};
 static int replaycounter;
-static int replaylastreloaded = -1;
-static int frameextra;
 
 struct zfile *savestate_file;
-static uae_u8 *replaybuffer, *replaybufferend;
 static int savestate_docompress, savestate_specialdump, savestate_nodialogs;
-static int replaybuffersize;
 
 TCHAR savestate_fname[MAX_DPATH];
-static struct staterecord staterecords[MAX_STATERECORDS];
+
+#define STATEFILE_ALLOC_SIZE 600000
+static int statefile_alloc;
+static int staterecords_max = 1000;
+static int staterecords_first = 0;
+static struct zfile *staterecord_statefile;
+struct staterecord
+{
+       int len;
+       int inuse;
+       uae_u8 *cpu;
+       uae_u8 *data;
+       uae_u8 *end;
+       int inprecoffset;
+};
+
+static struct staterecord **staterecords;
 
 static void state_incompatible_warn (void)
 {
@@ -122,6 +132,29 @@ static void state_incompatible_warn (void)
 /* functions for reading/writing bytes, shorts and longs in big-endian
 * format independent of host machine's endianess */
 
+static uae_u8 *storepos;
+void save_store_pos_func (uae_u8 **dstp)
+{
+       storepos = *dstp;
+       *dstp += 4;
+}
+void save_store_size_func (uae_u8 **dstp)
+{
+       uae_u8 *p = storepos;
+       save_u32_func (&p, *dstp - storepos);
+}
+void restore_store_pos_func (uae_u8 **srcp)
+{
+       storepos = *srcp;
+       *srcp += 4;
+}
+void restore_store_size_func (uae_u8 **srcp)
+{
+       uae_u8 *p = storepos;
+       uae_u32 len = restore_u32_func (&p);
+       *srcp = storepos + len;
+}
+
 void save_u32_func (uae_u8 **dstp, uae_u32 v)
 {
        uae_u8 *dst = *dstp;
@@ -153,7 +186,7 @@ void save_string_func (uae_u8 **dstp, const TCHAR *from)
 {
        uae_u8 *dst = *dstp;
        char *s, *s2;
-       s2 = s = ua (from);
+       s2 = s = uutf8 (from);
        while (s && *s)
                *dst++ = *s++;
        *dst++ = 0;
@@ -209,7 +242,7 @@ TCHAR *restore_string_func (uae_u8 **dstp)
                *top++ = v;
        } while (v);
        *dstp = dst;
-       s = au (to);
+       s = utf8u (to);
        xfree (to);
        return s;
 }
@@ -420,6 +453,7 @@ void restore_state (const TCHAR *filename)
        zfile_fseek (f, 0, SEEK_END);
        filesize = zfile_ftell (f);
        zfile_fseek (f, 0, SEEK_SET);
+       savestate_state = STATE_RESTORE;
        savestate_init ();
 
        chunk = restore_chunk (f, name, &len, &totallen, &filepos);
@@ -427,6 +461,7 @@ void restore_state (const TCHAR *filename)
                write_log (L"%s is not an AmigaStateFile\n", filename);
                goto error;
        }
+       write_log (L"STATERESTORE:\n");
        config_changed = 1;
        savestate_file = f;
        restore_header (chunk);
@@ -439,7 +474,6 @@ void restore_state (const TCHAR *filename)
        changed_prefs.mbresmem_low_size = 0;
        changed_prefs.mbresmem_high_size = 0;
        z3num = 0;
-       savestate_state = STATE_RESTORE;
        for (;;) {
                name[0] = 0;
                chunk = end = restore_chunk (f, name, &len, &totallen, &filepos);
@@ -482,10 +516,14 @@ void restore_state (const TCHAR *filename)
                        restore_pram (totallen, filepos);
                        continue;
 #endif
+               } else if (!_tcscmp (name, L"CYCS")) {
+                       end = restore_cycles (chunk);
                } else if (!_tcscmp (name, L"CPU ")) {
                        end = restore_cpu (chunk);
                } else if (!_tcscmp (name, L"CPUX"))
                        end = restore_cpu_extra (chunk);
+               else if (!_tcscmp (name, L"CPUT"))
+                       end = restore_cpu_trace (chunk);
 #ifdef FPUEMU
                else if (!_tcscmp (name, L"FPU "))
                        end = restore_fpu (chunk);
@@ -522,6 +560,8 @@ void restore_state (const TCHAR *filename)
                        end = restore_input (chunk);
                else if (!_tcscmp (name, L"CHPX"))
                        end = restore_custom_extra (chunk);
+               else if (!_tcscmp (name, L"CHPD"))
+                       end = restore_custom_event_delay (chunk);
                else if (!_tcscmp (name, L"AUD0"))
                        end = restore_audio (0, chunk);
                else if (!_tcscmp (name, L"AUD1"))
@@ -532,6 +572,8 @@ void restore_state (const TCHAR *filename)
                        end = restore_audio (3, chunk);
                else if (!_tcscmp (name, L"BLIT"))
                        end = restore_blitter (chunk);
+               else if (!_tcscmp (name, L"BLTX"))
+                       end = restore_blitter_new (chunk);
                else if (!_tcscmp (name, L"DISK"))
                        end = restore_floppy (chunk);
                else if (!_tcscmp (name, L"DSK0"))
@@ -542,6 +584,14 @@ void restore_state (const TCHAR *filename)
                        end = restore_disk (2, chunk);
                else if (!_tcscmp (name, L"DSK3"))
                        end = restore_disk (3, chunk);
+               else if (!_tcscmp (name, L"DSD0"))
+                       end = restore_disk2 (0, chunk);
+               else if (!_tcscmp (name, L"DSD1"))
+                       end = restore_disk2 (1, chunk);
+               else if (!_tcscmp (name, L"DSD2"))
+                       end = restore_disk2 (2, chunk);
+               else if (!_tcscmp (name, L"DSD3"))
+                       end = restore_disk2 (3, chunk);
                else if (!_tcscmp (name, L"KEYB"))
                        end = restore_keyboard (chunk);
 #ifdef AUTOCONFIG
@@ -582,6 +632,12 @@ void restore_state (const TCHAR *filename)
                        end = restore_ide (chunk);
                else if (!_tcsncmp (name, L"CDU", 3))
                        end = restore_cd (name[3] - '0', chunk);
+               else if (!_tcsncmp (name, L"2065", 4))
+                       end = restore_a2065 (chunk);
+
+               else if (!_tcsncmp (name, L"DMWP", 4))
+                       end = restore_debug_memwatch (chunk);
+
                else if (!_tcscmp (name, L"CONF"))
                        end = restore_configuration (chunk);
                else if (!_tcscmp (name, L"LOG "))
@@ -598,11 +654,6 @@ void restore_state (const TCHAR *filename)
                        name, totallen, end - chunk);
                xfree (chunk);
        }
-       restore_disk_finish ();
-       restore_blitter_finish ();
-       restore_akiko_finish ();
-       restore_cdtv_finish ();
-       restore_p96_finish ();
        target_addtorecent (filename, 0);
        return;
 
@@ -617,17 +668,26 @@ error:
 
 void savestate_restore_finish (void)
 {
-       if (savestate_state != STATE_RESTORE && savestate_state != STATE_REWIND)
+       if (!isrestore ())
                return;
        zfile_fclose (savestate_file);
        savestate_file = 0;
-       savestate_state = 0;
        restore_cpu_finish ();
-       init_hz ();
+       restore_audio_finish ();
+       restore_disk_finish ();
+       restore_blitter_finish ();
+       restore_akiko_finish ();
+       restore_cdtv_finish ();
+       restore_p96_finish ();
+       restore_a2065_finish ();
+       restore_cia_finish ();
+       savestate_state = 0;
+       init_hz_full ();
+       audio_activate ();
 }
 
 /* 1=compressed,2=not compressed,3=ram dump,4=audio dump */
-void savestate_initsave (const TCHAR *filename, int mode, int nodialogs)
+void savestate_initsave (const TCHAR *filename, int mode, int nodialogs, bool save)
 {
        if (filename == NULL) {
                savestate_fname[0] = 0;
@@ -640,6 +700,11 @@ void savestate_initsave (const TCHAR *filename, int mode, int nodialogs)
        savestate_docompress = (mode == 1) ? 1 : 0;
        savestate_specialdump = (mode == 3) ? 1 : (mode == 4) ? 2 : 0;
        savestate_nodialogs = nodialogs;
+       new_blitter = false;
+       if (save) {
+               savestate_free ();
+               inprec_close (true);
+       }
 }
 
 static void save_rams (struct zfile *f, int comp)
@@ -675,52 +740,16 @@ static void save_rams (struct zfile *f, int comp)
 
 /* Save all subsystems */
 
-int save_state (const TCHAR *filename, const TCHAR *description)
+static int save_state_internal (struct zfile *f, const TCHAR *description, int comp, bool savepath)
 {
        uae_u8 endhunk[] = { 'E', 'N', 'D', ' ', 0, 0, 0, 8 };
        uae_u8 header[1000];
        TCHAR tmp[100];
        uae_u8 *dst;
-       struct zfile *f;
-       int len,i;
        TCHAR name[5];
-       int comp = savestate_docompress;
-
-       if (!savestate_specialdump && !savestate_nodialogs) {
-               state_incompatible_warn ();
-               if (!save_filesys_cando ()) {
-                       gui_message (L"Filesystem active. Try again later");
-                       return -1;
-               }
-       }
-       savestate_nodialogs = 0;
-       custom_prepare_savestate ();
-       f = zfile_fopen (filename, L"w+b", 0);
-       if (!f)
-               return 0;
-       if (savestate_specialdump) {
-               size_t pos;
-               if (savestate_specialdump == 2)
-                       write_wavheader (f, 0, 22050);
-               pos = zfile_ftell (f);
-               save_rams (f, -1);
-               if (savestate_specialdump == 2) {
-                       int len, len2, i;
-                       uae_u8 *tmp;
-                       len = zfile_ftell (f) - pos;
-                       tmp = xmalloc (uae_u8, len);
-                       zfile_fseek(f, pos, SEEK_SET);
-                       len2 = zfile_fread (tmp, 1, len, f);
-                       for (i = 0; i < len2; i++)
-                               tmp[i] += 0x80;
-                       write_wavheader (f, len, 22050);
-                       zfile_fwrite (tmp, len2, 1, f);
-                       xfree (tmp);
-               }
-               zfile_fclose (f);
-               return 1;
-       }
+       int i, len;
 
+       write_log (L"STATESAVE (%s):\n", f ? zfile_getname (f) : L"<internal>");
        dst = header;
        save_u32 (0);
        save_string (L"UAE");
@@ -729,6 +758,10 @@ int save_state (const TCHAR *filename, const TCHAR *description)
        save_string (description);
        save_chunk (f, header, dst-header, L"ASF ", 0);
 
+       dst = save_cycles (&len, 0);
+       save_chunk (f, dst, len, L"CYCS", 0);
+       xfree (dst);
+
        dst = save_cpu (&len, 0);
        save_chunk (f, dst, len, L"CPU ", 0);
        xfree (dst);
@@ -737,6 +770,10 @@ int save_state (const TCHAR *filename, const TCHAR *description)
        save_chunk (f, dst, len, L"CPUX", 0);
        xfree (dst);
 
+       dst = save_cpu_trace (&len, 0);
+       save_chunk (f, dst, len, L"CPUT", 0);
+       xfree (dst);
+
 #ifdef FPUEMU
        dst = save_fpu (&len,0 );
        save_chunk (f, dst, len, L"FPU ", 0);
@@ -751,21 +788,28 @@ int save_state (const TCHAR *filename, const TCHAR *description)
 
        _tcscpy(name, L"DSKx");
        for (i = 0; i < 4; i++) {
-               dst = save_disk (i, &len, 0);
+               dst = save_disk (i, &len, 0, savepath);
                if (dst) {
                        name[3] = i + '0';
                        save_chunk (f, dst, len, name, 0);
                        xfree (dst);
                }
        }
+       _tcscpy(name, L"DSDx");
+       for (i = 0; i < 4; i++) {
+               dst = save_disk2 (i, &len, 0);
+               if (dst) {
+                       name[3] = i + '0';
+                       save_chunk (f, dst, len, name, comp);
+                       xfree (dst);
+               }
+       }
+
+
        dst = save_floppy (&len, 0);
        save_chunk (f, dst, len, L"DISK", 0);
        xfree (dst);
 
-       dst = save_blitter (&len, 0);
-       save_chunk (f, dst, len, L"BLIT", 0);
-       xfree (dst);
-
        dst = save_custom (&len, 0, 0);
        save_chunk (f, dst, len, L"CHIP", 0);
        xfree (dst);
@@ -774,6 +818,19 @@ int save_state (const TCHAR *filename, const TCHAR *description)
        save_chunk (f, dst, len, L"CHPX", 0);
        xfree (dst);
 
+       dst = save_custom_event_delay (&len, 0);
+       save_chunk (f, dst, len, L"CHPD", 0);
+       xfree (dst);
+
+       dst = save_blitter_new (&len, 0);
+       save_chunk (f, dst, len, L"BLTX", 0);
+       xfree (dst);
+       if (new_blitter == false) {
+               dst = save_blitter (&len, 0);
+               save_chunk (f, dst, len, L"BLIT", 0);
+               xfree (dst);
+       }
+
        dst = save_input (&len, 0);
        save_chunk (f, dst, len, L"CINP", 0);
        xfree (dst);
@@ -806,7 +863,7 @@ int save_state (const TCHAR *filename, const TCHAR *description)
        save_chunk (f, dst, len, L"CIAB", 0);
        xfree (dst);
 
-       dst = save_keyboard (&len);
+       dst = save_keyboard (&len, NULL);
        save_chunk (f, dst, len, L"KEYB", 0);
        xfree (dst);
 
@@ -814,6 +871,8 @@ int save_state (const TCHAR *filename, const TCHAR *description)
        dst = save_expansion (&len, 0);
        save_chunk (f, dst, len, L"EXPA", 0);
 #endif
+       dst = save_a2065 (&len, NULL);
+       save_chunk (f, dst, len, L"2065", 0);
 #ifdef PICASSO96
        dst = save_p96 (&len, 0);
        save_chunk (f, dst, len, L"P96 ", 0);
@@ -829,23 +888,23 @@ int save_state (const TCHAR *filename, const TCHAR *description)
        } while ((dst = save_rom (0, &len, 0)));
 
 #ifdef CD32
-       dst = save_akiko (&len);
+       dst = save_akiko (&len, NULL);
        save_chunk (f, dst, len, L"CD32", 0);
        xfree (dst);
 #endif
 #ifdef CDTV
-       dst = save_cdtv (&len);
+       dst = save_cdtv (&len, NULL);
        save_chunk (f, dst, len, L"CDTV", 0);
        xfree (dst);
-       dst = save_dmac (&len);
+       dst = save_dmac (&len, NULL);
        save_chunk (f, dst, len, L"DMAC", 0);
        xfree (dst);
 #endif
 
 #ifdef ACTION_REPLAY
-       dst = save_action_replay (&len, 0);
+       dst = save_action_replay (&len, NULL);
        save_chunk (f, dst, len, L"ACTR", comp);
-       dst = save_hrtmon (&len, 0);
+       dst = save_hrtmon (&len, NULL);
        save_chunk (f, dst, len, L"HRTM", comp);
 #endif
 #ifdef FILESYS
@@ -861,13 +920,13 @@ int save_state (const TCHAR *filename, const TCHAR *description)
                }
        }
 #endif
-       dst = save_gayle (&len);
+       dst = save_gayle (&len, NULL);
        if (dst) {
                save_chunk (f, dst, len, L"GAYL", 0);
                xfree(dst);
        }
        for (i = 0; i < 4; i++) {
-               dst = save_ide (i, &len);
+               dst = save_ide (i, &len, NULL);
                if (dst) {
                        save_chunk (f, dst, len, L"IDE ", 0);
                        xfree (dst);
@@ -882,6 +941,12 @@ int save_state (const TCHAR *filename, const TCHAR *description)
                }
        }
 
+       dst = save_debug_memwatch (&len, NULL);
+       if (dst) {
+               save_chunk (f, dst, len, L"DMWP", 0);
+               xfree(dst);
+       }
+
        /* add fake END tag, makes it easy to strip CONF and LOG hunks */
        /* move this if you want to use CONF or LOG hunks when restoring state */
        zfile_fwrite (endhunk, 1, 8, f);
@@ -899,10 +964,55 @@ int save_state (const TCHAR *filename, const TCHAR *description)
 
        zfile_fwrite (endhunk, 1, 8, f);
 
-       write_log (L"Save of '%s' complete\n", filename);
+       return 1;
+}
+
+int save_state (const TCHAR *filename, const TCHAR *description)
+{
+       struct zfile *f;
+       int comp = savestate_docompress;
+
+       if (!savestate_specialdump && !savestate_nodialogs) {
+               state_incompatible_warn ();
+               if (!save_filesys_cando ()) {
+                       gui_message (L"Filesystem active. Try again later.");
+                       return -1;
+               }
+       }
+       new_blitter = false;
+       savestate_nodialogs = 0;
+       custom_prepare_savestate ();
+       f = zfile_fopen (filename, L"w+b", 0);
+       if (!f)
+               return 0;
+       if (savestate_specialdump) {
+               size_t pos;
+               if (savestate_specialdump == 2)
+                       write_wavheader (f, 0, 22050);
+               pos = zfile_ftell (f);
+               save_rams (f, -1);
+               if (savestate_specialdump == 2) {
+                       int len, len2, i;
+                       uae_u8 *tmp;
+                       len = zfile_ftell (f) - pos;
+                       tmp = xmalloc (uae_u8, len);
+                       zfile_fseek(f, pos, SEEK_SET);
+                       len2 = zfile_fread (tmp, 1, len, f);
+                       for (i = 0; i < len2; i++)
+                               tmp[i] += 0x80;
+                       write_wavheader (f, len, 22050);
+                       zfile_fwrite (tmp, len2, 1, f);
+                       xfree (tmp);
+               }
+               zfile_fclose (f);
+               return 1;
+       }
+       int v = save_state_internal (f, description, comp, true);
+       if (v)
+               write_log (L"Save of '%s' complete\n", filename);
        zfile_fclose (f);
        savestate_state = 0;
-       return 1;
+       return v;
 }
 
 void savestate_quick (int slot, int save)
@@ -937,29 +1047,54 @@ void savestate_quick (int slot, int save)
        }
 }
 
-static struct staterecord *canrewind (int pos)
+bool savestate_check (void)
 {
-       int i;
-       struct staterecord *st;
+       if (vpos == 0 && !savestate_state) {
+               if (hsync_counter == 0 && input_play == INPREC_PLAY_NORMAL)
+                       savestate_memorysave ();
+               savestate_capture (0);
+       }
+       if (savestate_state == STATE_DORESTORE) {
+               savestate_state = STATE_RESTORE;
+               return true;
+       } else if (savestate_state == STATE_DOREWIND) {
+               savestate_state = STATE_REWIND;
+               return true;
+       }
+       return false;
+}
+
+static int rewindmode;
 
-       if (!replaybuffer)
+
+static struct staterecord *canrewind (int pos)
+{
+       if (pos < 0)
+               pos += staterecords_max;
+       if (!staterecords)
                return 0;
-       i = replaycounter;
-       st = &staterecords[i];
-       if (st->start)
-               return st;
-       return 0;
+       if (staterecords[pos] == NULL)
+               return NULL;
+       if (staterecords[pos]->inuse == 0)
+               return NULL;
+       if ((pos + 1) % staterecords_max  == staterecords_first)
+               return NULL;
+       return staterecords[pos];
 }
 
 int savestate_dorewind (int pos)
 {
+       rewindmode = pos;
+       if (pos < 0)
+               pos = replaycounter - 1;
        if (canrewind (pos)) {
                savestate_state = STATE_DOREWIND;
+               write_log (L"dorewind %d (%010d/%03d) -> %d\n", replaycounter - 1, hsync_counter, vsync_counter, pos);
                return 1;
        }
        return 0;
 }
-
+#if 0
 void savestate_listrewind (void)
 {
        int i = replaycounter;
@@ -982,33 +1117,55 @@ void savestate_listrewind (void)
                        i += MAX_STATERECORDS;
        }
 }
+#endif
 
 void savestate_rewind (void)
 {
        int len, i, dummy;
        uae_u8 *p, *p2;
        struct staterecord *st;
+       int pos;
+       bool rewind = false;
 
-       st = canrewind (1);
-       if (!st)
-               return;
-       frameextra = timeframes % currprefs.statecapturerate;
-       p =  st->start;
+       if (hsync_counter % currprefs.statecapturerate <= 25 && rewindmode <= -2) {
+               pos = replaycounter - 2;
+               rewind = true;
+       } else {
+               pos = replaycounter - 1;
+       }
+       st = canrewind (pos);
+       if (!st) {
+               rewind = false;
+               pos = replaycounter - 1;
+               st = canrewind (pos);
+               if (!st)
+                       return;
+       }
+       p = st->data;
        p2 = st->end;
-       write_log (L"rewinding from %d\n", replaycounter);
+       write_log (L"rewinding %d -> %d\n", replaycounter - 1, pos);
+       hsync_counter = restore_u32_func (&p);
+       vsync_counter = restore_u32_func (&p);
        p = restore_cpu (p);
+       p = restore_cycles (p);
        p = restore_cpu_extra (p);
+       if (restore_u32_func (&p))
+               p = restore_cpu_trace (p);
 #ifdef FPUEMU
        if (restore_u32_func (&p))
                p = restore_fpu (p);
 #endif
        for (i = 0; i < 4; i++) {
                p = restore_disk (i, p);
+               if (restore_u32_func (&p))
+                       p = restore_disk2 (i, p);
        }
        p = restore_floppy (p);
        p = restore_custom (p);
        p = restore_custom_extra (p);
-       p = restore_blitter (p);
+       if (restore_u32_func (&p))
+               p = restore_custom_event_delay (p);
+       p = restore_blitter_new (p);
        p = restore_custom_agacolors (p);
        for (i = 0; i < 8; i++) {
                p = restore_custom_sprite (i, p);
@@ -1018,8 +1175,14 @@ void savestate_rewind (void)
        }
        p = restore_cia (0, p);
        p = restore_cia (1, p);
+       p = restore_keyboard (p);
+       p = restore_inputstate (p);
 #ifdef AUTOCONFIG
        p = restore_expansion (p);
+#endif
+#ifdef PICASSO96
+       if (restore_u32_func (&p))
+               p = restore_p96 (p);
 #endif
        len = restore_u32_func (&p);
        memcpy (chipmemory, p, currprefs.chipmem_size > len ? len : currprefs.chipmem_size);
@@ -1038,70 +1201,144 @@ void savestate_rewind (void)
 #ifdef ACTION_REPLAY
        if (restore_u32_func (&p))
                p = restore_action_replay (p);
+       if (restore_u32_func (&p))
+               p = restore_hrtmon (p);
+#endif
+#ifdef CD32
+       if (restore_u32_func (&p))
+               p = restore_akiko (p);
+#endif
+#ifdef CDTV
+       if (restore_u32_func (&p))
+               p = restore_cdtv (p);
+       if (restore_u32_func (&p))
+               p = restore_dmac (p);
 #endif
+       if (restore_u32_func (&p))
+               p = restore_gayle (p);
+       for (i = 0; i < 4; i++) {
+               if (restore_u32_func (&p))
+                       p = restore_ide (p);
+       }
        p += 4;
        if (p != p2) {
                gui_message (L"reload failure, address mismatch %p != %p", p, p2);
                uae_reset (0);
                return;
        }
-       st->start = st->next = 0;
-       replaycounter--;
-       if (replaycounter < 0)
-               replaycounter += MAX_STATERECORDS;
+       inprec_setposition (st->inprecoffset, pos);
+       write_log (L"state %d restored.  (%010d/%03d)\n", pos, hsync_counter, vsync_counter);
+       if (rewind) {
+               replaycounter--;
+               if (replaycounter < 0)
+                       replaycounter += staterecords_max;
+               st = canrewind (replaycounter);
+               st->inuse = 0;
+       }
+
 }
 
 #define BS 10000
 
-static int bufcheck (uae_u8 **pp, int len)
+STATIC_INLINE int bufcheck (struct staterecord *sr, uae_u8 *p, int len)
 {
-       uae_u8 *p = *pp;
-       if (p + len + BS >= replaybuffer + replaybuffersize) {
-               //write_log (L"capture buffer wrap-around\n");
+       if (p - sr->data + BS + len >= sr->len)
                return 1;
-       }
        return 0;
 }
 
+void savestate_memorysave (void)
+{
+       new_blitter = true;
+       // create real statefile in memory too for later saving
+       zfile_fclose (staterecord_statefile);
+       staterecord_statefile = zfile_fopen_empty (NULL, L"statefile.inp.uss");
+       if (staterecord_statefile)
+               save_state_internal (staterecord_statefile, L"rerecording", 1, false);
+}
+
 void savestate_capture (int force)
 {
        uae_u8 *p, *p2, *p3, *dst;
        int i, len, tlen, retrycnt;
-       struct staterecord *st, *stn;
+       struct staterecord *st;
+       bool firstcapture = false;
 
 #ifdef FILESYS
        if (nr_units ())
                return;
 #endif
-       if (!replaybuffer)
+       if (!staterecords)
                return;
-       if (!force && (!currprefs.statecapture || !currprefs.statecapturerate || ((timeframes + frameextra) % currprefs.statecapturerate)))
+       if (!input_record)
                return;
+       if (currprefs.statecapturerate && hsync_counter == 0 && input_record == INPREC_RECORD_START && savestate_first_capture) {
+               // first capture
+               force = true;
+               firstcapture = true;
+               savestate_first_capture = false;
+       }
+       if (!force) {
+               if (currprefs.statecapturerate <= 0)
+                       return;
+               if (hsync_counter % currprefs.statecapturerate)
+                       return;
+       }
 
        retrycnt = 0;
 retry2:
-       st = &staterecords[replaycounter];
-       if (st->next == 0) {
-               replaycounter = 0;
-               st = &staterecords[replaycounter];
-               st->next = replaybuffer;
+       st = staterecords[replaycounter];
+       if (st == NULL) {
+               st = (struct staterecord*)xmalloc (uae_u8, statefile_alloc);
+               st->len = statefile_alloc;
+       } else if (retrycnt > 0) {
+               st->len += STATEFILE_ALLOC_SIZE;
+               st = (struct staterecord*)xrealloc (uae_u8, st, st->len);
        }
-       stn = &staterecords[(replaycounter + 1) & (MAX_STATERECORDS - 1)];
-       p = p2 = st->next;
+       if (st->len > statefile_alloc)
+               statefile_alloc = st->len;
+       st->inuse = 0;
+       st->data = (uae_u8*)(st + 1);
+       staterecords[replaycounter] = st;
+       retrycnt++;
+       p = p2 = st->data;
        tlen = 0;
-       if (bufcheck (&p, 0))
+       save_u32_func (&p, hsync_counter);
+       save_u32_func (&p, vsync_counter);
+       tlen += 8;
+
+       if (bufcheck (st, p, 0))
                goto retry;
-       stn->cpu = p;
+       st->cpu = p;
        save_cpu (&len, p);
        tlen += len;
        p += len;
-       if (bufcheck (&p, 0))
+
+       if (bufcheck (st, p, 0))
+               goto retry;
+       save_cycles (&len, p);
+       tlen += len;
+       p += len;
+
+       if (bufcheck (st, p, 0))
                goto retry;
        save_cpu_extra (&len, p);
        tlen += len;
        p += len;
+
+       if (bufcheck (st, p, 0))
+               goto retry;
+       p3 = p;
+       save_u32_func (&p, 0);
+       tlen += 4;
+       if (save_cpu_trace (&len, p)) {
+               save_u32_func (&p3, 1);
+               tlen += len;
+               p += len;
+       }
+
 #ifdef FPUEMU
-       if (bufcheck (&p, 0))
+       if (bufcheck (st, p, 0))
                goto retry;
        p3 = p;
        save_u32_func (&p, 0);
@@ -1113,77 +1350,128 @@ retry2:
        }
 #endif
        for (i = 0; i < 4; i++) {
-               if (bufcheck (&p, 0))
+               if (bufcheck (st, p, 0))
                        goto retry;
-               save_disk (i, &len, p);
+               save_disk (i, &len, p, true);
                tlen += len;
                p += len;
+               p3 = p;
+               save_u32_func (&p, 0);
+               tlen += 4;
+               if (save_disk2 (i, &len, p)) {
+                       save_u32_func (&p3, 1);
+                       tlen += len;
+                       p += len;
+               }
        }
-       if (bufcheck (&p, 0))
+
+       if (bufcheck (st, p, 0))
                goto retry;
        save_floppy (&len, p);
        tlen += len;
        p += len;
-       if (bufcheck (&p, 0))
+
+       if (bufcheck (st, p, 0))
                goto retry;
        save_custom (&len, p, 0);
        tlen += len;
        p += len;
-       if (bufcheck (&p, 0))
+
+       if (bufcheck (st, p, 0))
                goto retry;
        save_custom_extra (&len, p);
        tlen += len;
        p += len;
-       if (bufcheck (&p, 0))
+
+       if (bufcheck (st, p, 0))
+               goto retry;
+       p3 = p;
+       save_u32_func (&p, 0);
+       tlen += 4;
+       if (save_custom_event_delay (&len, p)) {
+               save_u32_func (&p3, 1);
+               tlen += len;
+               p += len;
+       }
+
+       if (bufcheck (st, p, 0))
                goto retry;
-       save_blitter (&len, p);
+       save_blitter_new (&len, p);
        tlen += len;
        p += len;
-       if (bufcheck (&p, 0))
+
+       if (bufcheck (st, p, 0))
                goto retry;
        save_custom_agacolors (&len, p);
        tlen += len;
        p += len;
        for (i = 0; i < 8; i++) {
-               if (bufcheck (&p, 0))
+               if (bufcheck (st, p, 0))
                        goto retry;
                save_custom_sprite (i, &len, p);
                tlen += len;
                p += len;
        }
+
        for (i = 0; i < 4; i++) {
-               if (bufcheck (&p, 0))
+               if (bufcheck (st, p, 0))
                        goto retry;
                save_audio (i, &len, p);
                tlen += len;
                p += len;
        }
-       if (bufcheck (&p, 0))
+
+       if (bufcheck (st, p, len))
                goto retry;
        save_cia (0, &len, p);
        tlen += len;
        p += len;
-       if (bufcheck (&p, 0))
+
+       if (bufcheck (st, p, len))
                goto retry;
        save_cia (1, &len, p);
        tlen += len;
        p += len;
+
+       if (bufcheck (st, p, len))
+               goto retry;
+       save_keyboard (&len, p);
+       tlen += len;
+       p += len;
+
+       if (bufcheck (st, p, len))
+               goto retry;
+       save_inputstate (&len, p);
+       tlen += len;
+       p += len;
 #ifdef AUTOCONFIG
-       if (bufcheck (&p, 0))
+       if (bufcheck (st, p, len))
                goto retry;
        save_expansion (&len, p);
        tlen += len;
        p += len;
+#endif
+#ifdef PICASSO96
+       if (bufcheck (st, p, 0))
+               goto retry;
+       p3 = p;
+       save_u32_func (&p, 0);
+       tlen += 4;
+       if (save_p96 (&len, p)) {
+               save_u32_func (&p3, 1);
+               tlen += len;
+               p += len;
+       }
 #endif
        dst = save_cram (&len);
-       if (bufcheck (&p, len))
+       if (bufcheck (st, p, len))
                goto retry;
        save_u32_func (&p, len);
        memcpy (p, dst, len);
        tlen += len + 4;
        p += len;
        dst = save_bram (&len);
-       if (bufcheck (&p, len))
+       if (bufcheck (st, p, len))
                goto retry;
        save_u32_func (&p, len);
        memcpy (p, dst, len);
@@ -1191,14 +1479,14 @@ retry2:
        p += len;
 #ifdef AUTOCONFIG
        dst = save_fram (&len);
-       if (bufcheck (&p, len))
+       if (bufcheck (st, p, len))
                goto retry;
        save_u32_func (&p, len);
        memcpy (p, dst, len);
        tlen += len + 4;
        p += len;
        dst = save_zram (&len, 0);
-       if (bufcheck (&p, len))
+       if (bufcheck (st, p, len))
                goto retry;
        save_u32_func (&p, len);
        memcpy (p, dst, len);
@@ -1206,7 +1494,7 @@ retry2:
        p += len;
 #endif
 #ifdef ACTION_REPLAY
-       if (bufcheck (&p, 0))
+       if (bufcheck (st, p, 0))
                goto retry;
        p3 = p;
        save_u32_func (&p, 0);
@@ -1216,58 +1504,151 @@ retry2:
                tlen += len;
                p += len;
        }
+       if (bufcheck (st, p, 0))
+               goto retry;
+       p3 = p;
+       save_u32_func (&p, 0);
+       tlen += 4;
+       if (save_hrtmon (&len, p)) {
+               save_u32_func (&p3, 1);
+               tlen += len;
+               p += len;
+       }
 #endif
+#ifdef CD32
+       if (bufcheck (st, p, 0))
+               goto retry;
+       p3 = p;
+       save_u32_func (&p, 0);
+       tlen += 4;
+       if (save_akiko (&len, p)) {
+               save_u32_func (&p3, 1);
+               tlen += len;
+               p += len;
+       }
+#endif
+#ifdef CDTV
+       if (bufcheck (st, p, 0))
+               goto retry;
+       p3 = p;
+       save_u32_func (&p, 0);
+       tlen += 4;
+       if (save_cdtv (&len, p)) {
+               save_u32_func (&p3, 1);
+               tlen += len;
+               p += len;
+       }
+       if (bufcheck (st, p, 0))
+               goto retry;
+       p3 = p;
+       save_u32_func (&p, 0);
+       tlen += 4;
+       if (save_dmac (&len, p)) {
+               save_u32_func (&p3, 1);
+               tlen += len;
+               p += len;
+       }
+#endif
+       if (bufcheck (st, p, 0))
+               goto retry;
+       p3 = p;
+       save_u32_func (&p, 0);
+       tlen += 4;
+       if (save_gayle (&len, p)) {
+               save_u32_func (&p3, 1);
+               tlen += len;
+               p += len;
+       }
+       for (i = 0; i < 4; i++) {
+               if (bufcheck (st, p, 0))
+                       goto retry;
+               p3 = p;
+               save_u32_func (&p, 0);
+               tlen += 4;
+               if (save_ide (i, &len, p)) {
+                       save_u32_func (&p3, 1);
+                       tlen += len;
+                       p += len;
+               }
+       }
        save_u32_func (&p, tlen);
-       stn->next = p;
-       stn->start = p2;
-       stn->end = p;
-       replaylastreloaded = -1;
+       st->end = p;
+       st->inuse = 1;
+       st->inprecoffset = inprec_getposition ();
+
        replaycounter++;
-       replaycounter &= (MAX_STATERECORDS - 1);
-       i = (replaycounter + 1) & (MAX_STATERECORDS - 1);
-       staterecords[i].next = staterecords[i].start = 0;
-       i = replaycounter - 1;
-       while (i != replaycounter) {
-               if (i < 0)
-                       i += MAX_STATERECORDS;
-               st = &staterecords[i];
-               if (p2 <= st->start && p >= st->end) {
-                       st->start = st->next = 0;
-                       break;
+       if (replaycounter >= staterecords_max)
+               replaycounter -= staterecords_max;
+       if (replaycounter == staterecords_first) {
+               staterecords_first++;
+               if (staterecords_first >= staterecords_max)
+                       staterecords_first -= staterecords_max;
+       }
+
+       write_log (L"state capture %d (%010d/%03d,%d/%d) (%d bytes, alloc %d)\n",
+               replaycounter, hsync_counter, vsync_counter,
+               hsync_counter % current_maxvpos (), current_maxvpos (),
+               st->end - st->data, statefile_alloc);
+
+       if (firstcapture) {
+               savestate_memorysave ();
+               input_record++;
+               for (i = 0; i < 4; i++) {
+                       bool wp = true;
+                       DISK_validate_filename (currprefs.floppyslots[i].df, false, &wp, NULL, NULL);
+                       inprec_recorddiskchange (i, currprefs.floppyslots[i].df, wp);
                }
-               i--;
+               input_record--;
        }
-       //write_log (L"state capture %d (%d bytes)\n", replaycounter, p - p2);
+
+
        return;
 retry:
-       staterecords[replaycounter].next = replaybuffer;
-       retrycnt++;
-       if (retrycnt > 1) {
-               write_log (L"can't save, too small capture buffer\n");
-               return;
-       }
-       goto retry2;
+       if (retrycnt < 10)
+               goto retry2;
+       write_log (L"can't save, too small capture buffer or out of memory\n");
+       return;
 }
 
 void savestate_free (void)
 {
-       xfree (replaybuffer);
-       replaybuffer = 0;
+       xfree (staterecords);
+       staterecords = NULL;
 }
 
 void savestate_init (void)
 {
        savestate_free ();
-       memset (staterecords, 0, sizeof (staterecords));
        replaycounter = 0;
-       replaylastreloaded = -1;
-       frameextra = 0;
-       if (currprefs.statecapture && currprefs.statecapturebuffersize && currprefs.statecapturerate) {
-               replaybuffersize = currprefs.statecapturebuffersize;
-               replaybuffer = xmalloc (uae_u8, replaybuffersize);
+       staterecords_max = currprefs.statecapturebuffersize;
+       if (input_record && savestate_state != STATE_DORESTORE) {
+               zfile_fclose (staterecord_statefile);
+               staterecord_statefile = NULL;
+               inprec_close (false);
+               staterecords = xcalloc (struct staterecord*, staterecords_max);
+               statefile_alloc = STATEFILE_ALLOC_SIZE;
+               inprec_open (NULL, NULL);
+               savestate_first_capture = true;
        }
 }
 
+
+void statefile_save_recording (const TCHAR *filename)
+{
+       if (!staterecord_statefile)
+               return;
+       struct zfile *zf = zfile_fopen (filename, L"wb", 0);
+       if (zf) {
+               int len = zfile_size (staterecord_statefile);
+               uae_u8 *data = zfile_getdata (staterecord_statefile, 0, len);
+               zfile_fwrite (data, len, 1, zf);
+               xfree (data);
+               zfile_fclose (zf);
+               write_log (L"input statefile '%s' saved\n", filename);
+       }
+}
+
+
 /*
 
 My (Toni Wilen <twilen@arabuusimiehet.com>)
diff --git a/statusline.cpp b/statusline.cpp
new file mode 100644 (file)
index 0000000..27d8522
--- /dev/null
@@ -0,0 +1,213 @@
+#include "sysconfig.h"
+#include "sysdeps.h"
+
+#include <ctype.h>
+#include <assert.h>
+
+#include "options.h"
+#include "uae.h"
+#include "xwin.h"
+#include "gui.h"
+#include "custom.h"
+#include "drawing.h"
+#include "statusline.h"
+
+/*
+* Some code to put status information on the screen.
+*/
+
+static const char *numbers = { /* ugly  0123456789CHD%+- */
+       "+++++++--++++-+++++++++++++++++-++++++++++++++++++++++++++++++++++++++++++++-++++++-++++----++---+--------------"
+       "+xxxxx+--+xx+-+xxxxx++xxxxx++x+-+x++xxxxx++xxxxx++xxxxx++xxxxx++xxxxx++xxxx+-+x++x+-+xxx++-+xx+-+x---+----------"
+       "+x+++x+--++x+-+++++x++++++x++x+++x++x++++++x++++++++++x++x+++x++x+++x++x++++-+x++x+-+x++x+--+x++x+--+x+----+++--"
+       "+x+-+x+---+x+-+xxxxx++xxxxx++xxxxx++xxxxx++xxxxx+--++x+-+xxxxx++xxxxx++x+----+xxxx+-+x++x+----+x+--+xxx+--+xxx+-"
+       "+x+++x+---+x+-+x++++++++++x++++++x++++++x++x+++x+--+x+--+x+++x++++++x++x++++-+x++x+-+x++x+---+x+x+--+x+----+++--"
+       "+xxxxx+---+x+-+xxxxx++xxxxx+----+x++xxxxx++xxxxx+--+x+--+xxxxx++xxxxx++xxxx+-+x++x+-+xxx+---+x++xx--------------"
+       "+++++++---+++-++++++++++++++----+++++++++++++++++--+++--++++++++++++++++++++-++++++-++++------------------------"
+};
+
+STATIC_INLINE uae_u32 ledcolor (uae_u32 c, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc, uae_u32 *a)
+{
+       uae_u32 v = rc[(c >> 16) & 0xff] | gc[(c >> 8) & 0xff] | bc[(c >> 0) & 0xff];
+       if (a)
+               v |= a[255 - ((c >> 24) & 0xff)];
+       return v;
+}
+
+static void write_tdnumber (uae_u8 *buf, int bpp, int x, int y, int num, uae_u32 c1, uae_u32 c2)
+{
+       int j;
+       const char *numptr;
+
+       numptr = numbers + num * TD_NUM_WIDTH + NUMBERS_NUM * TD_NUM_WIDTH * y;
+       for (j = 0; j < TD_NUM_WIDTH; j++) {
+               if (*numptr == 'x')
+                       putpixel (buf, bpp, x + j, c1, 1);
+               else if (*numptr == '+')
+                       putpixel (buf, bpp, x + j, c2, 0);
+               numptr++;
+       }
+}
+
+void draw_status_line_single (uae_u8 *buf, int bpp, int y, int totalwidth, uae_u32 *rc, uae_u32 *gc, uae_u32 *bc, uae_u32 *alpha)
+{
+       int x_start, j, led, border;
+       uae_u32 c1, c2, cb;
+
+       c1 = ledcolor (0x00ffffff, rc, gc, bc, alpha);
+       c2 = ledcolor (0x00000000, rc, gc, bc, alpha);
+       cb = ledcolor (TD_BORDER, rc, gc, bc, alpha);
+
+       if (td_pos & TD_RIGHT)
+               x_start = totalwidth - TD_PADX - VISIBLE_LEDS * TD_WIDTH;
+       else
+               x_start = TD_PADX;
+
+       for (led = 0; led < LED_MAX; led++) {
+               int side, pos, num1 = -1, num2 = -1, num3 = -1, num4 = -1;
+               int x, c, on = 0, am = 2;
+               xcolnr on_rgb, on_rgb2, off_rgb, pen_rgb;
+               int half = 0;
+
+               pen_rgb = c1;
+               if (led >= LED_DF0 && led <= LED_DF3) {
+                       int pled = led - LED_DF0;
+                       int track = gui_data.drive_track[pled];
+                       pos = 6 + pled;
+                       on_rgb = 0x00cc00;
+                       on_rgb2 = 0x006600;
+                       off_rgb = 0x003300;
+                       if (!gui_data.drive_disabled[pled]) {
+                               num1 = -1;
+                               num2 = track / 10;
+                               num3 = track % 10;
+                               on = gui_data.drive_motor[pled];
+                               if (gui_data.drive_writing[pled]) {
+                                       on_rgb = 0xcc0000;
+                                       on_rgb2 = 0x880000;
+                               }
+                               half = gui_data.drive_side ? 1 : -1;
+                               if (gui_data.df[pled][0] == 0)
+                                       pen_rgb = ledcolor (0x00aaaaaa, rc, gc, bc, alpha);
+                       }
+                       side = gui_data.drive_side;
+               } else if (led == LED_POWER) {
+                       pos = 3;
+                       on_rgb = ((gui_data.powerled_brightness * 10 / 16) + 0x33) << 16;
+                       on = 1;
+                       off_rgb = 0x330000;
+               } else if (led == LED_CD) {
+                       pos = 5;
+                       on = gui_data.cd & (LED_CD_AUDIO | LED_CD_ACTIVE);
+                       on_rgb = (on & LED_CD_AUDIO) ? 0x00cc00 : 0x0000cc;
+                       if ((gui_data.cd & LED_CD_ACTIVE2) && !(gui_data.cd & LED_CD_AUDIO)) {
+                               on_rgb &= 0xfefefe;
+                               on_rgb >>= 1;
+                       }
+                       off_rgb = 0x000033;
+                       num1 = -1;
+                       num2 = 10;
+                       num3 = 12;
+               } else if (led == LED_HD) {
+                       pos = 4;
+                       on = gui_data.hd;
+                       on_rgb = on == 2 ? 0xcc0000 : 0x0000cc;
+                       off_rgb = 0x000033;
+                       num1 = -1;
+                       num2 = 11;
+                       num3 = 12;
+               } else if (led == LED_FPS) {
+                       int fps = (gui_data.fps + 5) / 10;
+                       pos = 2;
+                       on_rgb = 0x000000;
+                       off_rgb = 0x000000;
+                       if (fps > 999)
+                               fps = 999;
+                       num1 = fps / 100;
+                       num2 = (fps - num1 * 100) / 10;
+                       num3 = fps % 10;
+                       am = 3;
+                       if (num1 == 0)
+                               am = 2;
+               } else if (led == LED_CPU) {
+                       int idle = (gui_data.idle + 5) / 10;
+                       pos = 1;
+                       on = framecnt && !picasso_on;
+                       on_rgb = 0xcc0000;
+                       off_rgb = 0x000000;
+                       num1 = idle / 100;
+                       num2 = (idle - num1 * 100) / 10;
+                       num3 = idle % 10;
+                       num4 = num1 == 0 ? 13 : -1;
+                       am = 3;
+               } else if (led == LED_SND) {
+                       int snd = abs(gui_data.sndbuf + 5) / 10;
+                       if (snd > 99)
+                               snd = 99;
+                       pos = 0;
+                       on = gui_data.sndbuf_status;
+                       if (on < 3) {
+                               num1 = gui_data.sndbuf < 0 ? 15 : 14;
+                               num2 = snd / 10;
+                               num3 = snd % 10;
+                       }
+                       on_rgb = 0x000000;
+                       if (on < 0)
+                               on_rgb = 0xcccc00; // underflow
+                       else if (on == 2)
+                               on_rgb = 0xcc0000; // really big overflow
+                       else if (on == 1)
+                               on_rgb = 0x0000cc; // "normal" overflow
+                       off_rgb = 0x000000;
+                       am = 3;
+               } else if (led == LED_MD && gui_data.drive_disabled[3]) {
+                       // DF3 reused as internal non-volatile ram led (cd32/cdtv)
+                       pos = 6 + 3;
+                       on = gui_data.md;
+                       on_rgb = on == 2 ? 0xcc0000 : 0x00cc00;
+                       off_rgb = 0x003300;
+                       num1 = -1;
+                       num2 = -1;
+                       num3 = -1;
+               } else
+                       return;
+               on_rgb |= 0x33000000;
+               off_rgb |= 0x33000000;
+               if (half > 0) {
+                       c = ledcolor (on ? (y >= TD_TOTAL_HEIGHT / 2 ? on_rgb2 : on_rgb) : off_rgb, rc, gc, bc, alpha);
+               } else if (half < 0) {
+                       c = ledcolor (on ? (y < TD_TOTAL_HEIGHT / 2 ? on_rgb2 : on_rgb) : off_rgb, rc, gc, bc, alpha);
+               } else {
+                       c = ledcolor (on ? on_rgb : off_rgb, rc, gc, bc, alpha);
+               }
+               border = 0;
+               if (y == 0 || y == TD_TOTAL_HEIGHT - 1) {
+                       c = ledcolor (TD_BORDER, rc, gc, bc, alpha);
+                       border = 1;
+               }
+
+               x = x_start + pos * TD_WIDTH;
+               if (!border)
+                       putpixel (buf, bpp, x - 1, cb, 0);
+               for (j = 0; j < TD_LED_WIDTH; j++)
+                       putpixel (buf, bpp, x + j, c, 0);
+               if (!border)
+                       putpixel (buf, bpp, x + j, cb, 0);
+
+               if (y >= TD_PADY && y - TD_PADY < TD_NUM_HEIGHT) {
+                       if (num3 >= 0) {
+                               x += (TD_LED_WIDTH - am * TD_NUM_WIDTH) / 2;
+                               if (num1 > 0) {
+                                       write_tdnumber (buf, bpp, x, y - TD_PADY, num1, pen_rgb, c2);
+                                       x += TD_NUM_WIDTH;
+                               }
+                               write_tdnumber (buf, bpp, x, y - TD_PADY, num2, pen_rgb, c2);
+                               x += TD_NUM_WIDTH;
+                               write_tdnumber (buf, bpp, x, y - TD_PADY, num3, pen_rgb, c2);
+                               x += TD_NUM_WIDTH;
+                               if (num4 > 0)
+                                       write_tdnumber (buf, bpp, x, y - TD_PADY, num4, pen_rgb, c2);
+                       }
+               }
+       }
+}
index bdc4ec3ab7b0fc0b553046e390df1eae0050348c..742315b92f5d734b40d3d27ae06b8779c965c92e 100644 (file)
--- a/traps.cpp
+++ b/traps.cpp
@@ -166,7 +166,7 @@ void REGPARAM2 m68k_handle_trap (unsigned int trap_num)
 
                        if (implicit_rts) {
                                m68k_do_rts ();
-                               fill_prefetch_slow ();
+                               fill_prefetch ();
                        }
                }
        } else
@@ -318,7 +318,7 @@ static uae_u32 trap_Call68k (TrapContext *context, uaecptr func_addr)
        /* Set PC to address of 68k call trap, so that it will be
        * executed when emulator context resumes. */
        m68k_setpc (m68k_call_trapaddr);
-       fill_prefetch_slow ();
+       fill_prefetch ();
 
        /* Switch to emulator context. */
        uae_sem_post (&context->switch_to_emu_sem);
@@ -359,7 +359,7 @@ static uae_u32 REGPARAM3 m68k_call_handler (TrapContext *dummy_ctx)
 
        /* Set PC to address of 68k function to call. */
        m68k_setpc (context->call68k_func_addr);
-       fill_prefetch_slow ();
+       fill_prefetch ();
 
        /* End critical section: allow other traps run. */
        uae_sem_post (&trap_mutex);
index 10e6697ddaf841adcae7143fe94cc0d54962bc1c..24285bf4a1c395456d356f1a2f44b6409b5c7e2d 100644 (file)
@@ -36,7 +36,7 @@ void gui_message (const TCHAR *format, ...)
 {
 }
 
-int uaerand (void)
+uae_u32 uaerand (void)
 {
        return rand ();
 }
@@ -377,7 +377,7 @@ static int unpack (const TCHAR *src, const TCHAR *filename, const TCHAR *dst, in
        TCHAR fn[MAX_DPATH];
 
        ret = 0;
-       zv = zfile_fopen_archive_root (src, ZFD_ALL | ZFD_NORECURSE);
+       zv = zfile_fopen_archive_root (src, ZFD_ALL);
        if (zv == NULL) {
                geterror();
                _tprintf (L"Couldn't open archive '%s'\n", src);
@@ -457,7 +457,10 @@ static int unpack (const TCHAR *src, const TCHAR *filename, const TCHAR *dst, in
        }
        geterror ();
        if (!found && !level) {
-               _tprintf (L"'%s' not found\n", fn);
+               if (dst[0])
+                       _tprintf (L"'%s' not found\n", dst);
+               else
+                       _tprintf (L"nothing extracted\n");
        }
        return ret;
 }
@@ -472,7 +475,7 @@ static int unpack2 (const TCHAR *src, const TCHAR *match, int level)
        TCHAR fn[MAX_DPATH];
 
        ret = 0;
-       zv = zfile_fopen_archive_root (src, ZFD_ALL | ZFD_NORECURSE);
+       zv = zfile_fopen_archive_root (src, ZFD_ALL);
        if (zv == NULL) {
                geterror();
                _tprintf (L"Couldn't open archive '%s'\n", src);
@@ -698,7 +701,7 @@ int __cdecl wmain (int argc, wchar_t *argv[], wchar_t *envp[])
                ok = 1;
        }
        if (!ok) {
-               _tprintf (L"UAE unpacker uaeunp 0.8c by Toni Wilen (c)2010\n");
+               _tprintf (L"UAE unpacker uaeunp 0.8d by Toni Wilen (c)2010\n");
                _tprintf (L"\n");
                _tprintf (L"List: \"uaeunp (-l) <path>\"\n");
                _tprintf (L"List all recursively: \"uaeunp -l <path> **\"\n");
index 6a294b2a1d80eea240bea5db0e8733785773175a..4bfad15bc895dacf182b978299e45ae27543b051 100644 (file)
--- a/zfile.cpp
+++ b/zfile.cpp
@@ -1827,7 +1827,6 @@ static struct zfile *zfile_fopenx2 (const TCHAR *name, const TCHAR *mode, int ma
 {
        struct zfile *f;
        TCHAR tmp[MAX_DPATH];
-       TCHAR dirsep[2] = { FSDB_DIR_SEPARATOR, '\0' };
 
 #ifdef _WIN32
        if (isinternetfile (name))
@@ -1880,7 +1879,11 @@ struct zfile *zfile_fopen (const TCHAR *name, const TCHAR *mode, int mask)
 {
        return zfile_fopenx (name, mode, mask, 0);
 }
-struct zfile *zfile_fopen2 (const TCHAR *name, const TCHAR *mode, int mask, int index)
+struct zfile *zfile_fopen (const TCHAR *name, const TCHAR *mode)
+{
+       return zfile_fopenx (name, mode, 0, 0);
+}
+struct zfile *zfile_fopen (const TCHAR *name, const TCHAR *mode, int mask, int index)
 {
        return zfile_fopenx (name, mode, mask, index);
 }
@@ -1956,15 +1959,17 @@ struct zfile *zfile_fopen_empty (struct zfile *prev, const TCHAR *name, uae_u64
                }
                l->size = size;
                l->datasize = size;
+               l->allocsize = size;
        } else {
-               l->data = xcalloc (uae_u8, 1);
+               l->data = xcalloc (uae_u8, 1000);
                l->size = 0;
+               l->allocsize = 1000;
        }
        return l;
 }
 struct zfile *zfile_fopen_empty (struct zfile *prev, const TCHAR *name)
 {
-       return zfile_fopen_empty (prev, name, 10000);
+       return zfile_fopen_empty (prev, name, 0);
 }
 
 struct zfile *zfile_fopen_parent (struct zfile *z, const TCHAR *name, uae_u64 offset, uae_u64 size)
@@ -2006,6 +2011,24 @@ struct zfile *zfile_fopen_data (const TCHAR *name, uae_u64 size, uae_u8 *data)
        return l;
 }
 
+int zfile_truncate (struct zfile *z, uae_s64 size)
+{
+       if (z->data) {
+               if (z->size > size) {
+                       z->size = size;
+                       if (z->datasize > z->size)
+                               z->datasize = z->size;
+                       if (z->seek > z->size)
+                               z->seek = z->size;
+                       return 1;
+               }
+               return 0;
+       } else {
+               /* !!! */
+               return 0;
+       }
+}
+
 uae_s64 zfile_size (struct zfile *z)
 {
        return z->size;
@@ -2108,12 +2131,25 @@ size_t zfile_fwrite (void *b, size_t l1, size_t l2, struct zfile *z)
                return 0;
        if (z->data) {
                int off = z->seek + l1 * l2;
-               if (off > z->size) {
-                       z->data = xrealloc (uae_u8, z->data, off);
+               if (z->allocsize == 0) {
+                       write_log (L"zfile_fwrite(data,%s) but allocsize=0!\n", z->name);
+                       return 0;
+               }
+               if (off > z->allocsize) {
+                       if (z->allocsize < off)
+                               z->allocsize = off;
+                       z->allocsize += z->size / 2;
+                       if (z->allocsize < 10000)
+                               z->allocsize = 10000;
+                       z->data = xrealloc (uae_u8, z->data, z->allocsize);
                        z->datasize = z->size = off;
                }
                memcpy (z->data + z->seek, b, l1 * l2);
                z->seek += l1 * l2;
+               if (z->seek > z->size)
+                       z->size = z->seek;
+               if (z->size > z->datasize)
+                       z->datasize = z->size;
                return l2;
        }
        return fwrite (b, l1, l2, z->f);
@@ -2219,7 +2255,7 @@ int zfile_ferror (struct zfile *z)
 
 uae_u8 *zfile_getdata (struct zfile *z, uae_s64 offset, int len)
 {
-       uae_s64 pos;
+       uae_s64 pos = zfile_ftell (z);
        uae_u8 *b;
        if (len < 0) {
                zfile_fseek (z, 0, SEEK_END);
@@ -2227,7 +2263,6 @@ uae_u8 *zfile_getdata (struct zfile *z, uae_s64 offset, int len)
                zfile_fseek (z, 0, SEEK_SET);
        }
        b = xmalloc (uae_u8, len);
-       pos = zfile_ftell (z);
        zfile_fseek (z, offset, SEEK_SET);
        zfile_fread (b, len, 1, z);
        zfile_fseek (z, pos, SEEK_SET);
@@ -2336,7 +2371,6 @@ static struct zvolume *zvolume_list;
 
 static void recurparent (TCHAR *newpath, struct znode *zn, int recurse)
 {
-       TCHAR tmp[2] = { FSDB_DIR_SEPARATOR, 0 };
        if (zn->parent && (&zn->volume->root != zn->parent || zn->volume->parentz == NULL)) {
                if (&zn->volume->root == zn->parent && zn->volume->parentz == NULL && !_tcscmp (zn->name, zn->parent->name))
                        goto end;
@@ -2348,7 +2382,7 @@ static void recurparent (TCHAR *newpath, struct znode *zn, int recurse)
        }
 end:
        if (newpath[0])
-               _tcscat (newpath, tmp);
+               _tcscat (newpath, FSDB_DIR_SEPARATOR_S);
        _tcscat (newpath, zn->name);
 }
 
@@ -2358,7 +2392,6 @@ static struct znode *znode_alloc (struct znode *parent, const TCHAR *name)
        TCHAR tmpname[MAX_DPATH];
        struct znode *zn = xcalloc (struct znode, 1);
        struct znode *zn2;
-       TCHAR sep[] = { FSDB_DIR_SEPARATOR, 0 };
 
        _tcscpy (tmpname, name);
        zn2 = parent->child;
@@ -2385,7 +2418,7 @@ static struct znode *znode_alloc (struct znode *parent, const TCHAR *name)
 
        fullpath[0] = 0;
        recurparent (fullpath, parent, FALSE);
-       _tcscat (fullpath, sep);
+       _tcscat (fullpath, FSDB_DIR_SEPARATOR_S);
        _tcscat (fullpath, tmpname);
 #ifdef ZFILE_DEBUG
        write_log (L"znode_alloc vol='%s' parent='%s' name='%s'\n", parent->volume->root.name, parent->name, name);
@@ -2601,7 +2634,7 @@ static struct zvolume *zfile_fopen_archive_data (struct znode *parent, struct zf
 
 static struct znode *get_znode (struct zvolume *zv, const TCHAR *ppath, int);
 
-static void zfile_fopen_archive_recurse2 (struct zvolume *zv, struct znode *zn)
+static void zfile_fopen_archive_recurse2 (struct zvolume *zv, struct znode *zn, int flags)
 {
        struct zvolume *zvnew;
        struct znode *zndir;
@@ -2628,7 +2661,7 @@ static void zfile_fopen_archive_recurse2 (struct zvolume *zv, struct znode *zn)
        }
 }
 
-static int zfile_fopen_archive_recurse (struct zvolume *zv)
+static int zfile_fopen_archive_recurse (struct zvolume *zv, int flags)
 {
        struct znode *zn;
        int i, added;
@@ -2642,7 +2675,7 @@ static int zfile_fopen_archive_recurse (struct zvolume *zv)
                if (ext && !zn->vchild && zn->type == ZNODE_FILE) {
                        for (i = 0; !done && archive_extensions[i]; i++) {
                                if (!strcasecmp (ext + 1, archive_extensions[i])) {
-                                       zfile_fopen_archive_recurse2 (zv, zn);
+                                       zfile_fopen_archive_recurse2 (zv, zn, flags);
                                        done = 1;
                                }
                        }
@@ -2650,7 +2683,7 @@ static int zfile_fopen_archive_recurse (struct zvolume *zv)
                if (!done) {
                        z = archive_getzfile (zn, zv->method, 0);
                        if (z && iszip (z))
-                               zfile_fopen_archive_recurse2 (zv, zn);
+                               zfile_fopen_archive_recurse2 (zv, zn, flags);
                }
                zn = zn->next;
        }
@@ -2673,7 +2706,7 @@ static struct zvolume *prepare_recursive_volume (struct zvolume *zv, const TCHAR
        if (!zvnew && !(flags & ZFD_NORECURSE)) {
 #if 1
                zvnew = archive_directory_plain (zf);
-               zfile_fopen_archive_recurse (zvnew);
+               zfile_fopen_archive_recurse (zvnew, flags);
                done = 1;
 #else
                int rc;
@@ -2705,7 +2738,7 @@ static struct zvolume *prepare_recursive_volume (struct zvolume *zv, const TCHAR
 #endif
        } else {
                zvnew->parent = zv->parent;
-               zfile_fopen_archive_recurse (zvnew);
+               zfile_fopen_archive_recurse (zvnew, flags);
                done = 1;
        }
        if (!done)
@@ -2787,11 +2820,10 @@ struct znode *znode_adddir (struct znode *parent, const TCHAR *name, struct zarc
 {
        struct znode *zn;
        TCHAR path[MAX_DPATH];
-       TCHAR sep[] = { FSDB_DIR_SEPARATOR, 0 };
 
        path[0] = 0;
        recurparent (path, parent, FALSE);
-       _tcscat (path, sep);
+       _tcscat (path, FSDB_DIR_SEPARATOR_S);
        _tcscat (path, name);
        zn = get_znode (parent->volume, path, FALSE);
        if (zn)
@@ -2932,7 +2964,7 @@ struct zvolume *zfile_fopen_archive (const TCHAR *filename, int flags)
 
 #if RECURSIVE_ARCHIVES
        if (zv && !(flags & ZFD_NORECURSE))
-               zfile_fopen_archive_recurse (zv);
+               zfile_fopen_archive_recurse (zv, flags);
 #endif
 
        if (zv)
index 082d8906b0125c4cbc1f7f9971fcbea8f488a8e6..848b353869ec83716cf9f29eca20bcfab778df9f 100644 (file)
@@ -1064,7 +1064,7 @@ static struct zfile *archive_access_plain (struct znode *zn)
        if (zn->offset) {
                struct zfile *zf;
                z = zfile_fopen_empty (zn->volume->archive, zn->fullname, zn->size);
-               zf = zfile_fopen2 (zfile_getname (zn->volume->archive), L"rb", zn->volume->archive->zfdmask & ~ZFD_ADF, zn->offset - 1);
+               zf = zfile_fopen (zfile_getname (zn->volume->archive), L"rb", zn->volume->archive->zfdmask & ~ZFD_ADF, zn->offset - 1);
                if (zf) {
                        zfile_fread (z->data, zn->size, 1, zf);
                        zfile_fclose (zf);