]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
imported winuaesrc1620b8.zip
authorToni Wilen <twilen@winuae.net>
Wed, 19 Aug 2009 15:35:15 +0000 (18:35 +0300)
committerToni Wilen <twilen@winuae.net>
Mon, 22 Feb 2010 19:47:57 +0000 (21:47 +0200)
20 files changed:
akiko.c
audio.c
cfgfile.c
custom.c
gencpu.c
gfxutil.c
include/cpu_prefetch.h
include/events.h
include/newcpu.h
include/options.h
include/xwin.h
main.c
newcpu.c
od-win32/srcrelease.cmd
od-win32/sysconfig.h
od-win32/win32.h
od-win32/win32gfx.c
od-win32/win32gui.c
od-win32/winuae_msvc/winuae_msvc.vcproj
od-win32/winuaechangelog.txt

diff --git a/akiko.c b/akiko.c
index 8b86dfa64505d420e98cf919dd4f53160c55c0b4..ed30efecad02123989c9c7828e84ecc1df2b7ab7 100644 (file)
--- a/akiko.c
+++ b/akiko.c
@@ -337,12 +337,22 @@ static uae_u32 akiko_c2p_read (int offset)
  * this piece of crap emulates real CD32 CDROM controller and drive :)
  */
 
-#define CDSTATUS_FRAME             0x80000000
-#define CDSTATUS_UNK1              0x40000000 /* not used by ROM */
-#define CDSTATUS_UNK2              0x20000000 /* not used by ROM */
-#define CDSTATUS_DATA_AVAILABLE            0x10000000
-#define CDSTATUS_DATASECTOR_ERROR   0x08000000 /* ?? */
-#define CDSTATUS_DATASECTOR        0x04000000
+#define CDINTERRUPT_SUBCODE        0x80000000
+#define CDINTERRUPT_DRIVEXMIT      0x40000000 /* not used by ROM */
+#define CDINTERRUPT_DRIVERECV      0x20000000 /* not used by ROM */
+#define CDINTERRUPT_RXDMADONE      0x10000000
+#define CDINTERRUPT_TXDMADONE      0x08000000
+#define CDINTERRUPT_PBX                    0x04000000
+#define CDINTERRUPT_OVERFLOW       0x02000000
+
+#define CDFLAG_SUBCODE             0x80000000
+#define CDFLAG_TXD                 0x40000000
+#define CDFLAG_RXD                 0x20000000
+#define CDFLAG_CAS                 0x10000000
+#define CDFLAG_PBX                 0x08000000
+#define CDFLAG_ENABLE              0x04000000
+#define CDFLAG_RAW                 0x02000000
+#define CDFLAG_MSB                 0x01000000
 
 #define CDS_ERROR 0x80
 #define CDS_PLAYING 0x08
@@ -368,15 +378,16 @@ static uae_u32 akiko_c2p_read (int offset)
 #define CH_ERR_ABNORMALSEEK     0xf0 // %11110000
 #define CH_ERR_NODISK           0xf8 // %11111000
 
-static uae_u32 cdrom_status1, cdrom_status2;
-static uae_u8 cdrom_status3;
-static uae_u32 cdrom_address1, cdrom_address2;
-static uae_u32 cdrom_longmask;
-static uae_u32 cdrom_readmask;
-static uae_u8 cdrom_command_offset_complete; /* 0x19 */
-static uae_u8 cdrom_command_offset_todo; /* 0x1d */
-static uae_u8 cdrom_result_complete; /* 0x1a */
-static uae_u8 cdrom_result_last_pos; /* 0x1f */
+static uae_u32 cdrom_intreq, cdrom_intena;
+static uae_u8 cdrom_subcodeoffset;
+static uae_u32 cdrom_addressdata, cdrom_addressmisc;
+static uae_u32 subcode_address, cdrx_address, cdtx_address;
+static uae_u32 cdrom_flags;
+static uae_u32 cdrom_pbx;
+
+static uae_u8 cdcomtxinx; /* 0x19 */
+static uae_u8 cdcomrxinx; /* 0x1a */
+static uae_u8 cdcomtxcmp; /* 0x1d */
 static uae_u8 cdrom_result_buffer[32];
 static uae_u8 cdrom_command_buffer[32];
 static uae_u8 cdrom_command;
@@ -400,6 +411,8 @@ static int cdrom_data_end, cdrom_leadout;
 static int cdrom_audiotimeout;
 static int cdrom_led;
 static int cdrom_dosomething;
+static int cdrom_receive_started;
+static int cd_initialized;
 
 static uae_u8 *sector_buffer_1, *sector_buffer_2;
 static int sector_buffer_sector_1, sector_buffer_sector_2;
@@ -417,13 +430,13 @@ static volatile int akiko_thread_running;
 
 static void checkint (void)
 {
-    if (cdrom_status1 & cdrom_status2)
+    if (cdrom_intreq & cdrom_intena)
        irq ();
 }
 
 static void set_status (uae_u32 status)
 {
-    cdrom_status1 |= status;
+    cdrom_intreq |= status;
     checkint ();
 }
 
@@ -569,7 +582,7 @@ static int cd_qcode (uae_u8 *d)
     d[9] = tobcd (s[6]);
     d[10] = tobcd (s[7]);
     if (as == 0x15) {
-       /* Make sure end of disc position is passed.
+       /* Make sure end of disc position is not missed.
         */
        int lsn = msf2lsn ((s[5] << 16) | (s[6] << 8) | (s[7] << 0));
        int msf = lsn2msf (cdrom_leadout);
@@ -709,13 +722,23 @@ static void sys_cddev_close (void)
 
 static int command_lengths[] = { 1,2,1,1,12,2,1,1,4,1,-1,-1,-1,-1,-1,-1 };
 
-static void cdrom_return_data (int len)
+static void cdrom_start_return_data (int len)
 {
-    uae_u32 cmd_buf = cdrom_address2;
+    if (len <= 0 || cdrom_receive_started > 0)
+       return;
+    cdrom_receive_started = len;
+}
+
+static void cdrom_return_data (void)
+{
+    uae_u32 cmd_buf = cdrx_address;
     int i;
     uae_u8 checksum;
+    int len = cdrom_receive_started;
 
-    if (len <= 0)
+    if (!len)
+       return;
+    if (!(cdrom_flags & CDFLAG_RXD))
        return;
 #if AKIKO_DEBUG_IO_CMD
     write_log (L"OUT:");
@@ -723,18 +746,19 @@ static void cdrom_return_data (int len)
     checksum = 0xff;
     for (i = 0; i < len; i++) {
        checksum -= cdrom_result_buffer[i];
-       put_byte (cmd_buf + ((cdrom_result_complete + i) & 0xff), cdrom_result_buffer[i]);
+       put_byte (cmd_buf + ((cdcomrxinx + i) & 0xff), cdrom_result_buffer[i]);
 #if AKIKO_DEBUG_IO_CMD
        write_log (L"%02X ", cdrom_result_buffer[i]);
 #endif
     }
-    put_byte (cmd_buf + ((cdrom_result_complete + len) & 0xff), checksum);
+    put_byte (cmd_buf + ((cdcomrxinx + len) & 0xff), checksum);
 #if AKIKO_DEBUG_IO_CMD
     write_log (L"%02X\n", checksum);
 #endif
-    cdrom_result_complete += len + 1;
-    cdrom_result_complete &= 0xff;
-    set_status (CDSTATUS_DATA_AVAILABLE);
+    cdcomrxinx += len + 1;
+    cdcomrxinx &= 0xff;
+    set_status (CDINTERRUPT_RXDMADONE);
+    cdrom_receive_started = 0;
 }
 
 static int cdrom_command_led (void)
@@ -744,7 +768,7 @@ static int cdrom_command_led (void)
     cdrom_led = v & 1;
     if (cdrom_led != old)
        gui_cd_led (0, cdrom_led ? 1 : -1);
-    if (v & 0x80) {
+    if (v & 0x80) { // result wanted?
        cdrom_result_buffer[0] = cdrom_command;
        cdrom_result_buffer[1] = cdrom_led;
        return 2;
@@ -769,6 +793,7 @@ static int cdrom_command_status (void)
     /* firmware info */
     strcpy (cdrom_result_buffer + 2, FIRMWAREVERSION);
     cdrom_result_buffer[0] = cdrom_command;
+    cd_initialized = 1;
     return 20;
 }
 
@@ -903,18 +928,20 @@ static int cdrom_command_subq (void)
 
 static void cdrom_run_command (void)
 {
-    uae_u32 cmd_buf = cdrom_address2 + 0x200;
     int i, cmd_len;
     uae_u8 checksum;
+    uae_u8 *pp = get_real_address (cdtx_address);
 
     for (;;) {
        if (cdrom_command_active)
            return;
-       if (cdrom_command_offset_complete == cdrom_command_offset_todo)
+       if (cdcomtxinx == cdcomtxcmp)
            return;
-       cdrom_command = get_byte (cmd_buf + cdrom_command_offset_complete);
-       if ((cdrom_command & 0xf0) == 0)
+       cdrom_command = get_byte (cdtx_address + cdcomtxinx);
+       if ((cdrom_command & 0xf0) == 0) {
+           cdcomtxinx = (cdcomtxinx + 1) & 0xff;
            return;
+       }
        cdrom_checksum_error = 0;
        cmd_len = command_lengths[cdrom_command & 0x0f];
        if (cmd_len < 0) {
@@ -928,13 +955,13 @@ static void cdrom_run_command (void)
 #endif
        checksum = 0;
        for (i = 0; i < cmd_len + 1; i++) {
-           cdrom_command_buffer[i] = get_byte (cmd_buf + ((cdrom_command_offset_complete + i) & 0xff));
+           cdrom_command_buffer[i] = get_byte (cdtx_address + ((cdcomtxinx + i) & 0xff));
            checksum += cdrom_command_buffer[i];
 #if AKIKO_DEBUG_IO_CMD
            write_log (L"%02X ", cdrom_command_buffer[i]);
 #endif
        }
-       if (checksum!=0xff) {
+       if (checksum != 0xff) {
 #if AKIKO_DEBUG_IO_CMD
            write_log (L" checksum error");
 #endif
@@ -945,6 +972,7 @@ static void cdrom_run_command (void)
 #endif
        cdrom_command_active = 1;
        cdrom_command_length = cmd_len;
+       set_status (CDINTERRUPT_TXDMADONE);
        return;
     }
 }
@@ -953,7 +981,7 @@ static void cdrom_run_command_run (void)
 {
     int len;
 
-    cdrom_command_offset_complete = (cdrom_command_offset_complete + cdrom_command_length + 1) & 0xff;
+    cdcomtxinx = (cdcomtxinx + cdrom_command_length + 1) & 0xff;
     memset (cdrom_result_buffer, 0, sizeof (cdrom_result_buffer));
     switch (cdrom_command & 0x0f)
     {
@@ -984,7 +1012,7 @@ static void cdrom_run_command_run (void)
        return;
     if (cdrom_checksum_error)
        cdrom_result_buffer[1] |= 0x80;
-    cdrom_return_data (len);
+    cdrom_start_return_data (len);
 }
 
 extern void encode_l2 (uae_u8 *p, int address);
@@ -997,13 +1025,13 @@ static void cdrom_run_read (void)
     int sec;
     static int seccnt;
 
-    if (!(cdrom_longmask & 0x04000000))
+    if (!(cdrom_flags & CDFLAG_ENABLE))
        return;
-    if (!cdrom_readmask) {
-       cdrom_longmask &= ~0x08000000;
+    if (!cdrom_pbx) {
+       set_status (CDINTERRUPT_OVERFLOW);
        return;
     }
-    if (!(cdrom_longmask & 0x08000000))
+    if (!(cdrom_flags & CDFLAG_PBX))
        return;
     if (cdrom_data_offset < 0)
        return;
@@ -1013,40 +1041,38 @@ static void cdrom_run_read (void)
     inc = 1;
     // always use highest available slot or Lotus 3 (Lotus Trilogy) fails to load
     for (seccnt = 15; seccnt >= 0; seccnt--) {
-       if (cdrom_readmask & (1 << seccnt))
+       if (cdrom_pbx & (1 << seccnt))
            break;
     }
-    if (cdrom_readmask & (1 << seccnt)) {
-        sector = cdrom_current_sector = cdrom_data_offset + cdrom_sector_counter;
-       sec = sector - sector_buffer_sector_1;
-       if (sector_buffer_sector_1 >= 0 && sec >= 0 && sec < SECTOR_BUFFER_SIZE) {
-           if (sector_buffer_info_1[sec] != 0xff && sector_buffer_info_1[sec] != 0) {
-               uae_u8 buf[2352];
-
-               memcpy (buf + 16, sector_buffer_1 + sec * 2048, 2048);
-               encode_l2 (buf, sector + 150);
-               buf[0] = 0;
-               buf[1] = 0;
-               buf[2] = 0;
-               buf[3] = cdrom_sector_counter & 31;
-               for (i = 0; i < 2352; i++)
-                   put_byte (cdrom_address1 + seccnt * 4096 + i, buf[i]);
-               for (i = 0; i < 73 * 2; i++)
-                   put_byte (cdrom_address1 + seccnt * 4096 + 0xc00 + i, 0);
-               cdrom_readmask &= ~(1 << seccnt);
-               set_status (CDSTATUS_DATASECTOR);
-           } else {
-               inc = 0;
-           }
-           if (sector_buffer_info_1[sec] != 0xff)
-               sector_buffer_info_1[sec]--;
-#if AKIKO_DEBUG_IO_CMD
-           write_log (L"read sector=%d, scnt=%d -> %d. %08X\n",
-               cdrom_data_offset, cdrom_sector_counter, sector, cdrom_address1 + seccnt * 4096);
-#endif
+    sector = cdrom_current_sector = cdrom_data_offset + cdrom_sector_counter;
+    sec = sector - sector_buffer_sector_1;
+    if (sector_buffer_sector_1 >= 0 && sec >= 0 && sec < SECTOR_BUFFER_SIZE) {
+        if (sector_buffer_info_1[sec] != 0xff && sector_buffer_info_1[sec] != 0) {
+           uae_u8 buf[2352];
+
+           memcpy (buf + 16, sector_buffer_1 + sec * 2048, 2048);
+           encode_l2 (buf, sector + 150);
+           buf[0] = 0;
+           buf[1] = 0;
+           buf[2] = 0;
+           buf[3] = cdrom_sector_counter & 31;
+           for (i = 0; i < 2352; i++)
+               put_byte (cdrom_addressdata + seccnt * 4096 + i, buf[i]);
+           for (i = 0; i < 73 * 2; i++)
+               put_byte (cdrom_addressdata + seccnt * 4096 + 0xc00 + i, 0);
+           cdrom_pbx &= ~(1 << seccnt);
+           set_status (CDINTERRUPT_PBX);
        } else {
            inc = 0;
        }
+       if (sector_buffer_info_1[sec] != 0xff)
+           sector_buffer_info_1[sec]--;
+#if AKIKO_DEBUG_IO_CMD
+       write_log (L"read sector=%d, scnt=%d -> %d. %08X\n",
+           cdrom_data_offset, cdrom_sector_counter, sector, cdrom_addressdata + seccnt * 4096);
+#endif
+    } else {
+        inc = 0;
     }
     if (inc)
        cdrom_sector_counter++;
@@ -1059,15 +1085,19 @@ static void akiko_handler (void)
 {
     if (unitnum < 0)
        return;
-    if (cdrom_result_complete > cdrom_result_last_pos && cdrom_result_complete - cdrom_result_last_pos < 100) {
-       //set_status (CDSTATUS_DATA_AVAILABLE);
+    if (!cd_initialized || cdrom_receive_started)
+       return;
+#if 0
+    if (cdrom_result_complete > cdcomrxcmp && cdrom_result_complete - cdcomrxcmp < 100) {
+       //set_status (CDINTERRUPT_RXDMADONE);
        return;
     }
-    if (cdrom_result_last_pos < cdrom_result_complete)
+    if (cdcomrxcmp < cdrom_result_complete)
        return;
+#endif
     if (mediachanged) {
        mediachanged = 0;
-        cdrom_return_data (cdrom_command_media_status ());
+        cdrom_start_return_data (cdrom_command_media_status ());
        if (!lastmediastate)
            cd_hunt = 1;
        cdrom_toc ();
@@ -1076,7 +1106,7 @@ static void akiko_handler (void)
        return;
     }
     if (cdrom_toc_counter >= 0 && !cdrom_command_active && cdrom_dosomething) {
-       cdrom_return_data (cdrom_return_toc_entry ());
+       cdrom_start_return_data (cdrom_return_toc_entry ());
        cdrom_dosomething--;
        return;
     }
@@ -1086,6 +1116,7 @@ static void akiko_internal (void)
 {
     if (!currprefs.cs_cd32cd)
        return;
+    cdrom_return_data ();
     cdrom_run_command ();
     if (cdrom_command_active > 0) {
        cdrom_command_active--;
@@ -1133,6 +1164,7 @@ void AKIKO_hsync_handler (void)
 
     framecounter--;
     if (framecounter <= 0) {
+       int i;
        if (cdrom_led)
            gui_cd_led (0, 1);
        if (cdrom_seek_delay <= 0) {
@@ -1140,9 +1172,18 @@ void AKIKO_hsync_handler (void)
        } else {
            cdrom_seek_delay--;
        }
-       framecounter = 1000000 / (59 * 75 * cdrom_speed);
-       set_status (CDSTATUS_FRAME);
-       cdrom_status3++;
+       framecounter = 1000000 / (58 * 75 * cdrom_speed);
+       if (cdrom_flags & CDFLAG_SUBCODE) {
+           set_status (CDINTERRUPT_SUBCODE);
+           if (cdrom_subcodeoffset >= 128)
+               cdrom_subcodeoffset = 0;
+           else
+               cdrom_subcodeoffset = 128;
+           for (i = 0; i < 100; i += 4) {
+               put_long (subcode_address + cdrom_subcodeoffset, 0);
+               cdrom_subcodeoffset += 4;
+           }
+       }
     }
 
     if (frame2counter > 0)
@@ -1154,10 +1195,10 @@ void AKIKO_hsync_handler (void)
        if (cdrom_audiotimeout > 0) {
            cdrom_audiotimeout--;
            if (cdrom_audiotimeout == 0) {
-               set_status (CDSTATUS_DATA_AVAILABLE);
+               set_status (CDINTERRUPT_RXDMADONE);
                cdrom_playing = 0;
                cdrom_result_buffer[1] = 0;
-               cdrom_return_data (2);
+               cdrom_start_return_data (2);
            }
        }
     }
@@ -1332,54 +1373,51 @@ static uae_u32 akiko_bget2 (uaecptr addr, int msg)
        case 0x05:
        case 0x06:
        case 0x07:
-           v = akiko_get_long (cdrom_status1, addr - 0x04);
+           v = akiko_get_long (cdrom_intreq, addr - 0x04);
            break;
        case 0x08:
        case 0x09:
        case 0x0a:
        case 0x0b:
-           v = akiko_get_long (cdrom_status2, addr - 0x08);
+           v = akiko_get_long (cdrom_intena, addr - 0x08);
            break;
        case 0x10:
        case 0x11:
        case 0x12:
        case 0x13:
-           v = akiko_get_long (cdrom_address1, addr - 0x10);
+           v = akiko_get_long (cdrom_addressdata, addr - 0x10);
            break;
        case 0x14:
        case 0x15:
        case 0x16:
        case 0x17:
-           v = akiko_get_long (cdrom_address2, addr - 0x14);
+           v = akiko_get_long (cdrom_addressmisc, addr - 0x14);
            break;
        case 0x18:
-           v = cdrom_status3;
+           v = cdrom_subcodeoffset;
            break;
        case 0x19:
-           v = cdrom_command_offset_complete;
+           v = cdcomtxinx;
            break;
        case 0x1a:
-           v = cdrom_result_complete;
-           break;
-       case 0x1f:
-           v = cdrom_result_last_pos;
+           v = cdcomrxinx;
            break;
        case 0x20:
        case 0x21:
-           v = akiko_get_long (cdrom_readmask, addr - 0x20 + 2);
+           v = akiko_get_long (cdrom_pbx, addr - 0x20 + 2);
            break;
        case 0x24:
        case 0x25:
        case 0x26:
        case 0x27:
-           v = akiko_get_long (cdrom_longmask, addr - 0x24);
+           v = akiko_get_long (cdrom_flags, addr - 0x24);
            break;
        } else if (addr < 0x30) {
            break;
        }
 
        default:
-       write_log (L"akiko_bget: unknown address %08X\n", addr);
+       write_log (L"akiko_bget: unknown address %08X PC=%08X\n", addr, M68K_GETPC);
        v = 0;
        break;
     }
@@ -1466,74 +1504,68 @@ static void akiko_bput2 (uaecptr addr, uae_u32 v, int msg)
        case 0x05:
        case 0x06:
        case 0x07:
-           akiko_put_long (&cdrom_status1, addr - 0x04, v);
+           akiko_put_long (&cdrom_intreq, addr - 0x04, v);
            break;
        case 0x08:
        case 0x09:
        case 0x0a:
        case 0x0b:
-           akiko_put_long (&cdrom_status2, addr - 0x08, v);
+           akiko_put_long (&cdrom_intena, addr - 0x08, v);
            if (addr == 8)
-               cdrom_status1 &= cdrom_status2;
+               cdrom_intreq &= cdrom_intena;
            break;
        case 0x10:
        case 0x11:
        case 0x12:
        case 0x13:
-           akiko_put_long (&cdrom_address1, addr - 0x10, v);
-           cdrom_address1 &= ~0xffff;
+           akiko_put_long (&cdrom_addressdata, addr - 0x10, v);
+           cdrom_addressdata &= 0x00ff0000;
            break;
        case 0x14:
        case 0x15:
        case 0x16:
        case 0x17:
-           akiko_put_long (&cdrom_address2, addr - 0x14, v);
+           akiko_put_long (&cdrom_addressmisc, addr - 0x14, v);
+           cdrom_addressmisc &= 0x00fffc00;
+           subcode_address = cdrom_addressmisc | 0x100;
+           cdrx_address = cdrom_addressmisc;
+           cdtx_address = cdrom_addressmisc | 0x200;
            break;
        case 0x18:
-           if (cdrom_status3 > 7)
-               cdrom_status3 = 7;
-           if (cdrom_status3 > 0)
-               cdrom_status3--;
-           if (cdrom_status3 == 0)
-               cdrom_status1 &= ~CDSTATUS_FRAME;
-           break;
-       case 0x19:
-           cdrom_command_offset_complete = v;
-           break;
-       case 0x1a:
-           cdrom_result_complete = v;
+           cdrom_intreq &= ~CDINTERRUPT_SUBCODE;
            break;
        case 0x1d:
-           cdrom_command_offset_todo = v;
+           cdrom_intreq &= ~CDINTERRUPT_TXDMADONE;
+           cdcomtxcmp = v;
            break;
        case 0x1f:
-           cdrom_result_last_pos = v;
+           cdrom_intreq &= ~CDINTERRUPT_RXDMADONE;
            break;
        case 0x20:
        case 0x21:
-           tmp = cdrom_readmask;
-           akiko_put_long (&cdrom_readmask, addr - 0x20 + 2, v);
-           cdrom_readmask |= tmp;
-           cdrom_readmask &= 0xffff;
-           cdrom_status1 &= ~CDSTATUS_DATASECTOR;
+           tmp = cdrom_pbx;
+           akiko_put_long (&cdrom_pbx, addr - 0x20 + 2, v);
+           cdrom_pbx |= tmp;
+           cdrom_pbx &= 0xffff;
+           cdrom_intreq &= ~CDINTERRUPT_PBX;
            break;
        case 0x24:
        case 0x25:
        case 0x26:
        case 0x27:
-           tmp = cdrom_longmask;
-           akiko_put_long (&cdrom_longmask, addr - 0x24, v);
-           if ((cdrom_longmask & 0x04000000) && !(tmp & 0x04000000))
+           tmp = cdrom_flags;
+           akiko_put_long (&cdrom_flags, addr - 0x24, v);
+           if ((cdrom_flags & CDFLAG_ENABLE) && !(tmp & CDFLAG_ENABLE))
                cdrom_sector_counter = 0;
-           if (!(cdrom_longmask & 0x08000000) && (tmp & 0x08000000))
-               cdrom_readmask = 0;
+           if (!(cdrom_flags & CDFLAG_PBX) && (tmp & CDFLAG_PBX))
+               cdrom_pbx = 0;
            break;
        } else if (addr < 0x30) {
            break;
        }
 
        default:
-       write_log (L"akiko_bput: unknown address %08X\n", addr);
+       write_log (L"akiko_bput: unknown address %08X=%02X PC=%08X\n", addr, v & 0xff, M68K_GETPC);
        break;
     }
     akiko_internal ();
@@ -1607,10 +1639,13 @@ void akiko_reset (void)
 
     cdrom_speed = 1;
     cdrom_current_sector = -1;
-    cdrom_command_offset_complete = 0;
-    cdrom_command_offset_todo = 0;
+    cdcomtxinx = 0;
+    cdcomrxinx = 0;
+    cdcomtxcmp = 0;
     cdrom_led = 0;
     lastmediastate = 0;
+    cdrom_receive_started = 0;
+    cd_initialized = 0;
 
     if (akiko_thread_running > 0) {
        cdaudiostop ();
@@ -1673,22 +1708,22 @@ uae_u8 *save_akiko(int *len)
     dstbak = dst = malloc (1000);
     save_u16 (0);
     save_u16 (0xCAFE);
-    save_u32 (cdrom_status1);
-    save_u32 (cdrom_status2);
+    save_u32 (cdrom_intreq);
+    save_u32 (cdrom_intena);
     save_u32 (0);
-    save_u32 (cdrom_address1);
-    save_u32 (cdrom_address2);
-    save_u8 (cdrom_status3);
-    save_u8 (cdrom_command_offset_complete);
-    save_u8 (cdrom_result_complete);
+    save_u32 (cdrom_addressdata);
+    save_u32 (cdrom_addressmisc);
+    save_u8 (cdrom_subcodeoffset);
+    save_u8 (cdcomrxinx);
+    save_u8 (cdcomrxinx);
+    save_u8 (0);
     save_u8 (0);
+    save_u8 (cdcomtxcmp);
     save_u8 (0);
-    save_u8 (cdrom_command_offset_todo);
     save_u8 (0);
-    save_u8 (cdrom_result_last_pos);
-    save_u16 ((uae_u16)cdrom_readmask);
+    save_u16 ((uae_u16)cdrom_pbx);
     save_u16 (0);
-    save_u32 (cdrom_longmask);
+    save_u32 (cdrom_flags);
     save_u32 (0);
     save_u32 (0);
     save_u32 ((scl_dir ? 0x8000 : 0) | (sda_dir ? 0x4000 : 0));
@@ -1731,22 +1766,22 @@ uae_u8 *restore_akiko (uae_u8 *src)
 
     restore_u16 ();
     restore_u16 ();
-    cdrom_status1 = restore_u32 ();
-    cdrom_status2 = restore_u32 ();
+    cdrom_intreq = restore_u32 ();
+    cdrom_intena = restore_u32 ();
     restore_u32 ();
-    cdrom_address1 = restore_u32 ();
-    cdrom_address2 = restore_u32 ();
-    cdrom_status3 = restore_u8 ();
-    cdrom_command_offset_complete = restore_u8 ();
-    cdrom_result_complete = restore_u8 ();
+    cdrom_addressdata = restore_u32 ();
+    cdrom_addressmisc = restore_u32 ();
+    cdrom_subcodeoffset = restore_u8 ();
+    cdcomtxinx = restore_u8 ();
+    cdcomrxinx = restore_u8 ();
+    restore_u8 ();
     restore_u8 ();
+    cdcomtxcmp = restore_u8 ();
     restore_u8 ();
-    cdrom_command_offset_todo = restore_u8 ();
     restore_u8 ();
-    cdrom_result_last_pos = restore_u8 ();
-    cdrom_readmask = restore_u16 ();
+    cdrom_pbx = restore_u16 ();
     restore_u16 ();
-    cdrom_longmask = restore_u32 ();
+    cdrom_flags = restore_u32 ();
     restore_u32 ();
     restore_u32 ();
     v = restore_u32 ();
diff --git a/audio.c b/audio.c
index 8319e321bc58560765216cbc9aa523e1d2468efd..ce1bd6a32afe6b566d7461733fcbf6f55ccd7644 100644 (file)
--- a/audio.c
+++ b/audio.c
@@ -1889,7 +1889,7 @@ void audio_vsync (void)
     static int lastdir;
 
     min = -10 * 10;
-    max = (isfullscreen () > 0 && currprefs.gfx_avsync) ? 10 * 10 : 20 * 10;
+    max = (isfullscreen () > 0 && currprefs.gfx_avsync > 0) ? 10 * 10 : 20 * 10;
     extrasamples = 0;
     if (gui_data.sndbuf < min) {
        // add extra sample
index 31c353b9e5abcbbc90e7e0bf2a2c4dc5492dfacb..d0fa9b57db07ea3755f8871f7ece3ce63b7de2cb 100644 (file)
--- a/cfgfile.c
+++ b/cfgfile.c
@@ -3259,6 +3259,8 @@ void default_prefs (struct uae_prefs *p, int type)
 
     p->fpu_model = 0;
     p->cpu_model = 68000;
+    p->cpu_clock_multiplier = 0;
+    p->cpu_frequency = 0;
     p->mmu_model = 0;
     p->cpu060_revision = 6;
     p->fpu_revision = -1;
@@ -3355,6 +3357,8 @@ static void buildin_default_prefs (struct uae_prefs *p)
 
     p->fpu_model = 0;
     p->cpu_model = 68000;
+    p->cpu_clock_multiplier = 0;
+    p->cpu_frequency = 0;
     p->cpu060_revision = 1;
     p->fpu_revision = -1;
     p->m68k_speed = 0;
index c9c59873e987d2550c13a4827d028f2c6dcdf95c..7ce9ae74db0ed574d61c67ec732f2a4d504e7304 100644 (file)
--- a/custom.c
+++ b/custom.c
@@ -181,6 +181,7 @@ uae_u16 beamcon0, new_beamcon0;
 uae_u16 vtotal = MAXVPOS_PAL, htotal = MAXHPOS_PAL;
 static uae_u16 hsstop, hbstrt, hbstop, vsstop, vbstrt, vbstop, hsstrt, vsstrt, hcenter;
 static int ciavsyncmode;
+static int baseclock, cpucycleunit;
 
 #define HSYNCTIME (maxhpos * CYCLE_UNIT);
 
@@ -297,7 +298,6 @@ struct copper {
     int strobe; /* COPJMP1 / COPJMP2 accessed */
     int last_write, last_write_hpos;
     int moveaddr, movedata, movedelay;
-    int movedata100, movedelay100;
 };
 
 static struct copper cop_state;
@@ -928,9 +928,9 @@ static void BPLCON0_Denise (int hpos, uae_u16 v);
 
 // writing to BPLCON0 adds 4 cycle delay before Agnus bitplane DMA sequence changes
 // (Note that Denise sees the change after 1 cycle)
-// AGA either needs 1 extra cycle or only in specific situations (perhaps only
-// when first plane in block is active, which is not possible in OCS/ECS)
-#define BPLCON_AGNUS_DELAY (4 + ((currprefs.chipset_mask & CSMASK_AGA) ? 1 : 0))
+// AGA needs extra cycle in some specific situations (Brian The Lion "dialog") but not
+// in all situations (Superstardust weapon panel)
+#define BPLCON_AGNUS_DELAY (4 + (bplcon0_planes == 8 ? 1 : 0))
 #define BPLCON_DENISE_DELAY 1
 
 static void maybe_setup_fmodes (int hpos)
@@ -2639,12 +2639,24 @@ void init_hz (void)
     int odbl = doublescan, omaxvpos = maxvpos;
     int hzc = 0;
 
-    if ((currprefs.chipset_refreshrate == 50 && !currprefs.ntscmode) ||
-       (currprefs.chipset_refreshrate == 60 && currprefs.ntscmode)) {
+    if (vsync_switchmode (-1) > 0)
+       currprefs.gfx_avsync = changed_prefs.gfx_avsync = vsync_switchmode (-1);
+
+    if (!isvsync () && ((currprefs.chipset_refreshrate == 50 && !currprefs.ntscmode) ||
+       (currprefs.chipset_refreshrate == 60 && currprefs.ntscmode))) {
        currprefs.chipset_refreshrate = changed_prefs.chipset_refreshrate = 0;
     }
-    if (isvsync ()) {
-       changed_prefs.chipset_refreshrate = currprefs.chipset_refreshrate = abs (currprefs.gfx_refreshrate);
+
+    baseclock = currprefs.ntscmode ? 28636360 : 28375160;
+    cpucycleunit = CYCLE_UNIT / 2;
+    if (currprefs.cpu_clock_multiplier) {
+       if (currprefs.cpu_clock_multiplier >= 256) {
+           cpucycleunit = CYCLE_UNIT / (currprefs.cpu_clock_multiplier >> 8);
+       } else {
+           cpucycleunit = CYCLE_UNIT * currprefs.cpu_clock_multiplier;
+       }
+    } else if (currprefs.cpu_frequency) {
+       cpucycleunit = CYCLE_UNIT * baseclock / (currprefs.cpu_frequency * 8);
     }
 
     doublescan = 0;
@@ -2735,6 +2747,12 @@ void init_hz (void)
        doublescan > 0 ? L" dblscan" : L"",
        vblank_hz, vblank_hz * maxvpos,
        maxhpos, maxvpos);
+
+    if ((vblank_hz == 50 || vblank_hz == 60) && isvsync ()) {
+       if (currprefs.gfx_refreshrate != vblank_hz)
+           vsync_switchmode (vblank_hz);
+    }
+
 }
 
 static void calcdiw (void)
@@ -4133,14 +4151,7 @@ static void update_copper (int until_hpos)
                    cop_state.state = COP_strobe_delay1;
                } else {
                    // FIX: all copper writes happen 1 cycle later than CPU writes
-                   if (0 && reg == 0x100) {
-                       // special case BPLCON0 BPL DMA sequence delay
-                       // dma sequence does not change until 1+4 cycles after the write
-                       cop_state.movedelay100 = 2;
-                       cop_state.movedata100 = data;
-                       if (thisline_decision.plfleft == -1)
-                           BPLCON0_Denise (old_hpos, data);
-                   } else if (customdelay[reg / 2]) {
+                   if (customdelay[reg / 2]) {
                        cop_state.moveaddr = reg;
                        cop_state.movedata = data;
                        cop_state.movedelay = customdelay[cop_state.moveaddr / 2];
@@ -5047,10 +5058,13 @@ static void hsync_handler (void)
 
     if (!(beamcon0 & 0x0800) && !(beamcon0 & 0x0020) && (currprefs.chipset_mask & CSMASK_ECS_AGNUS)) {
        lol ^= 1; // NTSC and !LOLDIS -> LOL toggles every line
+    } else if (!(currprefs.chipset_mask & CSMASK_ECS_AGNUS) && currprefs.ntscmode) {
+       lol ^= 1;
     }
     maxhpos = maxhpos_short + lol;
     eventtab[ev_hsync].evtime = get_cycles () + HSYNCTIME;
     eventtab[ev_hsync].oldcycles = get_cycles ();
+
     CIA_hsync_handler (!(bplcon0 & 2) || ((bplcon0 & 2) && currprefs.genlock));
     if (currprefs.cs_ciaatod > 0) {
        static int cia_hsync;
@@ -5094,6 +5108,7 @@ static void hsync_handler (void)
            lightpen_triggered = 1;
        }
        vpos = 0;
+       lol = 0;
        vsync_handler ();
 #if 0
        if (input_recording > 0) {
@@ -5391,7 +5406,7 @@ void customreset (int hardreset)
     target_reset ();
     reset_all_systems ();
     write_log (L"Reset at %08X\n", M68K_GETPC);
-    memory_map_dump();
+    memory_map_dump ();
 
     hsync_counter = 0;
     vsync_counter = 0;
@@ -5401,17 +5416,17 @@ void customreset (int hardreset)
     lightpen_cx = lightpen_cy = -1;
     if (! savestate_state) {
        currprefs.chipset_mask = changed_prefs.chipset_mask;
-       update_mirrors();
+       update_mirrors ();
        if (!aga_mode) {
            for (i = 0; i < 32; i++) {
                current_colors.color_regs_ecs[i] = 0;
-               current_colors.acolors[i] = getxcolor(0);
+               current_colors.acolors[i] = getxcolor (0);
            }
 #ifdef AGA
        } else {
            for (i = 0; i < 256; i++) {
                current_colors.color_regs_aga[i] = 0;
-               current_colors.acolors[i] = getxcolor(0);
+               current_colors.acolors[i] = getxcolor (0);
            }
 #endif
        }
@@ -5438,6 +5453,7 @@ void customreset (int hardreset)
        CLXCON (0);
        setup_fmodes (0);
        sprite_width = GET_SPRITEWIDTH (fmode);
+       new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20;
     }
 
     gayle_reset (hardreset);
@@ -5479,7 +5495,6 @@ void customreset (int hardreset)
     hdiwstate = DIW_waiting_start;
     set_cycles (0);
 
-    new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20;
     hack_vpos = 0;
     init_hz ();
     vpos_lpen = -1;
@@ -6652,20 +6667,6 @@ uae_u32 wait_cpu_cycle_read (uaecptr addr, int mode)
     return v;
 }
 
-#if 0
-uae_u32 wait_cpu_cycle_read_cycles (uaecptr addr, int mode, int *cycles)
-{
-    uae_u32 v = 0;
-    *cycles = dma_cycle () + CYCLE_UNIT;
-    if (mode > 0)
-       v = get_word (addr);
-    else if (mode == 0)
-       v = get_byte (addr);
-    do_cycles (1 * CYCLE_UNIT);
-    return v;
-}
-#endif
-
 void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v)
 {
     int hpos;
@@ -6701,6 +6702,16 @@ void do_cycles_ce (long cycles)
     }
 }
 
+void do_cycles_ce020 (int clocks)
+{
+    do_cycles_ce (clocks * cpucycleunit);
+}
+
+void do_cycles_ce000 (int clocks)
+{
+    do_cycles_ce (clocks * cpucycleunit);
+}
+
 int is_cycle_ce (void)
 {
     int hpos = current_hpos ();
index 8c1c75ed8205214d88382cdb3052dfe9e391b8ca..8b3ffae235173a948e346dc4c80eec3224a1d69e 100644 (file)
--- a/gencpu.c
+++ b/gencpu.c
@@ -124,22 +124,30 @@ static void returncycles (char *s, int cycles)
     else
        printf ("%sreturn %d * CYCLE_UNIT / 2;\n", s, cycles);
 }
-static void addcycles (int cycles)
+
+static void addcycles_ce020 (int cycles)
+{
+    if (!using_ce020) return;
+    printf ("\tdo_cycles_ce020 (%d);\n", cycles);
+    count_cycles += cycles;
+}
+static void addcycles000 (int cycles)
 {
     if (!using_ce) return;
-    printf ("\tdo_cycles_ce (%d * CYCLE_UNIT / 2);\n", cycles);
+    printf ("\tdo_cycles_ce000 (%d);\n", cycles);
     count_cycles += cycles;
 }
-static void addcycles2 (char *s, int cycles)
+static void addcycles000_2 (char *s, int cycles)
 {
     if (!using_ce) return;
-    printf ("%sdo_cycles_ce (%d * CYCLE_UNIT / 2);\n", s, cycles);
+    printf ("%sdo_cycles_ce000 (%d);\n", s, cycles);
     count_cycles += cycles;
 }
-static void addcycles3 (char *s)
+
+static void addcycles000_3 (char *s)
 {
     if (!using_ce) return;
-    printf ("%sif (cycles > 0) do_cycles_ce (cycles);\n", s);
+    printf ("%sif (cycles > 0) do_cycles_ce000 (cycles);\n", s);
     count_ncycles++;
 }
 
@@ -506,7 +514,7 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
            abort ();
        }
        if (!(flags & GF_APDI)) {
-           addcycles (2);
+           addcycles000 (2);
            insn_n_cycles += 2;
            count_cycles_ea += 2;
        }
@@ -535,7 +543,7 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
            count_read_ea++; 
        }
        if (!(flags & GF_AD8R)) {
-           addcycles (2);
+           addcycles000 (2);
            insn_n_cycles += 2;
            count_cycles_ea += 2;
        }
@@ -566,7 +574,7 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
            printf ("\t%sa = get_disp_ea_000 (tmppc, %s);\n", name, gen_nextiword (flags & GF_NOREFILL));
        }
        if (!(flags & GF_PC8R)) {
-           addcycles (2);
+           addcycles000 (2);
            insn_n_cycles += 2;
            count_cycles_ea += 2;
        }
@@ -646,9 +654,9 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
        start_brace ();
        if (using_ce020) {
            switch (size) {
-           case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = get_byte_ce_020 (%sa);\n", name, name); count_read++; break;
-           case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = get_word_ce_020 (%sa);\n", name, name); count_read++; break;
-           case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = get_long_ce_020 (%sa);\n", name, name); count_read += 2; break;
+           case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = get_byte_ce020 (%sa);\n", name, name); count_read++; break;
+           case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = get_word_ce020 (%sa);\n", name, name); count_read++; break;
+           case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = get_long_ce020 (%sa);\n", name, name); count_read += 2; break;
            default: abort ();
            }
        } else if (using_ce) {
@@ -908,7 +916,7 @@ static void genmovemel_ce (uae_u16 opcode)
     printf ("\tuae_u32 v;\n");
     genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, GF_AA);
     if (table68k[opcode].dmode == Ad8r || table68k[opcode].dmode == PC8r)
-       addcycles (2);
+       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",
@@ -985,7 +993,7 @@ static void genmovemle_ce (uae_u16 opcode)
     genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, GF_AA);
 
     if (table68k[opcode].dmode == Ad8r || table68k[opcode].dmode == PC8r) {
-       addcycles (2);
+       addcycles000 (2);
     }
     start_brace ();
     if (table68k[opcode].size == sz_long) {
@@ -1299,9 +1307,9 @@ static void shift_ce (amodes dmode, int size)
     if (using_ce && isreg (dmode)) {
        int c = size == sz_long ? 4 : 2;
        printf ("\t{\n");
-       printf ("\t\tint cycles = %d * CYCLE_UNIT / 2;\n", c);
-       printf ("\t\tcycles += 2 * CYCLE_UNIT / 2 * ccnt;\n");
-       addcycles3 ("\t\t");
+       printf ("\t\tint cycles = %d;\n", c);
+       printf ("\t\tcycles += 2 * ccnt;\n");
+       addcycles000_3 ("\t\t");
        printf ("\t}\n");
        count_cycles += c;
     }
@@ -1315,9 +1323,9 @@ static void bsetcycles (struct instr *curi)
     } else {
         printf ("\tsrc &= 31;\n");
         if (isreg (curi->dmode)) {
-           addcycles (2);
+           addcycles000 (2);
            if (curi->mnemo != i_BTST && using_ce) {
-               printf ("\tif (src > 15) do_cycles_ce (2 * CYCLE_UNIT / 2);\n");
+               printf ("\tif (src > 15) do_cycles_ce000 (2);\n");
                count_ncycles++;
            }
        }
@@ -1377,7 +1385,7 @@ static void gen_opcode (unsigned long int opcode)
                    c += 2;
            }
            if (c > 0)
-               addcycles (c);
+               addcycles000 (c);
        } else if (curi->smode == Dreg) {
            int c = 0;
            if (curi->dmode == Dreg) {
@@ -1387,7 +1395,7 @@ static void gen_opcode (unsigned long int opcode)
                    c += 2;
            }
            if (c > 0)
-               addcycles (c);
+               addcycles000 (c);
        }
        fill_prefetch_next ();
        genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
@@ -1399,7 +1407,7 @@ static void gen_opcode (unsigned long int opcode)
        if (curi->size == sz_byte) {
            printf ("\tsrc &= 0xFF;\n");
        }
-       addcycles (4);
+       addcycles000 (4);
        fill_prefetch_next ();
        printf ("\tregs.sr %c= src;\n", curi->mnemo == i_EORSR ? '^' : '|');
        printf ("\tMakeFromSR ();\n");
@@ -1410,7 +1418,7 @@ static void gen_opcode (unsigned long int opcode)
        if (curi->size == sz_byte) {
            printf ("\tsrc |= 0xFF00;\n");
        }
-       addcycles (4);
+       addcycles000 (4);
        fill_prefetch_next ();
        printf ("\tregs.sr &= src;\n");
        printf ("\tMakeFromSR ();\n");
@@ -1426,7 +1434,7 @@ static void gen_opcode (unsigned long int opcode)
                    c += 2;
            }
            if (c > 0)
-               addcycles (c);
+               addcycles000 (c);
        }
        fill_prefetch_next ();
        start_brace ();
@@ -1439,13 +1447,13 @@ static void gen_opcode (unsigned long int opcode)
        if (curi->smode == immi) {
            int c = 4;
            if (c > 0)
-               addcycles (c);
+               addcycles000 (c);
        } else {
            int c = curi->size == sz_long ? 2 : 4;
            if (islongimm (curi))
                c += 2;
            if (c > 0)
-               addcycles (c);
+               addcycles000 (c);
        }
        fill_prefetch_next ();
        start_brace ();
@@ -1456,9 +1464,9 @@ static void gen_opcode (unsigned long int opcode)
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
        genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
        if (curi->size == sz_long && isreg (curi->smode))
-           addcycles (4);
+           addcycles000 (4);
        if (!isreg (curi->smode))
-           addcycles (2);
+           addcycles000 (2);
        fill_prefetch_next ();
        start_brace ();
        printf ("\tuae_u32 newv = dst - src - (GET_XFLG (&regs.ccrflags) ? 1 : 0);\n");
@@ -1489,7 +1497,7 @@ static void gen_opcode (unsigned long int opcode)
            genflags (flag_zn, curi->size, "newv", "", "");
            printf ("\tSET_VFLG (&regs.ccrflags, (tmp_newv & 0x80) != 0 && (newv & 0x80) == 0);\n");
        }
-       addcycles (2);
+       addcycles000 (2);
        genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
        break;
     case i_ADD:
@@ -1503,7 +1511,7 @@ static void gen_opcode (unsigned long int opcode)
                    c += 2;
            }
            if (c > 0)
-               addcycles (c);
+               addcycles000 (c);
        }
        fill_prefetch_next ();
        start_brace ();
@@ -1518,13 +1526,13 @@ static void gen_opcode (unsigned long int opcode)
            if (islongimm (curi))
                c += 2;
            if (c > 0)
-               addcycles (c);
+               addcycles000 (c);
        } else {
            int c = curi->size == sz_long ? 2 : 4;
            if (islongimm (curi))
                c += 2;
            if (c > 0)
-               addcycles (c);
+               addcycles000 (c);
        }
        fill_prefetch_next ();
        start_brace ();
@@ -1535,9 +1543,9 @@ static void gen_opcode (unsigned long int opcode)
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
        genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
        if (curi->size == sz_long && isreg (curi->smode))
-           addcycles (4);
+           addcycles000 (4);
        if (!isreg (curi->smode))
-           addcycles (2);
+           addcycles000 (2);
        fill_prefetch_next ();
        start_brace ();
        printf ("\tuae_u32 newv = dst + src + (GET_XFLG (&regs.ccrflags) ? 1 : 0);\n");
@@ -1570,13 +1578,13 @@ static void gen_opcode (unsigned long int opcode)
            genflags (flag_zn, curi->size, "newv", "", "");
            printf ("\tSET_VFLG (&regs.ccrflags, (tmp_newv & 0x80) == 0 && (newv & 0x80) != 0);\n");
        }
-       addcycles (2);
+       addcycles000 (2);
        genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
        break;
     case i_NEG:
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
        if (isreg (curi->smode) && curi->size == sz_long)
-           addcycles (2);
+           addcycles000 (2);
        fill_prefetch_next ();
        start_brace ();
        genflags (flag_sub, curi->size, "dst", "src", "0");
@@ -1585,7 +1593,7 @@ static void gen_opcode (unsigned long int opcode)
     case i_NEGX:
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
        if (isreg (curi->smode) && curi->size == sz_long)
-           addcycles (2);
+           addcycles000 (2);
        fill_prefetch_next ();
        start_brace ();
        printf ("\tuae_u32 newv = 0 - src - (GET_XFLG (&regs.ccrflags) ? 1 : 0);\n");
@@ -1596,7 +1604,7 @@ static void gen_opcode (unsigned long int opcode)
     case i_NBCD:
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
        if (isreg (curi->smode))
-           addcycles (2);
+           addcycles000 (2);
        fill_prefetch_next ();
        start_brace ();
        printf ("\tuae_u16 newv_lo = - (src & 0xF) - (GET_XFLG (&regs.ccrflags) ? 1 : 0);\n");
@@ -1623,7 +1631,7 @@ static void gen_opcode (unsigned long int opcode)
     case i_CLR:
        genamode (curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0);
        if (isreg (curi->smode) && curi->size == sz_long)
-           addcycles (2);
+           addcycles000 (2);
        fill_prefetch_next ();
        genflags (flag_logical, curi->size, "0", "", "");
        genastore_rev ("0", curi->smode, "srcreg", curi->size, "src");
@@ -1631,7 +1639,7 @@ static void gen_opcode (unsigned long int opcode)
     case i_NOT:
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
        if (isreg (curi->smode) && curi->size == sz_long)
-           addcycles (2);
+           addcycles000 (2);
        fill_prefetch_next ();
        start_brace ();
        printf ("\tuae_u32 dst = ~src;\n");
@@ -1657,7 +1665,7 @@ static void gen_opcode (unsigned long int opcode)
        genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
        bsetcycles (curi);
        if (curi->mnemo == i_BCLR && curi->dmode == Dreg)
-           addcycles (2);
+           addcycles000 (2);
        fill_prefetch_next ();
        if (curi->mnemo == i_BCHG) {
            printf ("\tdst ^= (1 << src);\n");
@@ -1682,7 +1690,7 @@ static void gen_opcode (unsigned long int opcode)
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
        genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
        if (curi->dmode == Dreg && curi->size == sz_long)
-           addcycles (2);
+           addcycles000 (2);
        fill_prefetch_next ();
        start_brace ();
        genflags (flag_cmp, curi->size, "newv", "src", "dst");
@@ -1690,7 +1698,7 @@ static void gen_opcode (unsigned long int opcode)
     case i_CMPA:
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
        genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
-       addcycles (2);
+       addcycles000 (2);
        fill_prefetch_next ();
        start_brace ();
        genflags (flag_cmp, sz_long, "newv", "src", "dst");
@@ -1780,7 +1788,7 @@ static void gen_opcode (unsigned long int opcode)
     case i_MVSR2: // MOVE FROM SR (like CLR, does dummy read first on 68000)
        genamode (curi->smode, "srcreg", sz_word, "src", cpu_level == 0 ? 1 : 2, 0, 0);
        if (isreg (curi->smode))
-           addcycles (2);
+           addcycles000 (2);
        fill_prefetch_next ();
        printf ("\tMakeSR ();\n");
        if (curi->size == sz_byte)
@@ -1791,10 +1799,10 @@ static void gen_opcode (unsigned long int opcode)
     case i_MV2SR: // MOVE TO SR
        genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
        if (curi->size == sz_byte) {
-           addcycles (8);
+           addcycles000 (8);
            printf ("\tMakeSR ();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n");
        } else {
-           addcycles (4);
+           addcycles000 (4);
            printf ("\tregs.sr = src;\n");
        }
        fill_prefetch_next ();
@@ -1811,7 +1819,7 @@ static void gen_opcode (unsigned long int opcode)
     case i_EXG:
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
        genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
-       addcycles (2);
+       addcycles000 (2);
        fill_prefetch_next ();
        genastore ("dst", curi->smode, "srcreg", curi->size, "src");
        genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
@@ -1863,7 +1871,7 @@ static void gen_opcode (unsigned long int opcode)
     case i_RESET:
        fill_prefetch_next ();
        printf ("\tcpureset ();\n");
-       addcycles (128);
+       addcycles000 (128);
        if (using_prefetch)
            printf ("\tregs.irc = get_iword (4);\n");
        break;
@@ -2005,12 +2013,12 @@ static void gen_opcode (unsigned long int opcode)
            need_endlabel = 1;
        }
        if (curi->smode == Ad16 || curi->smode == absw || curi->smode == PC16)
-           addcycles (2);
+           addcycles000 (2);
        printf ("\tm68k_setpc (srca);\n");
        m68k_pc_offset = 0;
        fill_prefetch_1 (0);
        if (curi->smode == Ad8r || curi->smode == PC8r)
-           addcycles (6);
+           addcycles000 (6);
        printf("\tm68k_areg (regs, 7) -= 4;\n");
        if (using_ce) {
            printf("\tput_word_ce (m68k_areg (regs, 7), oldpc >> 16);\n");
@@ -2031,7 +2039,7 @@ static void gen_opcode (unsigned long int opcode)
            need_endlabel = 1;
        }
        if (curi->smode == Ad16 || curi->smode == Ad8r || curi->smode == absw || curi->smode == PC16 || curi->smode == PC8r)
-           addcycles (2);
+           addcycles000 (2);
 //     if (using_ce && (curi->smode == Ad8r || curi->smode == PC8r))
        printf ("\tm68k_setpc (srca);\n");
        m68k_pc_offset = 0;
@@ -2048,7 +2056,7 @@ static void gen_opcode (unsigned long int opcode)
            printf ("\t}\n");
            need_endlabel = 1;
        }
-       addcycles (2);
+       addcycles000 (2);
        if (using_ce)
            printf ("\tm68k_do_bsr_ce (m68k_getpc () + %d, s);\n", m68k_pc_offset);
        else if (using_indirect)
@@ -2062,7 +2070,7 @@ static void gen_opcode (unsigned long int opcode)
     case i_Bcc:
        if (curi->size == sz_long) {
            if (cpu_level < 2) {
-               addcycles (2);
+               addcycles000 (2);
                printf ("\tif (cctrue (&regs.ccrflags, %d)) {\n", curi->cc, endlabelstr);
                printf ("\t\texception3i (opcode, m68k_getpc () + 2, m68k_getpc () + 1);\n");
                printf ("\t\tgoto %s;\n", endlabelstr);
@@ -2078,7 +2086,7 @@ static void gen_opcode (unsigned long int opcode)
            }
        }
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_NOREFILL);
-       addcycles (2);
+       addcycles000 (2);
        printf ("\tif (!cctrue (&regs.ccrflags, %d)) goto didnt_jump;\n", curi->cc);
        if (using_exception_3) {
            printf ("\tif (src & 1) {\n");
@@ -2106,11 +2114,11 @@ static void gen_opcode (unsigned long int opcode)
        need_endlabel = 1;
        sync_m68k_pc ();
        if (curi->size == sz_byte) {
-           addcycles (2);
+           addcycles000 (2);
            irc2ir ();
            fill_prefetch_2 ();
        } else if (curi->size == sz_word) {
-           addcycles (2);
+           addcycles000 (2);
            fill_prefetch_full ();
        } else {
            fill_prefetch_full ();
@@ -2121,21 +2129,21 @@ static void gen_opcode (unsigned long int opcode)
        genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA);
        genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, GF_AA);
        if (curi->smode == Ad8r || curi->smode == PC8r)
-           addcycles (2);
+           addcycles000 (2);
        fill_prefetch_next ();
        if (curi->smode == Ad8r || curi->smode == PC8r)
-           addcycles (2);
+           addcycles000 (2);
        genastore ("srca", curi->dmode, "dstreg", curi->size, "dst");
        break;
     case i_PEA:
        genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA);
        genamode (Apdi, "7", sz_long, "dst", 2, 0, GF_AA);
        if (curi->smode == Ad8r || curi->smode == PC8r)
-           addcycles (2);
+           addcycles000 (2);
        if (!(curi->smode == absw || curi->smode == absl))
            fill_prefetch_next ();
        if (curi->smode == Ad8r || curi->smode == PC8r)
-           addcycles (2);
+           addcycles000 (2);
        genastore ("srca", Apdi, "7", sz_long, "dst");
        if ((curi->smode == absw || curi->smode == absl))
            fill_prefetch_next ();
@@ -2144,7 +2152,7 @@ static void gen_opcode (unsigned long int opcode)
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_NOREFILL);
        genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0, GF_AA | GF_NOREFILL);
        printf ("\tuaecptr oldpc = m68k_getpc ();\n");
-       addcycles (2);
+       addcycles000 (2);
        printf ("\tif (!cctrue (&regs.ccrflags, %d)) {\n", curi->cc);
        printf ("\t\tm68k_incpc ((uae_s32)offs + 2);\n");
        printf ("\t"); fill_prefetch_1 (0);
@@ -2165,7 +2173,7 @@ static void gen_opcode (unsigned long int opcode)
            printf ("\t\t\treturn;\n");
        printf ("\t\t}\n");
        printf ("\t} else {\n");
-       addcycles2 ("\t\t", 2);
+       addcycles000_2 ("\t\t", 2);
        printf ("\t}\n");
        printf ("\tm68k_setpc (oldpc + %d);\n", m68k_pc_offset);
        m68k_pc_offset = 0;
@@ -2182,8 +2190,8 @@ static void gen_opcode (unsigned long int opcode)
        if (using_ce) {
            printf ("\tint cycles = 0;\n");
            if (isreg (curi->smode))
-               printf ("\tif (val) cycles += 2 * CYCLE_UNIT / 2;\n");
-           addcycles3 ("\t");
+               printf ("\tif (val) cycles += 2;\n");
+           addcycles000_3 ("\t");
        }
        genastore ("val", curi->smode, "srcreg", curi->size, "src");
        break;
@@ -2209,8 +2217,10 @@ static void gen_opcode (unsigned long int opcode)
        fill_prefetch_next ();
        if (using_ce) {
            start_brace ();
-           printf ("\t\tint cycles = (getDivu68kCycles((uae_u32)dst, (uae_u16)src) - 4) * CYCLE_UNIT / 2;\n");
-           addcycles3 ("\t\t");
+           printf ("\t\tint cycles = (getDivu68kCycles((uae_u32)dst, (uae_u16)src) - 4);\n");
+           addcycles000_3 ("\t\t");
+       } else if (using_ce020) {
+           addcycles_ce020 (40);
        }
        /* The N flag appears to be set each time there is an overflow.
         * Weird. but 68020 only sets N when dst is negative.. */
@@ -2255,8 +2265,10 @@ static void gen_opcode (unsigned long int opcode)
        fill_prefetch_next ();
        if (using_ce) {
            start_brace ();
-           printf ("\t\tint cycles = (getDivs68kCycles((uae_s32)dst, (uae_s16)src) - 4) * CYCLE_UNIT / 2;\n");
-           addcycles3 ("\t\t");
+           printf ("\t\tint cycles = (getDivs68kCycles((uae_s32)dst, (uae_s16)src) - 4);\n");
+           addcycles000_3 ("\t\t");
+       } else if (using_ce020) {
+           addcycles_ce020 (50);
        }
        printf ("\t\tif ((newv & 0xffff8000) != 0 && (newv & 0xffff8000) != 0xffff8000) {\n");
        printf ("\t\t\tSET_VFLG (&regs.ccrflags, 1);\n");
@@ -2285,12 +2297,14 @@ static void gen_opcode (unsigned long int opcode)
        start_brace ();
        printf ("\tuae_u32 newv = (uae_u32)(uae_u16)dst * (uae_u32)(uae_u16)src;\n");
        if (using_ce)
-           printf ("\tint cycles = (38 - 4) * CYCLE_UNIT / 2, bits;\n");
+           printf ("\tint cycles = 38 - 4, bits;\n");
        genflags (flag_logical, sz_long, "newv", "", "");
        if (using_ce) {
            printf ("\tfor(bits = 0; bits < 16 && src; bits++, src >>= 1)\n");
-           printf ("\t\tif (src & 1) cycles += 2 * CYCLE_UNIT / 2;\n");
-           addcycles3 ("\t");
+           printf ("\t\tif (src & 1) cycles += 2;\n");
+           addcycles000_3 ("\t");
+       } else if (using_ce020) {
+           addcycles_ce020 (20);
        }
        genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
        sync_m68k_pc ();
@@ -2305,15 +2319,17 @@ static void gen_opcode (unsigned long int opcode)
        start_brace ();
        printf ("\tuae_u32 newv = (uae_s32)(uae_s16)dst * (uae_s32)(uae_s16)src;\n");
        if (using_ce) {
-           printf ("\tint cycles = (38 - 4) * CYCLE_UNIT / 2, bits;\n");
+           printf ("\tint cycles = 38 - 4, bits;\n");
            printf ("\tuae_u32 usrc;\n");
        }
        genflags (flag_logical, sz_long, "newv", "", "");
        if (using_ce) {
            printf ("\tusrc = ((uae_u32)src) << 1;\n");
            printf ("\tfor(bits = 0; bits < 16 && usrc; bits++, usrc >>= 1)\n");
-           printf ("\t\tif ((usrc & 3) == 1 || (usrc & 3) == 2) cycles += 2 * CYCLE_UNIT / 2;\n");
-           addcycles3 ("\t");
+           printf ("\t\tif ((usrc & 3) == 1 || (usrc & 3) == 2) cycles += 2;\n");
+           addcycles000_3 ("\t");
+       } else if (using_ce020) {
+           addcycles_ce020 (20);
        }
        genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
        count_cycles += 38 - 4;
@@ -2325,13 +2341,13 @@ static void gen_opcode (unsigned long int opcode)
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
        genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
        sync_m68k_pc ();
-       addcycles (4);
+       addcycles000 (4);
        printf ("\tif (dst > src) {\n");
        printf ("\t\tSET_NFLG (&regs.ccrflags, 0);\n");
        printf ("\t\tException (6, oldpc);\n");
        printf ("\t\tgoto %s;\n", endlabelstr);
        printf ("\t}\n");
-       addcycles (2);
+       addcycles000 (2);
        printf ("\tif ((uae_s32)dst < 0) {\n");
        printf ("\t\tSET_NFLG (&regs.ccrflags, 1);\n");
        printf ("\t\tException (6, oldpc);\n");
@@ -2903,12 +2919,18 @@ static void gen_opcode (unsigned long int opcode)
        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");
        break;
     case i_MULL:
        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 (40);
+       }
        sync_m68k_pc ();
        printf ("\tm68k_mull(opcode, dst, extra);\n");
        break;
@@ -3028,7 +3050,7 @@ static void gen_opcode (unsigned long int opcode)
        genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
        genflags (flag_logical, curi->size, "src", "", "");
        if (!isreg (curi->smode))
-           addcycles (2);
+           addcycles000 (2);
        fill_prefetch_next ();
         printf ("\tsrc |= 0x80;\n");
        if (cpu_level >= 2 || curi->smode == Dreg || !using_ce) {
@@ -3039,7 +3061,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_ce (4 * CYCLE_UNIT / 2);\n");
+           printf ("\t\tdo_cycles_ce000 (4);\n");
            printf ("\t}\n");
        }
        break;
@@ -3102,33 +3124,63 @@ static void gen_opcode (unsigned long int opcode)
        break;
 
      case i_MOVE16:
-       if ((opcode & 0xfff8) == 0xf620) {
-            /* MOVE16 (Ax)+,(Ay)+ */
-            printf ("\tuaecptr mems = m68k_areg (regs, srcreg) & ~15, memd;\n");
-            printf ("\tdstreg = (%s >> 12) & 7;\n", gen_nextiword (0));
-            printf ("\tmemd = m68k_areg (regs, dstreg) & ~15;\n");
-            printf ("\tput_long (memd, get_long (mems));\n");
-            printf ("\tput_long (memd+4, get_long (mems+4));\n");
-            printf ("\tput_long (memd+8, get_long (mems+8));\n");
-            printf ("\tput_long (memd+12, get_long (mems+12));\n");
-            printf ("\tif (srcreg != dstreg)\n");
-            printf ("\tm68k_areg (regs, srcreg) += 16;\n");
-            printf ("\tm68k_areg (regs, dstreg) += 16;\n");
-       } else {
-            /* Other variants */
-            genamode (curi->smode, "srcreg", curi->size, "mems", 0, 2, 0);
-            genamode (curi->dmode, "dstreg", curi->size, "memd", 0, 2, 0);
-            printf ("\tmemsa &= ~15;\n");
-            printf ("\tmemda &= ~15;\n");
-            printf ("\tput_long (memda, get_long (memsa));\n");
-            printf ("\tput_long (memda+4, get_long (memsa+4));\n");
-            printf ("\tput_long (memda+8, get_long (memsa+8));\n");
-            printf ("\tput_long (memda+12, get_long (memsa+12));\n");
-            if ((opcode & 0xfff8) == 0xf600)
+        if (using_ce020) {
+           if ((opcode & 0xfff8) == 0xf620) {
+                /* MOVE16 (Ax)+,(Ay)+ */
+                printf ("\tuaecptr mems = m68k_areg (regs, srcreg) & ~15, memd;\n");
+                printf ("\tdstreg = (%s >> 12) & 7;\n", gen_nextiword (0));
+                printf ("\tmemd = m68k_areg (regs, dstreg) & ~15;\n");
+                printf ("\tput_long_ce020 (memd, get_long_ce020 (mems));\n");
+                printf ("\tput_long_ce020 (memd+4, get_long_ce020 (mems+4));\n");
+                printf ("\tput_long_ce020 (memd+8, get_long_ce020 (mems+8));\n");
+                printf ("\tput_long_ce020 (memd+12, get_long_ce020 (mems+12));\n");
+                printf ("\tif (srcreg != dstreg)\n");
                 printf ("\tm68k_areg (regs, srcreg) += 16;\n");
-            else if ((opcode & 0xfff8) == 0xf608)
                 printf ("\tm68k_areg (regs, dstreg) += 16;\n");
-       }
+           } else {
+                /* Other variants */
+                genamode (curi->smode, "srcreg", curi->size, "mems", 0, 2, 0);
+                genamode (curi->dmode, "dstreg", curi->size, "memd", 0, 2, 0);
+                printf ("\tmemsa &= ~15;\n");
+                printf ("\tmemda &= ~15;\n");
+                printf ("\tput_long_ce020 (memda, get_long_ce020 (memsa));\n");
+                printf ("\tput_long_ce020 (memda+4, get_long_ce020 (memsa+4));\n");
+                printf ("\tput_long_ce020 (memda+8, get_long_ce020 (memsa+8));\n");
+                printf ("\tput_long_ce020 (memda+12, get_long_ce020 (memsa+12));\n");
+                if ((opcode & 0xfff8) == 0xf600)
+                    printf ("\tm68k_areg (regs, srcreg) += 16;\n");
+                else if ((opcode & 0xfff8) == 0xf608)
+                    printf ("\tm68k_areg (regs, dstreg) += 16;\n");
+           }
+        } else {
+           if ((opcode & 0xfff8) == 0xf620) {
+                /* MOVE16 (Ax)+,(Ay)+ */
+                printf ("\tuaecptr mems = m68k_areg (regs, srcreg) & ~15, memd;\n");
+                printf ("\tdstreg = (%s >> 12) & 7;\n", gen_nextiword (0));
+                printf ("\tmemd = m68k_areg (regs, dstreg) & ~15;\n");
+                printf ("\tput_long (memd, get_long (mems));\n");
+                printf ("\tput_long (memd+4, get_long (mems+4));\n");
+                printf ("\tput_long (memd+8, get_long (mems+8));\n");
+                printf ("\tput_long (memd+12, get_long (mems+12));\n");
+                printf ("\tif (srcreg != dstreg)\n");
+                printf ("\tm68k_areg (regs, srcreg) += 16;\n");
+                printf ("\tm68k_areg (regs, dstreg) += 16;\n");
+           } else {
+                /* Other variants */
+                genamode (curi->smode, "srcreg", curi->size, "mems", 0, 2, 0);
+                genamode (curi->dmode, "dstreg", curi->size, "memd", 0, 2, 0);
+                printf ("\tmemsa &= ~15;\n");
+                printf ("\tmemda &= ~15;\n");
+                printf ("\tput_long (memda, get_long (memsa));\n");
+                printf ("\tput_long (memda+4, get_long (memsa+4));\n");
+                printf ("\tput_long (memda+8, get_long (memsa+8));\n");
+                printf ("\tput_long (memda+12, get_long (memsa+12));\n");
+                if ((opcode & 0xfff8) == 0xf600)
+                    printf ("\tm68k_areg (regs, srcreg) += 16;\n");
+                else if ((opcode & 0xfff8) == 0xf608)
+                    printf ("\tm68k_areg (regs, dstreg) += 16;\n");
+           }
+        }
        break;
 
     case i_PFLUSHN:
@@ -3320,8 +3372,10 @@ static void generate_one_opcode (int rp)
 
     if (opcode_next_clev[rp] != cpu_level) {
        if (generate_stbl)
-           fprintf (stblfile, "{ CPUFUNC(op_%04lx_%d), %ld }, /* %s */\n", opcode, opcode_last_postfix[rp],
-                opcode, lookuptab[i].name);
+           fprintf (stblfile, "{ %sCPUFUNC(op_%04lx_%d), %ld }, /* %s */\n",
+               (using_ce || using_ce020) ? "(cpuop_func*)" : "",
+               opcode, opcode_last_postfix[rp],
+               opcode, lookuptab[i].name);
        return;
     }
     if (generate_stbl) {
@@ -3491,12 +3545,12 @@ int main (int argc, char **argv)
     using_ce = 0;
 
     postfix2 = -1;
-    for (i = 0; i < 14; i++) {
+    for (i = 0; i < 24; i++) {
        postfix = i;
-       if (i >= 6 && i < 11)
+       if ((i >= 6 && i < 11) || (i > 12 && i < 20))
            continue;
        generate_stbl = 1;
-       if (i == 0 || i == 11 || i == 12 || i == 13) {
+       if (i == 0 || i == 11 || i == 12 || i == 20) {
            if (generate_stbl)
                fprintf (stblfile, "#ifdef CPUEMU_%d\n", postfix);
            postfix2 = postfix;
@@ -3516,21 +3570,21 @@ int main (int argc, char **argv)
                using_ce = 1;
            for (rp = 0; rp < nr_cpuop_funcs; rp++)
                opcode_next_clev[rp] = 0;
-       } else if (i == 13) {
-           cpu_level = 2;
+       } else if (i >= 20) {
+           cpu_level = 25 - i;
            using_ce020 = 1;
-           for (rp = 0; rp < nr_cpuop_funcs; rp++)
-               opcode_next_clev[rp] = cpu_level;
+           if (i == 20)
+               read_counts ();
        }
 
        if (generate_stbl) {
-           if (i > 0 && i < 10)
+           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)
+           if ((i > 0 && i < 10) || (i >= 20))
                fprintf (stblfile, "#endif /* CPUEMU_68000_ONLY */\n");
            if (postfix2 >= 0)
                fprintf (stblfile, "#endif /* CPUEMU_%d */\n", postfix2);
index 8911d5c680a644f6e31c7ef3e5809af166b088a4..44b50d3b91e37127ae1c83e83c24ba57624e08f4 100644 (file)
--- a/gfxutil.c
+++ b/gfxutil.c
@@ -292,7 +292,7 @@ void alloc_colors_rgb (int rw, int gw, int bw, int rs, int gs, int bs, int aw, i
        int j;
 
        if (currprefs.gfx_blackerthanblack) {
-           j = i * 15 / 16 + 16;
+           j = i * 15 / 16;
        } else {  
            j = i;
        }
index d2160906583d95a62ecb5ef7b58f25b81e8c2595..fae528139fa970d70fead1bffd7166ee85be49c5 100644 (file)
@@ -12,32 +12,55 @@ STATIC_INLINE uae_u32 get_long_prefetch (int o)
     return v;
 }
 
-#ifdef CPUEMU_13
+#ifdef CPUEMU_20
 
 STATIC_INLINE uae_u32 mem_access_delay_long_read_020 (uaecptr addr)
 {
     switch (ce_banktype[(addr >> 16) & 0xff])
     {
        case CE_MEMBANK_CHIP:
-       return wait_cpu_cycle_read (addr, -1);
+       if ((addr & 3) != 0) {
+           uae_u32 v;
+           v  = wait_cpu_cycle_read (addr + 0, 1) << 16;
+           v |= wait_cpu_cycle_read (addr + 2, 1) <<  0;
+           return v;
+       } else {
+           return wait_cpu_cycle_read (addr, -1);
+       }
        case CE_MEMBANK_FAST:
-       do_cycles_ce (2 * CYCLE_UNIT / 2);
+       if ((addr & 3) != 0)
+           do_cycles_ce020 (2 * CPU020_MEM_CYCLE);
+       else
+           do_cycles_ce020 (1 * CPU020_MEM_CYCLE);
        break;
        case CE_MEMBANK_FAST16BIT:
-       do_cycles_ce (4 * CYCLE_UNIT / 2);
+       do_cycles_ce020 (2 * CPU020_MEM_CYCLE);
        break;
     }
     return get_long (addr);
 }
+
 STATIC_INLINE uae_u32 mem_access_delay_longi_read_020 (uaecptr addr)
 {
     switch (ce_banktype[(addr >> 16) & 0xff])
     {
        case CE_MEMBANK_CHIP:
-       return wait_cpu_cycle_read (addr, -1);
+       if ((addr & 3) != 0) {
+           uae_u32 v;
+           v  = wait_cpu_cycle_read (addr + 0, 1) << 16;
+           v |= wait_cpu_cycle_read (addr + 2, 1) <<  0;
+           return v;
+       } else {
+           return wait_cpu_cycle_read (addr, -1);
+       }
        case CE_MEMBANK_FAST:
+       if ((addr & 3) != 0)
+           do_cycles_ce020 (2 * CPU020_MEM_CYCLE);
+       else
+           do_cycles_ce020 (1 * CPU020_MEM_CYCLE);
+       break;
        case CE_MEMBANK_FAST16BIT:
-       do_cycles_ce (2 * CYCLE_UNIT / 2);
+       do_cycles_ce020 (2 * CPU020_MEM_CYCLE);
        break;
     }
     return get_longi (addr);
@@ -48,14 +71,25 @@ STATIC_INLINE uae_u32 mem_access_delay_word_read_020 (uaecptr addr)
     switch (ce_banktype[(addr >> 16) & 0xff])
     {
        case CE_MEMBANK_CHIP:
-       return wait_cpu_cycle_read (addr, 1);
+       if ((addr & 3) == 3) {
+           uae_u16 v;
+           v  = wait_cpu_cycle_read (addr + 0, 0) << 8;
+           v |= wait_cpu_cycle_read (addr + 1, 0) << 0;
+           return v;
+       } else {
+           return wait_cpu_cycle_read (addr, 1);
+       }
        case CE_MEMBANK_FAST:
        case CE_MEMBANK_FAST16BIT:
-       do_cycles_ce (2 * CYCLE_UNIT / 2);
+       if ((addr & 3) == 3)
+           do_cycles_ce020 (2 * CPU020_MEM_CYCLE);
+       else
+           do_cycles_ce020 (1 * CPU020_MEM_CYCLE);
        break;
     }
     return get_word (addr);
 }
+
 STATIC_INLINE uae_u32 mem_access_delay_wordi_read_020 (uaecptr addr)
 {
     switch (ce_banktype[(addr >> 16) & 0xff])
@@ -64,7 +98,7 @@ STATIC_INLINE uae_u32 mem_access_delay_wordi_read_020 (uaecptr addr)
        return wait_cpu_cycle_read (addr, 1);
        case CE_MEMBANK_FAST:
        case CE_MEMBANK_FAST16BIT:
-       do_cycles_ce (2 * CYCLE_UNIT / 2);
+       do_cycles_ce020 (1 * CPU020_MEM_CYCLE);
        break;
     }
     return get_wordi (addr);
@@ -78,12 +112,13 @@ STATIC_INLINE uae_u32 mem_access_delay_byte_read_020 (uaecptr addr)
        return wait_cpu_cycle_read (addr, 0);
        case CE_MEMBANK_FAST:
        case CE_MEMBANK_FAST16BIT:
-       do_cycles_ce (2 * CYCLE_UNIT / 2);
+       do_cycles_ce020 (1 * CPU020_MEM_CYCLE);
        break;
        
     }
     return get_byte (addr);
 }
+
 STATIC_INLINE void mem_access_delay_byte_write_020 (uaecptr addr, uae_u32 v)
 {
     switch (ce_banktype[(addr >> 16) & 0xff])
@@ -93,51 +128,71 @@ STATIC_INLINE void mem_access_delay_byte_write_020 (uaecptr addr, uae_u32 v)
        return;
        case CE_MEMBANK_FAST:
        case CE_MEMBANK_FAST16BIT:
-       do_cycles_ce (2 * CYCLE_UNIT / 2);
+       do_cycles_ce020 (1 * CPU020_MEM_CYCLE);
        break;
     }
     put_byte (addr, v);
 }
+
 STATIC_INLINE void mem_access_delay_word_write_020 (uaecptr addr, uae_u32 v)
 {
     switch (ce_banktype[(addr >> 16) & 0xff])
     {
        case CE_MEMBANK_CHIP:
-       wait_cpu_cycle_write (addr, 1, v);
+       if ((addr & 3) == 3) {
+           wait_cpu_cycle_write (addr + 0, 0, (v >> 8) & 0xff);
+           wait_cpu_cycle_write (addr + 1, 0, (v >> 0) & 0xff);
+       } else {
+           wait_cpu_cycle_write (addr + 0, 1, v);
+       }
        return;
        break;
        case CE_MEMBANK_FAST:
        case CE_MEMBANK_FAST16BIT:
-       do_cycles_ce (2 * CYCLE_UNIT / 2);
+       if ((addr & 3) == 3)
+           do_cycles_ce020 (2 * CPU020_MEM_CYCLE);
+       else
+           do_cycles_ce020 (1 * CPU020_MEM_CYCLE);
        break;
     }
     put_word (addr, v);
 }
+
 STATIC_INLINE void mem_access_delay_long_write_020 (uaecptr addr, uae_u32 v)
 {
     switch (ce_banktype[(addr >> 16) & 0xff])
     {
        case CE_MEMBANK_CHIP:
-       wait_cpu_cycle_write (addr, -1, v);
+       if ((addr & 3) == 3) {
+           wait_cpu_cycle_write (addr + 0, 1, (v >> 16) & 0xffff);
+           wait_cpu_cycle_write (addr + 2, 1, (v >>  0) & 0xffff);
+       } else {
+           wait_cpu_cycle_write (addr + 0, -1, v);
+       }
        return;
        break;
        case CE_MEMBANK_FAST:
+       if ((addr & 3) != 0)
+           do_cycles_ce020 (2 * CPU020_MEM_CYCLE);
+       else
+           do_cycles_ce020 (1 * CPU020_MEM_CYCLE);
+       break;
        case CE_MEMBANK_FAST16BIT:
-       do_cycles_ce (2 * CYCLE_UNIT / 2);
+       do_cycles_ce020 (2 * CPU020_MEM_CYCLE);
        break;
-    }
+   }
     put_long (addr, v);
 }
 
-STATIC_INLINE uae_u32 get_long_ce_020 (uaecptr addr)
+STATIC_INLINE uae_u32 get_long_ce020 (uaecptr addr)
 {
     return mem_access_delay_long_read_020 (addr);
 }
-STATIC_INLINE uae_u32 get_word_ce_020 (uaecptr addr)
+STATIC_INLINE uae_u32 get_word_ce020 (uaecptr addr)
 {
     return mem_access_delay_word_read_020 (addr);
 }
-STATIC_INLINE uae_u32 get_byte_ce_020 (uaecptr addr)
+STATIC_INLINE uae_u32 get_byte_ce020 (uaecptr addr)
 {
     return mem_access_delay_byte_read_020 (addr);
 }
@@ -155,37 +210,32 @@ STATIC_INLINE void put_byte_ce020 (uaecptr addr, uae_u8 v)
     mem_access_delay_byte_write_020 (addr, v);
 }
 
-STATIC_INLINE void fill_cache020 (uae_u32 pc)
-{
-    regs.prefetch020pc = pc;
-    if ((pc >= regs.prefetch020ptr && pc - regs.prefetch020ptr < 256) && (regs.cacr & 1)) {
-       regs.prefetch020 = get_long (pc);
-       do_cycles_ce (1 * CYCLE_UNIT);
-    } else {
-       if (!(regs.cacr & 2))
-           regs.prefetch020ptr = pc;
-       regs.prefetch020 = mem_access_delay_long_read_020 (pc);
-    }
-}
+extern void fill_cache0x0 (uae_u32);
 
 STATIC_INLINE uae_u32 get_word_ce020_prefetch (int o)
 {
     uae_u32 pc = m68k_getpc () + o;
-    if (pc == regs.prefetch020pc)
-       return regs.prefetch020 >> 16;
-    if (pc == regs.prefetch020pc + 2)
-       return regs.prefetch020 & 0xffff;
-    fill_cache020 (pc);
-    return regs.prefetch020 >> 16;
+
+    for (;;) {
+       if (pc == regs.prefetch020addr) {
+           uae_u32 v = regs.prefetch020data >> 16;
+           return v;
+       }
+       if (pc == regs.prefetch020addr + 2) {
+           uae_u32 v = regs.prefetch020data & 0xffff;
+           fill_cache0x0 (pc + 2);
+           return v;
+       }
+       fill_cache0x0 (pc);
+    }
 }
 
 STATIC_INLINE uae_u32 get_long_ce020_prefetch (int o)
 {
-    uae_u32 pc = m68k_getpc () + o;
-    if (pc == regs.prefetch020pc)
-       return regs.prefetch020;
-    fill_cache020 (pc);
-    return regs.prefetch020;
+    uae_u32 v;
+    v = get_word_ce020_prefetch (o) << 16;
+    v |= get_word_ce020_prefetch (o + 2);
+    return v;
 }
 
 STATIC_INLINE uae_u32 next_iword_020ce (void)
@@ -212,7 +262,7 @@ 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_ce (4 * CYCLE_UNIT / 2);
+       do_cycles_ce000 (4);
        break;
     }
     return get_word (addr);
@@ -225,7 +275,7 @@ 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_ce (4 * CYCLE_UNIT / 2);
+       do_cycles_ce000 (4);
        break;
     }
     return get_wordi (addr);
@@ -239,7 +289,7 @@ 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_ce (4 * CYCLE_UNIT / 2);
+       do_cycles_ce000 (4);
        break;
        
     }
@@ -254,7 +304,7 @@ STATIC_INLINE void mem_access_delay_byte_write (uaecptr addr, uae_u32 v)
        return;
        case CE_MEMBANK_FAST:
        case CE_MEMBANK_FAST16BIT:
-       do_cycles_ce (4 * CYCLE_UNIT / 2);
+       do_cycles_ce000 (4);
        break;
     }
     put_byte (addr, v);
@@ -269,7 +319,7 @@ STATIC_INLINE void mem_access_delay_word_write (uaecptr addr, uae_u32 v)
        break;
        case CE_MEMBANK_FAST:
        case CE_MEMBANK_FAST16BIT:
-       do_cycles_ce (4 * CYCLE_UNIT / 2);
+       do_cycles_ce000 (4);
        break;
     }
     put_word (addr, v);
index f739d0861ce731b062dd13a85a833bab94564fd1..5022ac03dc4e7b347012c73e00c399ca201ff197 100644 (file)
@@ -24,6 +24,8 @@ extern frame_time_t syncbase;
 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_ce000 (int clocks);
 extern int is_cycle_ce (void);
 
 extern unsigned long currcycle, nextevent, is_lastline;
index 448a761c8cbf96079fb70c5efad09523d271baa0..2269d55ff96da5faba997dfa04572d4aa0f952ba 100644 (file)
@@ -86,6 +86,20 @@ typedef double fptype;
 #endif
 #endif
 
+#define CPU000_MEM_CYCLE 4
+#define CPU000_CLOCK_MULT 2
+#define CPU020_MEM_CYCLE 3
+#define CPU020_CLOCK_MULT 4
+
+#define CACHELINES020 64
+#define CACHELINES040 1024 // 040 cache really isn't like this..
+struct cache020
+{
+    uae_u32 data;
+    uae_u32 tag;
+    uae_u32 valid:1;
+};
+
 extern struct regstruct
 {
     uae_u32 regs[16];
@@ -98,10 +112,6 @@ extern struct regstruct
     uae_u16 irc, ir;
     uae_u32 spcflags;
     
-    uae_u32 prefetch020;
-    uae_u32 prefetch020pc;
-    uae_u32 prefetch020ptr;
-
     uaecptr usp, isp, msp;
     uae_u16 sr;
     flagtype t1;
@@ -140,6 +150,11 @@ extern struct regstruct
     uae_u8 panic;
     uae_u32 panic_pc, panic_addr;
 
+    uae_u32 prefetch020data;
+    uae_u32 prefetch020addr;
+    struct cache020 cacheline020[CACHELINES020];
+    struct cache020 cacheline040[CACHELINES040];
+
 } regs, lastint_regs, mmu_backup_regs;
 
 STATIC_INLINE uae_u32 munge24 (uae_u32 x)
@@ -302,8 +317,8 @@ extern void m68k_reset (int);
 extern int getDivu68kCycles(uae_u32 dividend, uae_u16 divisor);
 extern int getDivs68kCycles(uae_s32 dividend, uae_s16 divisor);
 
-extern void mmu_op       (uae_u32, uae_u32);
-extern void mmu_op30     (uaecptr, uae_u32, int, uaecptr);
+extern void mmu_op (uae_u32, uae_u32);
+extern void mmu_op30 (uaecptr, uae_u32, int, uaecptr);
 
 extern void fpuop_arithmetic(uae_u32, uae_u16);
 extern void fpuop_dbcc(uae_u32, uae_u16);
@@ -328,12 +343,16 @@ extern void fill_prefetch_slow (void);
 
 /* 68060 */
 extern const struct cputbl op_smalltbl_0_ff[];
+extern const struct cputbl op_smalltbl_20_ff[];
 /* 68040 */
 extern const struct cputbl op_smalltbl_1_ff[];
+extern const struct cputbl op_smalltbl_21_ff[];
 /* 68030 */
 extern const struct cputbl op_smalltbl_2_ff[];
+extern const struct cputbl op_smalltbl_22_ff[];
 /* 68020 */
 extern const struct cputbl op_smalltbl_3_ff[];
+extern const struct cputbl op_smalltbl_23_ff[];
 /* 68010 */
 extern const struct cputbl op_smalltbl_4_ff[];
 /* 68000 */
index b5e7c087ef42711ce2b06605faafbef067b1bf1b..1f5a8b0d829c49c48aa4470d27ff8dcfd212310d 100644 (file)
@@ -212,6 +212,8 @@ struct uae_prefs {
     int catweasel;
     int cpu_idle;
     int cpu_cycle_exact;
+    int cpu_clock_multiplier;
+    int cpu_frequency;
     int blitter_cycle_exact;
     int floppy_speed;
     int floppy_write_length;
index 1e158241adc6a8affa856fb1338e1439efaf84b4..0d2df10264417d1d9aea7e823a32e16dfc9561be 100644 (file)
@@ -25,6 +25,7 @@ extern int isfullscreen (void);
 extern void toggle_fullscreen (void);
 extern void toggle_mousegrab (void);
 extern void desktop_coords (int *dw, int *dh, int *x, int *y, int *w, int *h);
+extern int vsync_switchmode (int);
 
 extern void flush_line (int);
 extern void flush_block (int, int);
diff --git a/main.c b/main.c
index 36fbb6e6f1a8bfeda770ad7fe97f350eba9a69b3..015e39b9fa243c9539155bc3bd6927dbe3086412 100644 (file)
--- a/main.c
+++ b/main.c
@@ -120,28 +120,42 @@ void fixup_cpu (struct uae_prefs *p)
        p->address_space_24 = 1;
        if (p->cpu_compatible || p->cpu_cycle_exact)
            p->fpu_model = 0;
+       if (!p->cpu_frequency && !p->cpu_clock_multiplier)
+           p->cpu_clock_multiplier = 2 << 8;
        break;
     case 68010:
        p->address_space_24 = 1;
        if (p->cpu_compatible || p->cpu_cycle_exact)
            p->fpu_model = 0;
+       if (!p->cpu_frequency && !p->cpu_clock_multiplier)
+           p->cpu_clock_multiplier = 2 << 8;
        break;
     case 68020:
+       if (!p->cpu_frequency && !p->cpu_clock_multiplier)
+           p->cpu_clock_multiplier = 4 << 8;
        break;
     case 68030:
        p->address_space_24 = 0;
+       if (!p->cpu_frequency && !p->cpu_clock_multiplier)
+           p->cpu_clock_multiplier = 8 << 8;
        break;
     case 68040:
        p->address_space_24 = 0;
        if (p->fpu_model)
            p->fpu_model = 68040;
+       if (!p->cpu_frequency && !p->cpu_clock_multiplier)
+           p->cpu_clock_multiplier = 16 << 8;
        break;
     case 68060:
        p->address_space_24 = 0;
        if (p->fpu_model)
            p->fpu_model = 68060;
+       if (!p->cpu_frequency && !p->cpu_clock_multiplier)
+           p->cpu_clock_multiplier = 16 << 8;
        break;
     }
+    if (!p->cpu_frequency && !p->cpu_clock_multiplier)
+        p->cpu_clock_multiplier = 4 << 8;
 }
 
 
@@ -377,8 +391,10 @@ void fixup_prefs (struct uae_prefs *p)
     p->uaeserial = 0;
 #endif
 #if defined (CPUEMU_12)
-    if (p->cpu_cycle_exact)
+    if (p->cpu_cycle_exact) {
        p->gfx_framerate = 1;
+       p->cachesize = 0;
+    }
 #endif
     if (p->maprom && !p->address_space_24)
        p->maprom = 0x0f000000;
index 80eb6c361d96cae52317c6b422541812c9c31906..a0ae2a1366625f2044e7dff8a5534924c3c6c718 100644 (file)
--- a/newcpu.c
+++ b/newcpu.c
@@ -129,18 +129,34 @@ void dump_counts (void)
 
 static void set_cpu_caches (void)
 {
-#ifdef JIT
+    int i;
+
     if (currprefs.cpu_model < 68040) {
+       if (regs.cacr & 0x08) { // Clear Cache
+           for (i = 0; i < CACHELINES020; i++)
+               regs.cacheline020[i].valid = 0;
+           regs.prefetch020addr = 0xff000000;
+       }
+       if (regs.cacr & 0x04) { // Clear Entry
+           regs.cacheline020[(regs.caar >> 2) & 0x3f].valid = 0;
+       }
+#ifdef JIT
        set_cache_state (regs.cacr & 1);
        if (regs.cacr & 0x08) {
-           regs.cacr &= ~0x08;
            flush_icache (0, 3);
-           regs.prefetch020pc = regs.prefetch020ptr = 0xff000000;
        }
+#endif
+       regs.cacr &= ~0x08;
     } else {
+#ifdef JIT
        set_cache_state ((regs.cacr & 0x8000) ? 1 : 0);
-    }
 #endif
+       if (!(regs.cacr & 0x8000)) {
+           for (i = 0; i < CACHELINES040; i++)
+               regs.cacheline040[i].valid = 0;
+           regs.prefetch020addr = 0xff000000;
+       }
+    }
 }
 
 STATIC_INLINE void count_instr (unsigned int opcode)
@@ -169,20 +185,26 @@ static void build_cpufunctbl (void)
        case 68060:
        lvl = 5;
        tbl = op_smalltbl_0_ff;
+       if (currprefs.cpu_cycle_exact)
+          tbl = op_smalltbl_20_ff;
        break;
        case 68040:
        lvl = 4;
        tbl = op_smalltbl_1_ff;
+       if (currprefs.cpu_cycle_exact)
+          tbl = op_smalltbl_21_ff;
        break;
        case 68030:
        lvl = 3;
        tbl = op_smalltbl_2_ff;
+       if (currprefs.cpu_cycle_exact)
+          tbl = op_smalltbl_22_ff;
        break;
        case 68020:
        lvl = 2;
        tbl = op_smalltbl_3_ff;
        if (currprefs.cpu_cycle_exact)
-           tbl = op_smalltbl_13_ff;
+          tbl = op_smalltbl_23_ff;
        break;
        case 68010:
        lvl = 1;
@@ -1683,7 +1705,10 @@ void m68k_reset (int hardreset)
     regs.caar = regs.cacr = 0;
     regs.itt0 = regs.itt1 = regs.dtt0 = regs.dtt1 = 0;
     regs.tcr = regs.mmusr = regs.urp = regs.srp = regs.buscr = 0;
-    regs.prefetch020pc = regs.prefetch020ptr = 0xff000000;
+    if (currprefs.cpu_model == 68020) {
+       regs.cacr |= 8;
+       set_cpu_caches ();
+    }
 
     if (currprefs.mmu_model)
        mmu_reset ();
@@ -2631,7 +2656,7 @@ void m68k_go (int may_quit)
            run_func = currprefs.cpu_cycle_exact && currprefs.cpu_model == 68000 ? m68k_run_1_ce :
                   currprefs.cpu_compatible > 0 && currprefs.cpu_model == 68000 ? m68k_run_1 :
                   currprefs.cpu_model >= 68020 && currprefs.cachesize ? m68k_run_2a :
-                  currprefs.cpu_model == 68020 && currprefs.cpu_cycle_exact ? m68k_run_2ce :
+                  currprefs.cpu_model >= 68020 && currprefs.cpu_cycle_exact ? m68k_run_2ce :
                   currprefs.cpu_compatible ? m68k_run_2p : m68k_run_2;
        }
 #endif
@@ -3479,3 +3504,67 @@ int getDivs68kCycles (uae_s32 dividend, uae_s16 divisor)
 
     return mcycles * 2;
 }
+
+STATIC_INLINE void fill_cache040 (uae_u32 addr)
+{
+    int index;
+    uae_u32 tag;
+    uae_u32 data;
+    struct cache020 *c;
+
+    addr &= ~3;
+    index = (addr >> 2) & (CACHELINES040 - 1);
+    tag = regs.s | (addr & ~((CACHELINES040 << 2) - 1));
+    c = &regs.cacheline040[index];
+    if (c->valid && c->tag == tag) {
+       // cache hit
+       regs.prefetch020addr = addr;
+       regs.prefetch020data = c->data;
+       return;
+    }
+    // cache miss
+    data = mem_access_delay_longi_read_020 (addr);
+    if (1) {
+       c->tag = tag;
+       c->valid = !!(regs.cacr & 0x8000);
+       c->data = data;
+    }
+    regs.prefetch020addr = addr;
+    regs.prefetch020data = data;
+}
+
+STATIC_INLINE void fill_cache020 (uae_u32 addr)
+{
+    int index;
+    uae_u32 tag;
+    uae_u32 data;
+    struct cache020 *c;
+
+    addr &= ~3;
+    index = (addr >> 2) & (CACHELINES020 - 1);
+    tag = regs.s | (addr & ~((CACHELINES020 << 2) - 1));
+    c = &regs.cacheline020[index];
+    if (c->valid && c->tag == tag) {
+       // cache hit
+       regs.prefetch020addr = addr;
+       regs.prefetch020data = c->data;
+       return;
+    }
+    // cache miss
+    data = mem_access_delay_longi_read_020 (addr);
+    if (!(regs.caar & 2)) {
+       c->tag = tag;
+       c->valid = !!(regs.cacr & 1);
+       c->data = data;
+    }
+    regs.prefetch020addr = addr;
+    regs.prefetch020data = data;
+}
+
+void fill_cache0x0 (uae_u32 addr)
+{
+    if (currprefs.cpu_model >= 68040)
+       fill_cache040 (addr);
+    else
+       fill_cache020 (addr);
+}
index fb4ccf7a323caf315ca9d8bf89a6e7f5dd45fa0e..d5946194c5d2ee911de53c8b54918ff198101da0 100644 (file)
@@ -23,6 +23,7 @@ del compstbl.c
 del cpuemu_0.c
 del cpuemu_11.c
 del cpuemu_12.c
+del cpuemu_20.c
 del linetoscr.c
 
 cd jit
index 622674cdb07f7e329bd98c8a25b4ad0b2d484a1d..baae7175caddcd9e2558bf52d3d59e04bafa755d 100644 (file)
@@ -46,7 +46,7 @@
 #define CPUEMU_0 /* generic 680x0 emulation */
 #define CPUEMU_11 /* 68000+prefetch emulation */
 #define CPUEMU_12 /* 68000 cycle-exact cpu&blitter */
-#define CPUEMU_13 /* 68020 "cycle-exact" + blitter */
+#define CPUEMU_20 /* 68020+ "cycle-exact" + blitter */
 #define ACTION_REPLAY /* Action Replay 1/2/3 support */
 #define PICASSO96 /* Picasso96 display card emulation */
 #define UAEGFX_INTERNAL /* built-in libs:picasso96/uaegfx.card */
index 2680b607c865ca15c625d2ba7aea3909b4b183e8..74d2871915906ca7a64ecf9be7a416420f20cf3f 100644 (file)
@@ -17,8 +17,8 @@
 
 #define WINUAEPUBLICBETA 1
 
-#define WINUAEBETA L"7"
-#define WINUAEDATE MAKEBD(2009, 8, 16)
+#define WINUAEBETA L"8"
+#define WINUAEDATE MAKEBD(2009, 8, 19)
 #define WINUAEEXTRA L""
 #define WINUAEREV L""
 
index a6303ee8721fe3007ba1fe5fd5c414609e0c59f7..3c4df63e02a8e2905bde3f535a59453730016b40 100644 (file)
@@ -327,8 +327,10 @@ static int set_ddraw_2 (void)
                    break;
                }
            }
-           if (got == FALSE)
+           if (got == FALSE) {
+               write_log (L"set_ddraw: refresh rate %d not supported\n", freq);
                freq = 0;
+           }
            write_log (L"set_ddraw: trying %dx%d, bits=%d, refreshrate=%d\n", width, height, bits, freq);
            ddrval = DirectDraw_SetDisplayMode (width, height, bits, freq);
            if (SUCCEEDED (ddrval))
@@ -1692,6 +1694,52 @@ static int reopen (int full)
     return 0;
 }
 
+int vsync_switchmode (int hz)
+{
+    static int tempvsync;
+    int w = currentmode->native_width;
+    int h = currentmode->native_height;
+    int d = currentmode->native_depth / 8;
+    struct MultiDisplay *md = getdisplay (&currprefs);
+    struct PicassoResolution *found = NULL;
+    int newh, i, cnt;
+
+    if (hz < 0)
+       return tempvsync;
+
+    if (currprefs.ntscmode)
+       newh = h * 312 / 262;
+    else
+       newh = h * 262 / 312;
+
+    for (cnt = 0; cnt <= abs (newh - h) && !found; cnt++) {
+       for (i = 0; md->DisplayModes[i].depth >= 0 && !found; i++) {
+           struct PicassoResolution *r = &md->DisplayModes[i];
+           if (r->res.width == w && (r->res.height == newh + cnt || r->res.height == newh - cnt) && r->depth == d) {
+               int j;
+               for (j = 0; r->refresh[j] > 0; j++) {
+                   if (r->refresh[j] == hz) {
+                       found = r;
+                       break;
+                   }
+               }
+           }
+       }
+    }
+    if (!found) {
+       tempvsync = currprefs.gfx_avsync;
+       changed_prefs.gfx_avsync = 0;
+       write_log (L"refresh rate changed to %d but no matching screenmode found, vsync disabled\n", hz);
+    } else {
+       newh = found->res.height;
+       changed_prefs.gfx_size_fs.height = newh;
+       changed_prefs.gfx_refreshrate = hz;
+       write_log (L"refresh rate changed to %d, new screenmode %dx%d\n", hz, w, newh);
+    }
+    reopen (1);
+    return 0;
+}
+
 #ifdef PICASSO96
 
 static int modeswitchneeded (struct winuae_currentmode *wc)
index c69b2fd4e501baf01fe676e8a65d73e76c657f3c..935b24631aaebd1b846df8c94aeb04586c2be611 100644 (file)
@@ -1462,7 +1462,7 @@ static void gui_to_prefs (void)
     /* filesys hack */
     currprefs.mountitems = changed_prefs.mountitems;
     memcpy (&currprefs.mountconfig, &changed_prefs.mountconfig, MOUNT_CONFIG_SIZE * sizeof (struct uaedev_config_info));
-
+    fixup_prefs (&changed_prefs);
     updatewinfsmode (&changed_prefs);
 }
 
index d98210fe338468e4f2f10cedb2e7adf102662a8e..1572f46265efd3b132433aab320a0a685ddb10d4 100644 (file)
                                        >
                                </File>
                                <File
-                                       RelativePath=".\configfile.ico"
+                                       RelativePath="..\resources\configfile.ico"
                                        >
                                </File>
                                <File
-                                       RelativePath="..\resources\configfile.ico"
+                                       RelativePath=".\configfile.ico"
                                        >
                                </File>
                                <File
                                        >
                                </File>
                                <File
-                                       RelativePath=".\file.ico"
+                                       RelativePath="..\resources\file.ico"
                                        >
                                </File>
                                <File
-                                       RelativePath="..\resources\file.ico"
+                                       RelativePath=".\file.ico"
                                        >
                                </File>
                                <File
                                        >
                                </File>
                                <File
-                                       RelativePath="..\resources\port.ico"
+                                       RelativePath=".\port.ico"
                                        >
                                </File>
                                <File
-                                       RelativePath=".\port.ico"
+                                       RelativePath="..\resources\port.ico"
                                        >
                                </File>
                                <File
                                >
                        </File>
                        <File
-                               RelativePath="..\..\cpuemu_13.c"
+                               RelativePath="..\..\cpuemu_20.c"
                                >
                        </File>
                        <File
index 6b8d251fa3a8a289dcbb05fd7baf1f051574a6fa..b6a686e285b18e5be44454a6582cf184d97fcd90 100644 (file)
@@ -1,4 +1,36 @@
 
+Beta 8:
+
+68020 CE mode updates:
+
+- unaligned word/long accesses emulated (68020 always fetches aligned
+  longs, two accesses required if for example word is fetched
+  from address 3)
+- emulate 68020 instruction cache logic as documented in 68020 manual,
+  cache hits are free, cache misses require normal, possibly slow
+  chip ram fetch
+- approximate emulation of 68020 prefetch buffer, more compatible with
+  self-modifying code
+- very approximate 68020 MUL/DIV cycle usage added
+- 68030/040/060 also supported in "020CE" mode. Not totally useless
+  because this can mean more compatible HD installed games by switching
+  between JIT and "CE" mode on the fly using uae-configuration.
+  (switching between CPU types on the fly isn't very good idea..)
+
+Note that 68020 "CE" is still too fast (CPU internal calculations are
+not counted yet) but this is 100x better than previously because
+memory fetches are emulated, too fast CPU chip memory accesses and
+too fast blitter was the most common cause for problems.
+
+- CD32 drive command communication and interrupt handling rewritten,
+  should now match real hardware (I think..) At least Brian the Lion
+  CD32 works again..
+- automatic vsync mode on the fly switching between 50Hz and 60Hz
+  screen modes if refresh rate is supported, disable vsync temporarily
+  if rate not supported (until switching back to supported rate)
+- Superstardust AGA weapon panel breaks if 1 extra BPLCON0 delay cycle
+  added. Obviously previous fix wasn't right.. Lets try something else,
+  add extra cycle if first bpl dma cycle is allocated (8 planes)
 
 Beta 7:
 
@@ -20,7 +52,9 @@ Beta 7:
   extra cycles) Quickstart A1200/CD32 most compatible now enables this
   new CE-mode. Some weird sound problems can be noticed, reason unknown..
 
-Two above changes can break lots of things as usual..
+Two above changes can break lots of things as usual.. Binary size also
+increased, 4th CPU core added (68020CE) and finally, next official
+version is now guaranteed to not be 1.6.2..
 
 Beta 6: