]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
2700b7
authorToni Wilen <twilen@winuae.net>
Sun, 1 Sep 2013 11:43:08 +0000 (14:43 +0300)
committerToni Wilen <twilen@winuae.net>
Sun, 1 Sep 2013 11:43:08 +0000 (14:43 +0300)
40 files changed:
akiko.cpp
archivers/lzx/unlzx.cpp
audio.cpp
blkdev.cpp
build68k.cpp
cfgfile.cpp
custom.cpp
debug.cpp
disk.cpp
filesys.cpp
gayle.cpp
gencpu.cpp
gfxboard.cpp
include/audio.h
include/cpu_prefetch.h
include/newcpu.h
include/options.h
include/readcpu.h
include/savestate.h
include/scsi.h
main.cpp
memory.cpp
newcpu.cpp
od-win32/dinput.cpp
od-win32/direct3d.cpp
od-win32/direct3d.h
od-win32/hardfile_win32.cpp
od-win32/mman.cpp
od-win32/resources/resource.h
od-win32/resources/winuae.rc
od-win32/win32.cpp
od-win32/win32.h
od-win32/win32gfx.cpp
od-win32/win32gui.cpp
readcpu.cpp
savestate.cpp
scsi.cpp
scsiemul.cpp
scsitape.cpp
table68k

index 3a1ad119ecc8b9ed42236b14fc3f0a64feac7bbe..300a2a2f0f19c3285a63cb83bd40e6325f5ec520 100644 (file)
--- a/akiko.cpp
+++ b/akiko.cpp
@@ -1376,7 +1376,6 @@ static void *akiko_thread (void *null)
        uae_u8 *tmp1;
        uae_u8 *tmp2;
        int tmp3;
-       int offset;
        int sector;
 
        while (akiko_thread_running || comm_pipe_has_data (&requests)) {
@@ -1442,19 +1441,30 @@ static void *akiko_thread (void *null)
                }
                if (cdrom_data_end > 0 && sector >= 0 &&
                        (sector_buffer_sector_1 < 0 || sector < sector_buffer_sector_1 || sector >= sector_buffer_sector_1 + SECTOR_BUFFER_SIZE * 2 / 3 || i != SECTOR_BUFFER_SIZE)) {
+                               int blocks;
                                memset (sector_buffer_info_2, 0, SECTOR_BUFFER_SIZE);
 #if AKIKO_DEBUG_IO_CMD
                                write_log (_T("filling buffer sector=%d (max=%d)\n"), sector, cdrom_data_end);
 #endif
                                sector_buffer_sector_2 = sector;
-                               offset = 0;
-                               while (offset < SECTOR_BUFFER_SIZE) {
-                                       int ok = 0;
-                                       if (sector < cdrom_data_end)
-                                               ok = sys_command_cd_rawread (unitnum, sector_buffer_2 + offset * 2352, sector, 1, 2352);
-                                       sector_buffer_info_2[offset] = ok ? 3 : 0;
-                                       offset++;
-                                       sector++;
+                               if (sector + SECTOR_BUFFER_SIZE >= cdrom_data_end)
+                                       blocks = cdrom_data_end - sector;
+                               else
+                                       blocks = SECTOR_BUFFER_SIZE;
+                               int ok = sys_command_cd_rawread (unitnum, sector_buffer_2, sector, blocks, 2352);
+                               if (!ok) {
+                                       int offset = 0;
+                                       while (offset < SECTOR_BUFFER_SIZE) {
+                                               int ok = 0;
+                                               if (sector < cdrom_data_end)
+                                                       ok = sys_command_cd_rawread (unitnum, sector_buffer_2 + offset * 2352, sector, 1, 2352);
+                                               sector_buffer_info_2[offset] = ok ? 3 : 0;
+                                               offset++;
+                                               sector++;
+                                       }
+                               } else {
+                                       for (int i = 0; i < SECTOR_BUFFER_SIZE; i++)
+                                               sector_buffer_info_2[i] = i < blocks ? 3 : 0;
                                }
                                tmp1 = sector_buffer_info_1;
                                sector_buffer_info_1 = sector_buffer_info_2;
index 373a6ce2d9f60d038368615373710d6f7ea7f19d..2e048f70cb3446996c66832d00630b59812765c9 100644 (file)
@@ -32,6 +32,8 @@
 
 /* - minimal UAE specific version 13-14.06.2007 by Toni Wilen */
 
+#define LZX_ERROR_CHECK 1
+
 #include <stdlib.h>
 #include <stdio.h>
 
 
 /* ---------------------------------------------------------------------- */
 
-static unsigned char *source;
-static unsigned char *destination;
-static unsigned char *source_end;
-static unsigned char *destination_end;
-
-static unsigned int decrunch_method;
-static unsigned int decrunch_length;
-static unsigned int last_offset;
-static unsigned int global_control;
-static int global_shift;
-
-static unsigned char offset_len[8];
-static unsigned short offset_table[128];
-static unsigned char huffman20_len[20];
-static unsigned short huffman20_table[96];
-static unsigned char literal_len[768];
-static unsigned short literal_table[5120];
+struct lzxdata
+{
+  unsigned char *source;
+  unsigned char *destination;
+  unsigned char *source_end;
+  unsigned char *destination_end;
+
+  unsigned short decrunch_method;
+  unsigned int decrunch_length;
+  unsigned int last_offset;
+  unsigned int global_control;
+  short global_shift;
+  unsigned int sum;
+
+  unsigned char offset_len[8];
+  unsigned short offset_table[128];
+  unsigned char huffman20_len[20];
+  unsigned short huffman20_table[96];
+  unsigned char literal_len[768];
+  unsigned short literal_table[5120];
+};
 
 /* ---------------------------------------------------------------------- */
 
-static unsigned int sum;
-
 static const unsigned int crc_table[256]=
 {
  0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,
@@ -141,18 +145,18 @@ static const unsigned char table_four[34]=
 /* Possible problems with 64 bit machines here. It kept giving warnings   */
 /* for people so I changed back to ~.                                     */
 
-static void crc_calc(unsigned char *memory, unsigned int length)
+static void crc_calc(struct lzxdata *d, unsigned char *memory, unsigned int length)
 {
  register unsigned int temp;
 
  if(length)
  {
-  temp = ~sum; /* was (sum ^ 4294967295) */
+  temp = ~d->sum; /* was (sum ^ 4294967295) */
   do
   {
    temp = crc_table[(*memory++ ^ temp) & 255] ^ (temp >> 8);
   } while(--length);
-  sum = ~temp; /* was (temp ^ 4294967295) */
+  d->sum = ~temp; /* was (temp ^ 4294967295) */
  }
 }
 
@@ -161,14 +165,17 @@ static void crc_calc(unsigned char *memory, unsigned int length)
 /* Build a fast huffman decode table from the symbol bit lengths.         */
 /* There is an alternate algorithm which is faster but also more complex. */
 
-static int make_decode_table(int number_symbols, int table_size,
+static int make_decode_table(struct lzxdata *d, short number_symbols, short table_size,
                      unsigned char *length, unsigned short *table)
 {
  register unsigned char bit_num = 0;
- register int symbol;
- unsigned int leaf; /* could be a register */
- unsigned int table_mask, bit_mask, pos, fill, next_symbol, reverse;
- int abort = 0;
+ register short symbol;
+ unsigned short leaf; /* could be a register */
+ unsigned short bit_mask, fill, next_symbol, reverse;
+ unsigned int table_mask, pos;
+#if LZX_ERROR_CHECK
+ short abort = 0;
+#endif
 
  pos = 0; /* consistantly used as the current position in the decode table */
 
@@ -177,7 +184,7 @@ static int make_decode_table(int number_symbols, int table_size,
  bit_mask >>= 1; /* don't do the first number */
  bit_num++;
 
- while((!abort) && (bit_num <= table_size))
+ while(bit_num <= table_size)
  {
   for(symbol = 0; symbol < number_symbols; symbol++)
   {
@@ -191,12 +198,15 @@ static int make_decode_table(int number_symbols, int table_size,
      leaf = (leaf << 1) + (reverse & 1);
      reverse >>= 1;
     } while(--fill);
-    if((pos += bit_mask) > table_mask)
+       pos += bit_mask;
+#if LZX_ERROR_CHECK
+       if(pos > table_mask)
     {
-     abort = 1;
-     break; /* we will overrun the table! abort! */
+        /* we will overrun the table! abort! */
+        return 1;
     }
-    fill = bit_mask;
+#endif
+       fill = bit_mask;
     next_symbol = 1 << bit_num;
     do
     {
@@ -209,7 +219,7 @@ static int make_decode_table(int number_symbols, int table_size,
   bit_num++;
  }
 
- if((!abort) && (pos != table_mask))
+ if(pos != table_mask)
  {
   for(symbol = pos; symbol < table_mask; symbol++) /* clear the rest of the table */
   {
@@ -228,7 +238,7 @@ static int make_decode_table(int number_symbols, int table_size,
   table_mask <<= 16;
   bit_mask = 32768;
 
-  while((!abort) && (bit_num <= 16))
+  while(bit_num <= 16)
   {
    for(symbol = 0; symbol < number_symbols; symbol++)
    {
@@ -254,20 +264,24 @@ static int make_decode_table(int number_symbols, int table_size,
       leaf += (pos >> (15 - fill)) & 1;
      }
      table[leaf] = symbol;
-     if((pos += bit_mask) > table_mask)
+        pos += bit_mask;
+#if LZX_ERROR_CHECK
+        if(pos > table_mask)
      {
-      abort = 1;
-      break; /* we will overrun the table! abort! */
+      /* we will overrun the table! abort! */
+         return 1;
      }
+#endif
     }
    }
    bit_mask >>= 1;
    bit_num++;
   }
  }
- if(pos != table_mask) abort = 1; /* the table is incomplete! */
-
- return(abort);
+#if LZX_ERROR_CHECK
+ if(pos != table_mask) return 1; /* the table is incomplete! */
+#endif
+ return 0;
 }
 
 /* ---------------------------------------------------------------------- */
@@ -275,86 +289,91 @@ static int make_decode_table(int number_symbols, int table_size,
 /* Read and build the decrunch tables. There better be enough data in the */
 /* source buffer or it's stuffed. */
 
-static int read_literal_table()
+static int read_literal_table(struct lzxdata *d)
 {
  register unsigned int control;
- register int shift;
- unsigned int temp; /* could be a register */
- unsigned int symbol, pos, count, fix, max_symbol;
- int abort = 0;
+ register short shift;
+ unsigned short temp; /* could be a register */
+ unsigned short symbol, pos, count, fix, max_symbol;
+#if LZX_ERROR_CHECK
+ short abort = 0;
+#endif
 
- control = global_control;
- shift = global_shift;
+ control = d->global_control;
+ shift = d->global_shift;
 
  if(shift < 0) /* fix the control word if necessary */
  {
   shift += 16;
-  control += *source++ << (8 + shift);
-  control += *source++ << shift;
+  control += *d->source++ << (8 + shift);
+  control += *d->source++ << shift;
  }
 
 /* read the decrunch method */
 
- decrunch_method = control & 7;
+ d->decrunch_method = control & 7;
  control >>= 3;
  if((shift -= 3) < 0)
  {
   shift += 16;
-  control += *source++ << (8 + shift);
-  control += *source++ << shift;
+  control += *d->source++ << (8 + shift);
+  control += *d->source++ << shift;
  }
 
 /* Read and build the offset huffman table */
 
- if((!abort) && (decrunch_method == 3))
+ if(d->decrunch_method == 3)
  {
   for(temp = 0; temp < 8; temp++)
   {
-   offset_len[temp] = control & 7;
+   d->offset_len[temp] = control & 7;
    control >>= 3;
    if((shift -= 3) < 0)
    {
     shift += 16;
-    control += *source++ << (8 + shift);
-    control += *source++ << shift;
+    control += *d->source++ << (8 + shift);
+    control += *d->source++ << shift;
    }
   }
-  abort = make_decode_table(8, 7, offset_len, offset_table);
+#if LZX_ERROR_CHECK
+  abort = make_decode_table(d, 8, 7, d->offset_len, d->offset_table);
+  if (abort)
+         return abort;
+#else
+  make_decode_table(d, 8, 7, d->offset_len, d->offset_table);
+#endif
  }
 
 /* read decrunch length */
 
- if(!abort)
- {
-  decrunch_length = (control & 255) << 16;
+  d->decrunch_length = (control & 255) << 16;
   control >>= 8;
   if((shift -= 8) < 0)
   {
    shift += 16;
-   control += *source++ << (8 + shift);
-   control += *source++ << shift;
+   control += *d->source++ << (8 + shift);
+   control += *d->source++ << shift;
   }
-  decrunch_length += (control & 255) << 8;
+  d->decrunch_length += (control & 255) << 8;
   control >>= 8;
   if((shift -= 8) < 0)
   {
    shift += 16;
-   control += *source++ << (8 + shift);
-   control += *source++ << shift;
+   control += *d->source++ << (8 + shift);
+   control += *d->source++ << shift;
   }
-  decrunch_length += (control & 255);
+  d->decrunch_length += (control & 255);
   control >>= 8;
   if((shift -= 8) < 0)
   {
    shift += 16;
-   control += *source++ << (8 + shift);
-   control += *source++ << shift;
+   control += *d->source++ << (8 + shift);
+   control += *d->source++ << shift;
   }
- }
 
 /* read and build the huffman literal table */
 
- if((!abort) && (decrunch_method != 1))
+ if(d->decrunch_method != 1)
  {
   pos = 0;
   fix = 1;
@@ -364,31 +383,35 @@ static int read_literal_table()
   {
    for(temp = 0; temp < 20; temp++)
    {
-    huffman20_len[temp] = control & 15;
+    d->huffman20_len[temp] = control & 15;
     control >>= 4;
     if((shift -= 4) < 0)
     {
      shift += 16;
-     control += *source++ << (8 + shift);
-     control += *source++ << shift;
+     control += *d->source++ << (8 + shift);
+     control += *d->source++ << shift;
     }
    }
-   abort = make_decode_table(20, 6, huffman20_len, huffman20_table);
-
-   if(abort) break; /* argh! table is corrupt! */
+#if LZX_ERROR_CHECK
+   abort = make_decode_table(d, 20, 6, d->huffman20_len, d->huffman20_table);
+   if (abort)
+          return abort;
+#else
+   make_decode_table(d, 20, 6, d->huffman20_len, d->huffman20_table);
+#endif
 
    do
    {
-    if((symbol = huffman20_table[control & 63]) >= 20)
+    if((symbol = d->huffman20_table[control & 63]) >= 20)
     {
      do /* symbol is longer than 6 bits */
      {
-      symbol = huffman20_table[((control >> 6) & 1) + (symbol << 1)];
+      symbol = d->huffman20_table[((control >> 6) & 1) + (symbol << 1)];
       if(!shift--)
       {
        shift += 16;
-       control += *source++ << 24;
-       control += *source++ << 16;
+       control += *d->source++ << 24;
+       control += *d->source++ << 16;
       }
       control >>= 1;
      } while(symbol >= 20);
@@ -396,14 +419,14 @@ static int read_literal_table()
     }
     else
     {
-     temp = huffman20_len[symbol];
+     temp = d->huffman20_len[symbol];
     }
     control >>= temp;
     if((shift -= temp) < 0)
     {
      shift += 16;
-     control += *source++ << (8 + shift);
-     control += *source++ << shift;
+     control += *d->source++ << (8 + shift);
+     control += *d->source++ << shift;
     }
     switch(symbol)
     {
@@ -425,11 +448,11 @@ static int read_literal_table()
       if((shift -= temp) < 0)
       {
        shift += 16;
-       control += *source++ << (8 + shift);
-       control += *source++ << shift;
+       control += *d->source++ << (8 + shift);
+       control += *d->source++ << shift;
       }
       while((pos < max_symbol) && (count--))
-       literal_len[pos++] = 0;
+       d->literal_len[pos++] = 0;
       break;
      }
      case 19:
@@ -438,20 +461,20 @@ static int read_literal_table()
       if(!shift--)
       {
        shift += 16;
-       control += *source++ << 24;
-       control += *source++ << 16;
+       control += *d->source++ << 24;
+       control += *d->source++ << 16;
       }
       control >>= 1;
-      if((symbol = huffman20_table[control & 63]) >= 20)
+      if((symbol = d->huffman20_table[control & 63]) >= 20)
       {
        do /* symbol is longer than 6 bits */
        {
-       symbol = huffman20_table[((control >> 6) & 1) + (symbol << 1)];
+       symbol = d->huffman20_table[((control >> 6) & 1) + (symbol << 1)];
        if(!shift--)
        {
         shift += 16;
-        control += *source++ << 24;
-        control += *source++ << 16;
+        control += *d->source++ << 24;
+        control += *d->source++ << 16;
        }
        control >>= 1;
        } while(symbol >= 20);
@@ -459,24 +482,24 @@ static int read_literal_table()
       }
       else
       {
-       temp = huffman20_len[symbol];
+       temp = d->huffman20_len[symbol];
       }
       control >>= temp;
       if((shift -= temp) < 0)
       {
        shift += 16;
-       control += *source++ << (8 + shift);
-       control += *source++ << shift;
+       control += *d->source++ << (8 + shift);
+       control += *d->source++ << shift;
       }
-      symbol = table_four[literal_len[pos] + 17 - symbol];
+      symbol = table_four[d->literal_len[pos] + 17 - symbol];
       while((pos < max_symbol) && (count--))
-       literal_len[pos++] = symbol;
+       d->literal_len[pos++] = symbol;
       break;
      }
      default:
      {
-      symbol = table_four[literal_len[pos] + 17 - symbol];
-      literal_len[pos++] = symbol;
+      symbol = table_four[d->literal_len[pos] + 17 - symbol];
+      d->literal_len[pos++] = symbol;
       break;
      }
     }
@@ -485,14 +508,19 @@ static int read_literal_table()
    max_symbol += 512;
   } while(max_symbol == 768);
 
-  if(!abort)
-   abort = make_decode_table(768, 12, literal_len, literal_table);
+#if LZX_ERROR_CHECK
+   abort = make_decode_table(d, 768, 12, d->literal_len, d->literal_table);
+   if (abort)
+          return abort;
+#else
+   make_decode_table(d, 768, 12, d->literal_len, d->literal_table);
+#endif
  }
 
- global_control = control;
- global_shift = shift;
d->global_control = control;
d->global_shift = shift;
 
- return(abort);
+ return 0;
 }
 
 /* ---------------------------------------------------------------------- */
@@ -501,61 +529,61 @@ static int read_literal_table()
 /* and source buffers. Most of the time is spent in this routine so it's  */
 /* pretty damn optimized. */
 
-static void decrunch(void)
+static void decrunch(struct lzxdata *d)
 {
  register unsigned int control;
- register int shift;
- unsigned int temp; /* could be a register */
- unsigned int symbol, count;
+ register short shift;
+ unsigned short temp; /* could be a register */
+ unsigned short symbol, count;
  unsigned char *string;
 
- control = global_control;
- shift = global_shift;
+ control = d->global_control;
+ shift = d->global_shift;
 
  do
  {
-  if((symbol = literal_table[control & 4095]) >= 768)
+  if((symbol = d->literal_table[control & 4095]) >= 768)
   {
    control >>= 12;
    if((shift -= 12) < 0)
    {
     shift += 16;
-    control += *source++ << (8 + shift);
-    control += *source++ << shift;
+    control |= *d->source++ << (8 + shift);
+    control |= *d->source++ << shift;
    }
    do /* literal is longer than 12 bits */
    {
-    symbol = literal_table[(control & 1) + (symbol << 1)];
+    symbol = d->literal_table[(control & 1) + (symbol << 1)];
     if(!shift--)
     {
      shift += 16;
-     control += *source++ << 24;
-     control += *source++ << 16;
+     control |= *d->source++ << 24;
+     control |= *d->source++ << 16;
     }
     control >>= 1;
    } while(symbol >= 768);
   }
   else
   {
-   temp = literal_len[symbol];
+   temp = d->literal_len[symbol];
    control >>= temp;
    if((shift -= temp) < 0)
    {
     shift += 16;
-    control += *source++ << (8 + shift);
-    control += *source++ << shift;
+    control |= *d->source++ << (8 + shift);
+    control |= *d->source++ << shift;
    }
   }
   if(symbol < 256)
   {
-   *destination++ = symbol;
+   *d->destination++ = symbol;
   }
   else
   {
    symbol -= 256;
    count = table_two[temp = symbol & 31];
    temp = table_one[temp];
-   if((temp >= 3) && (decrunch_method == 3))
+   if((temp >= 3) && (d->decrunch_method == 3))
    {
     temp -= 3;
     count += ((control & table_three[temp]) << 3);
@@ -563,25 +591,25 @@ static void decrunch(void)
     if((shift -= temp) < 0)
     {
      shift += 16;
-     control += *source++ << (8 + shift);
-     control += *source++ << shift;
+     control |= *d->source++ << (8 + shift);
+     control |= *d->source++ << shift;
     }
-    count += (temp = offset_table[control & 127]);
-    temp = offset_len[temp];
+    count += (temp = d->offset_table[control & 127]);
+    temp = d->offset_len[temp];
    }
    else
    {
     count += control & table_three[temp];
-    if(!count) count = last_offset;
+    if(!count) count = d->last_offset;
    }
    control >>= temp;
    if((shift -= temp) < 0)
    {
     shift += 16;
-    control += *source++ << (8 + shift);
-    control += *source++ << shift;
+    control |= *d->source++ << (8 + shift);
+    control |= *d->source++ << shift;
    }
-   last_offset = count;
+   d->last_offset = count;
 
    count = table_two[temp = (symbol >> 5) & 15] + 3;
    temp = table_one[temp];
@@ -590,19 +618,20 @@ static void decrunch(void)
    if((shift -= temp) < 0)
    {
     shift += 16;
-    control += *source++ << (8 + shift);
-    control += *source++ << shift;
+    control |= *d->source++ << (8 + shift);
+    control |= *d->source++ << shift;
    }
-   string = destination - last_offset;
+
+   string = d->destination - d->last_offset;
    do
    {
-    *destination++ = *string++;
+    *d->destination++ = *string++;
    } while(--count);
   }
- } while((destination < destination_end) && (source < source_end));
+ } while((d->destination < d->destination_end) && (d->source < d->source_end));
 
- global_control = control;
- global_shift = shift;
d->global_control = control;
d->global_shift = shift;
 }
 
 struct zfile *archive_access_lzx (struct znode *zn)
@@ -611,8 +640,9 @@ struct zfile *archive_access_lzx (struct znode *zn)
     struct znode *znfirst, *znlast;
     struct zfile *zf = zn->volume->archive;
     struct zfile *dstf, *newzf;
-    uae_u8 *buf, *dbuf;
+    uae_u8 *buf, *dbuf, *dbufend;
     unsigned int compsize, unpsize;
+       struct lzxdata d = { 0 };
 
     dstf = NULL;
     buf = dbuf = NULL;
@@ -622,68 +652,71 @@ struct zfile *archive_access_lzx (struct znode *zn)
     unpsize = 0;
     znfirst = zn;
     while (znfirst->prev) {
-       struct znode *zt = znfirst->prev;
-       if (!zt || zt->offset != 0)
-           break;
-       znfirst = zt;
-       unpsize += znfirst->size;
+               struct znode *zt = znfirst->prev;
+               if (!zt || zt->offset != 0)
+                       break;
+               znfirst = zt;
+               unpsize += znfirst->size;
     }
     /* find last file in compressed block */
     znlast = zn;
     while (znlast) {
-       unpsize += znlast->size;
-       if (znlast->offset != 0)
-           break;
-       znlast = znlast->next;
+               unpsize += znlast->size;
+               if (znlast->offset != 0)
+                       break;
+               znlast = znlast->next;
     }
     if (!znlast)
-       return NULL;
+               return NULL;
     /* start offset to compressed block */
     startpos = znlast->offset;
     compsize = znlast->packedsize;
     zfile_fseek (zf, startpos, SEEK_SET);
-    buf = xmalloc (uae_u8, compsize);
+    buf = xmalloc (uae_u8, compsize + 1);
+       buf[compsize] = 0;
     zfile_fread (buf, compsize, 1, zf);
     dbuf = xcalloc (uae_u8, unpsize);
 
     /* unpack complete block */
-    memset(offset_len, 0, sizeof offset_len);
-    memset(literal_len, 0, sizeof literal_len);
-    sum = 0;
-    source = buf;
-    source_end = buf + compsize;
-    global_control = 0;
-    global_shift = -16;
-    last_offset = 1;
-    destination = dbuf;
+    d.source = buf;
+    d.source_end = buf + compsize + 1;
+    d.global_control = 0;
+    d.global_shift = -16;
+    d.last_offset = 1;
+    d.destination = dbuf;
+       dbufend = dbuf + unpsize;
+       int outsize = 0;
     if (compsize == unpsize) {
-       memcpy (dbuf, buf, unpsize);
+               memcpy (dbuf, buf, unpsize);
     } else {
-       while (unpsize > 0) {
-           uae_u8 *pdest = destination;
-           if (!read_literal_table()) {
-               destination_end = destination + decrunch_length;
-               decrunch();
-               unpsize -= decrunch_length;
-               crc_calc (pdest, decrunch_length);
-           } else {
-               write_log (_T("LZX corrupt compressed data %s\n"), zn->name);
-               goto end;
-           }
-       }
+               while (unpsize > 0) {
+                       uae_u8 *pdest = d.destination;
+                       if (!read_literal_table(&d)) {
+                               d.destination_end = d.destination + d.decrunch_length;
+                               if (d.destination_end > dbufend)
+                                       goto end;
+                               decrunch(&d);
+                               outsize += d.decrunch_length;
+                               unpsize -= d.decrunch_length;
+                               crc_calc (&d, pdest, d.decrunch_length);
+                       } else {
+                               write_log (_T("LZX corrupt compressed data %s\n"), zn->name);
+                               goto end;
+                       }
+               }
     }
     /* pre-cache all files we just decompressed */
     for (;;) {
-       if (znfirst->size && !znfirst->f) {
-           dstf = zfile_fopen_empty (zf, znfirst->name, znfirst->size);
-           zfile_fwrite(dbuf + znfirst->offset2, znfirst->size, 1, dstf);
-           znfirst->f = dstf;
-           if (znfirst == zn)
-               newzf = zfile_dup (dstf);
-       }
-       if (znfirst == znlast)
-           break;
-       znfirst = znfirst->next;
+               if (znfirst->size && !znfirst->f) {
+                       dstf = zfile_fopen_empty (zf, znfirst->name, znfirst->size);
+                       zfile_fwrite(dbuf + znfirst->offset2, znfirst->size, 1, dstf);
+                       znfirst->f = dstf;
+                       if (znfirst == zn)
+                       newzf = zfile_dup (dstf);
+               }
+               if (znfirst == znlast)
+                       break;
+               znfirst = znfirst->next;
     }
 end:
     xfree(buf);
@@ -711,6 +744,7 @@ struct zvolume *archive_directory_lzx (struct zfile *in_file)
  unsigned char archive_header[31];
  char header_filename[256];
  char header_comment[256];
+ struct lzxdata d = { 0 };
 
  if (zfile_fread(archive_header, 1, 10, in_file) != 10)
      return 0;
@@ -728,13 +762,13 @@ struct zvolume *archive_directory_lzx (struct zfile *in_file)
    {
     if(actual == 31)
     {
-     sum = 0; /* reset CRC */
+     d.sum = 0; /* reset CRC */
      crc = (archive_header[29] << 24) + (archive_header[28] << 16) + (archive_header[27] << 8) + archive_header[26];
      archive_header[29] = 0; /* Must set the field to 0 before calculating the crc */
      archive_header[28] = 0;
      archive_header[27] = 0;
      archive_header[26] = 0;
-     crc_calc(archive_header, 31);
+     crc_calc(&d, archive_header, 31);
      temp = archive_header[30]; /* filename length */
      actual = zfile_fread(header_filename, 1, temp, in_file);
      if(!zfile_ferror(in_file))
@@ -742,7 +776,7 @@ struct zvolume *archive_directory_lzx (struct zfile *in_file)
       if(actual == temp)
       {
        header_filename[temp] = 0;
-       crc_calc((unsigned char*)header_filename, temp);
+       crc_calc(&d, (unsigned char*)header_filename, temp);
        temp = archive_header[14]; /* comment length */
        actual = zfile_fread(header_comment, 1, temp, in_file);
        if(!zfile_ferror(in_file))
@@ -750,8 +784,8 @@ struct zvolume *archive_directory_lzx (struct zfile *in_file)
        if(actual == temp)
        {
         header_comment[temp] = 0;
-        crc_calc((unsigned char*)header_comment, temp);
-        if(sum == crc)
+        crc_calc(&d, (unsigned char*)header_comment, temp);
+        if(d.sum == crc)
         {
          unsigned int year, month, day;
          unsigned int hour, minute, second;
index 8fbdc5899fd98111fee68b253fc3e41afc6a7026..6ec40ecd8de17c36cac7dfd6291b82f6501fd8de 100644 (file)
--- a/audio.cpp
+++ b/audio.cpp
@@ -1101,12 +1101,11 @@ static void audio_event_reset (void)
        doublesample = 0;
 }
 
-static void audio_deactivate (void)
+void audio_deactivate (void)
 {
-       if (!currprefs.sound_auto)
-               return;
        gui_data.sndbuf_status = 3;
        gui_data.sndbuf = 0;
+       audio_work_to_do = 0;
        pause_sound_buffer ();
        clear_sound_buffers ();
        audio_event_reset ();
index 2d73639bfab6bf06bfbe73ceb79e06d6d59638c2..f693e3e20000cc67c9dc9d038aa4e11352ef1ea3 100644 (file)
@@ -38,6 +38,7 @@ struct blkdevstate
        int delayed;
        uae_sem_t sema;
        int sema_cnt;
+       int current_pos;
        int play_end_pos;
        uae_u8 play_qcode[SUBQ_SIZE];
        TCHAR newimagefile[256];
@@ -499,6 +500,7 @@ void device_func_reset (void)
                struct blkdevstate *st = &state[i];
                st->wasopen = 0;
                st->waspaused = false;
+               st->mediawaschanged = false;
                st->imagechangetime = 0;
                st->cdimagefileinuse = false;
                st->newimagefile[0] = 0;
@@ -1195,6 +1197,7 @@ static int scsiemudrv (int unitnum, uae_u8 *cmd)
 
 static int scsi_read_cd (int unitnum, uae_u8 *cmd, uae_u8 *data, struct device_info *di)
 {
+       struct blkdevstate *st = &state[unitnum];
        int msf = cmd[0] == 0xb9;
        int start = msf ? msf2lsn (rl (cmd + 2) & 0x00ffffff) : rl (cmd + 2);
        int len = rl (cmd + 5) & 0x00ffffff;
@@ -1207,21 +1210,26 @@ static int scsi_read_cd (int unitnum, uae_u8 *cmd, uae_u8 *data, struct device_i
        int subs = cmd[10] & 7;
        if (len == 0)
                return 0;
-       return sys_command_cd_rawread (unitnum, data, start, len, 0, (cmd[1] >> 2) & 7, cmd[9], subs);
+       int v = sys_command_cd_rawread (unitnum, data, start, len, 0, (cmd[1] >> 2) & 7, cmd[9], subs);
+       if (v > 0)
+               st->current_pos = start + len;
+       return v;
 }
 
 static int scsi_read_cd_data (int unitnum, uae_u8 *scsi_data, uae_u32 offset, uae_u32 len, struct device_info *di, int *scsi_len)
 {
+       struct blkdevstate *st = &state[unitnum];
        if (len == 0) {
                *scsi_len = 0;
                return 0;
        } else {
                if (len * di->bytespersector > SCSI_DATA_BUFFER_SIZE)
                        return -3;
-               if (offset >= di->sectorspertrack)
+               if (offset >= di->sectorspertrack * di->cylinders * di->trackspercylinder)
                        return -1;
                int v = cmd_readx (unitnum, scsi_data, offset, len) * di->bytespersector;
                if (v > 0) {
+                       st->current_pos = offset + len;
                        *scsi_len = v;
                        return 0;
                }
@@ -1270,6 +1278,8 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
                s[2] = 6; /* UNIT ATTENTION */
                s[12] = 0x28; /* MEDIUM MAY HAVE CHANGED */
                ls = 0x12;
+               if (cmd == 0x00)
+                       st->mediawaschanged = false;
                goto end;
        }
 
@@ -1283,6 +1293,15 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len,
        case 0x1e: /* PREVENT/ALLOW MEDIUM REMOVAL */
                scsi_len = 0;
                break;
+       case 0xbd: /* MECHANISM STATUS */
+               len = (cmdbuf[8] << 8) | cmdbuf[9];
+               if (len > 8)
+                       len = 8;
+               scsi_len = len;
+               r[2] = st->current_pos >> 16;
+               r[3] = st->current_pos >>  8;
+               r[4] = st->current_pos >>  0;
+               break;
        case 0x12: /* INQUIRY */
        {
                if ((cmdbuf[1] & 1) || cmdbuf[2] != 0)
index 339a63f600e743503cad76f4b51f40c562be9e52..4b292db90860c4eba92c5672cdaa2c7b83070494 100644 (file)
@@ -76,196 +76,243 @@ int main(int argc, char **argv)
 #endif
     getnextch();
     while (nextch != EOF) {
-       int cpulevel, uncpulevel, plevel, sduse;
-       int i;
-
-       char patbits[16];
-       char opcstr[256];
-       int bitpos[16];
-       int flagset[5], flaguse[5];
-
-       unsigned int bitmask,bitpattern;
-       int n_variable;
-
-       n_variable = 0;
-       bitmask = bitpattern = 0;
-       memset (bitpos, 0, sizeof(bitpos));
-       for(i=0; i<16; i++) {
-           int currbit;
-           bitmask <<= 1;
-           bitpattern <<= 1;
-
-           switch (nextch) {
-            case '0': currbit = bit0; bitmask |= 1; break;
-            case '1': currbit = bit1; bitmask |= 1; bitpattern |= 1; break;
-            case 'c': currbit = bitc; break;
-            case 'C': currbit = bitC; break;
-            case 'f': currbit = bitf; break;
-            case 'i': currbit = biti; break;
-            case 'I': currbit = bitI; break;
-            case 'j': currbit = bitj; break;
-            case 'J': currbit = bitJ; break;
-            case 'k': currbit = bitk; break;
-            case 'K': currbit = bitK; break;
-            case 's': currbit = bits; break;
-            case 'S': currbit = bitS; break;
-            case 'd': currbit = bitd; break;
-            case 'D': currbit = bitD; break;
-            case 'r': currbit = bitr; break;
-            case 'R': currbit = bitR; break;
-            case 'z': currbit = bitz; break;
-            case 'p': currbit = bitp; break;
-            default: abort();
-           }
-           if (!(bitmask & 1)) {
-               bitpos[n_variable] = currbit;
-               n_variable++;
-           }
-
-           if (nextch == '0' || nextch == '1')
-               bitmask |= 1;
-           if (nextch == '1')
-               bitpattern |= 1;
-           patbits[i] = nextch;
-           getnextch();
-       }
-
-       while (isspace(nextch) || nextch == ':') /* Get CPU level, unimplemented level, and privilege level */
-           getnextch();
-
-       switch (nextch) {
-        case '0': cpulevel = 0; break;
-        case '1': cpulevel = 1; break;
-        case '2': cpulevel = 2; break;
-        case '3': cpulevel = 3; break;
-        case '4': cpulevel = 4; break;
-        case '5': cpulevel = 5; break;
-        case '6': cpulevel = 6; break;
-        case '7': cpulevel = 7; break;
-        default: abort();
-       }
-       getnextch();
-
-       switch (nextch) {
-        case '0': uncpulevel = 0; break;
-        case '1': uncpulevel = 1; break;
-        case '2': uncpulevel = 2; break;
-        case '3': uncpulevel = 3; break;
-        case '4': uncpulevel = 4; break;
-        case '5': uncpulevel = 5; break;
-        case '6': uncpulevel = 6; break;
-        case '7': uncpulevel = 7; break;
-        default: abort();
-       }
-       getnextch();
-
-       switch (nextch) {
-        case '0': plevel = 0; break;
-        case '1': plevel = 1; break;
-        case '2': plevel = 2; break;
-        case '3': plevel = 3; break;
-        default: abort();
-       }
-       getnextch();
-
-       while (isspace(nextch))                   /* Get flag set information */
-           getnextch();
-
-       if (nextch != ':')
-           abort();
-
-       for(i = 0; i < 5; i++) {
-           getnextch();
-           switch(nextch){
-            case '-': flagset[i] = fa_unset; break;
-            case '/': flagset[i] = fa_isjmp; break;
-            case '+': flagset[i] = fa_isbranch; break;
-            case '0': flagset[i] = fa_zero; break;
-            case '1': flagset[i] = fa_one; break;
-            case 'x': flagset[i] = fa_dontcare; break;
-            case '?': flagset[i] = fa_unknown; break;
-            default: flagset[i] = fa_set; break;
-           }
-       }
-
-       getnextch();
-       while (isspace(nextch))
-           getnextch();
-
-       if (nextch != ':')                        /* Get flag used information */
-           abort();
-
-       for(i = 0; i < 5; i++) {
-           getnextch();
-           switch(nextch){
-            case '-': flaguse[i] = fu_unused; break;
-            case '/': flaguse[i] = fu_isjmp; break;
-            case '+': flaguse[i] = fu_maybecc; break;
-            case '?': flaguse[i] = fu_unknown; break;
-            default: flaguse[i] = fu_used; break;
-           }
-       }
-
-       getnextch();
-       while (isspace(nextch))
-           getnextch();
-
-       if (nextch != ':')                        /* Get source/dest usage information */
-           abort();
-
-       getnextch();
-       sduse = nextchtohex() << 4;
-       getnextch();
-       sduse |= nextchtohex();
-
-       getnextch();
-       while (isspace(nextch))
-           getnextch();
-
-       if (nextch != ':')
-           abort();
-
-       fgets(opcstr, 250, tablef);
-       getnextch();
-       {
-           int j;
-           /* Remove superfluous spaces from the string */
-           char *opstrp = opcstr, *osendp;
-           char tmp[100], *p;
-           int slen = 0;
-
-           while (isspace(*opstrp))
+               int cpulevel, uncpulevel, plevel, sduse;
+               int i;
+
+               char patbits[16];
+               char opcstr[256];
+               int bitpos[16];
+               int flagset[5], flaguse[5];
+
+               unsigned int bitmask,bitpattern;
+               int n_variable;
+
+               int head = 0, tail = 0, clocks = 0, fetchmode = 0;
+
+               n_variable = 0;
+               bitmask = bitpattern = 0;
+               memset (bitpos, 0, sizeof(bitpos));
+               for(i=0; i<16; i++) {
+                       int currbit;
+                       bitmask <<= 1;
+                       bitpattern <<= 1;
+
+                       switch (nextch) {
+                        case '0': currbit = bit0; bitmask |= 1; break;
+                        case '1': currbit = bit1; bitmask |= 1; bitpattern |= 1; break;
+                        case 'c': currbit = bitc; break;
+                        case 'C': currbit = bitC; break;
+                        case 'f': currbit = bitf; break;
+                        case 'i': currbit = biti; break;
+                        case 'I': currbit = bitI; break;
+                        case 'j': currbit = bitj; break;
+                        case 'J': currbit = bitJ; break;
+                        case 'k': currbit = bitk; break;
+                        case 'K': currbit = bitK; break;
+                        case 's': currbit = bits; break;
+                        case 'S': currbit = bitS; break;
+                        case 'd': currbit = bitd; break;
+                        case 'D': currbit = bitD; break;
+                        case 'r': currbit = bitr; break;
+                        case 'R': currbit = bitR; break;
+                        case 'z': currbit = bitz; break;
+                        case 'p': currbit = bitp; break;
+                        default: abort();
+                       }
+                       if (!(bitmask & 1)) {
+                       bitpos[n_variable] = currbit;
+                       n_variable++;
+                       }
+
+                       if (nextch == '0' || nextch == '1')
+                       bitmask |= 1;
+                       if (nextch == '1')
+                       bitpattern |= 1;
+                       patbits[i] = nextch;
+                       getnextch();
+               }
+
+               while (isspace(nextch) || nextch == ':') /* Get CPU level, unimplemented level, and privilege level */
+                       getnextch();
+
+               switch (nextch) {
+                case '0': cpulevel = 0; break;
+                case '1': cpulevel = 1; break;
+                case '2': cpulevel = 2; break;
+                case '3': cpulevel = 3; break;
+                case '4': cpulevel = 4; break;
+                case '5': cpulevel = 5; break;
+                case '6': cpulevel = 6; break;
+                case '7': cpulevel = 7; break;
+                default: abort();
+               }
+               getnextch();
+
+               switch (nextch) {
+                case '0': uncpulevel = 0; break;
+                case '1': uncpulevel = 1; break;
+                case '2': uncpulevel = 2; break;
+                case '3': uncpulevel = 3; break;
+                case '4': uncpulevel = 4; break;
+                case '5': uncpulevel = 5; break;
+                case '6': uncpulevel = 6; break;
+                case '7': uncpulevel = 7; break;
+                default: abort();
+               }
+               getnextch();
+
+               switch (nextch) {
+                case '0': plevel = 0; break;
+                case '1': plevel = 1; break;
+                case '2': plevel = 2; break;
+                case '3': plevel = 3; break;
+                default: abort();
+               }
+               getnextch();
+
+               while (isspace(nextch))                   /* Get flag set information */
+                       getnextch();
+
+               if (nextch != ':')
+                       abort();
+
+               for(i = 0; i < 5; i++) {
+                       getnextch();
+                       switch(nextch){
+                        case '-': flagset[i] = fa_unset; break;
+                        case '/': flagset[i] = fa_isjmp; break;
+                        case '+': flagset[i] = fa_isbranch; break;
+                        case '0': flagset[i] = fa_zero; break;
+                        case '1': flagset[i] = fa_one; break;
+                        case 'x': flagset[i] = fa_dontcare; break;
+                        case '?': flagset[i] = fa_unknown; break;
+                        default: flagset[i] = fa_set; break;
+                       }
+               }
+
+               getnextch();
+               while (isspace(nextch))
+                       getnextch();
+
+               if (nextch != ':')                        /* Get flag used information */
+                       abort();
+
+               for(i = 0; i < 5; i++) {
+                       getnextch();
+                       switch(nextch){
+                        case '-': flaguse[i] = fu_unused; break;
+                        case '/': flaguse[i] = fu_isjmp; break;
+                        case '+': flaguse[i] = fu_maybecc; break;
+                        case '?': flaguse[i] = fu_unknown; break;
+                        default: flaguse[i] = fu_used; break;
+                       }
+               }
+
+               getnextch();
+               while (isspace(nextch))
+                       getnextch();
+
+               if (nextch != ':')                        /* Get source/dest usage information */
+                       abort();
+
+               getnextch();
+               sduse = nextchtohex() << 4;
+               getnextch();
+               sduse |= nextchtohex();
+
+               getnextch();
+               while (isspace(nextch))
+                       getnextch();
+
+               if (nextch != ':')
+                       abort();
+
+               fgets(opcstr, 250, tablef);
+               getnextch();
+
+               if (nextch == '-') {
+                       char c, fm[20];
+                       getnextch();
+                       while (isspace(nextch))
+                               getnextch();
+                       for (;;) {
+                               if (nextch < '0' || nextch > '9')
+                                       break;
+                               head *= 10;
+                               head += nextch - '0';
+                               nextch = fgetc (tablef);
+                       }
+                       while (isspace(nextch))
+                               getnextch();
+                       for (;;) {
+                               if (nextch < '0' || nextch > '9')
+                                       break;
+                               tail *= 10;
+                               tail += nextch - '0';
+                               nextch = fgetc (tablef);
+                       }
+                       while (isspace(nextch))
+                               getnextch();
+                       for (;;) {
+                               if (nextch < '0' || nextch > '9')
+                                       break;
+                               clocks *= 10;
+                               clocks += nextch - '0';
+                               nextch = fgetc (tablef);
+                       }
+                       if (nextch == ' ') {
+                               fgets(fm, sizeof fm, tablef);
+                               if (!strnicmp(fm, "fea", 3))
+                                       fetchmode = 1;
+                               if (!strnicmp(fm, "cea", 3))
+                                       fetchmode = 2;
+                               if (!strnicmp(fm, "fiea", 4))
+                                       fetchmode = 3;
+                               if (!strnicmp(fm, "ciea", 4))
+                                       fetchmode = 4;
+                               if (!strnicmp(fm, "jea", 3))
+                                       fetchmode = 5;
+                       }
+                       getnextch();
+               }
+
+               int j;
+               /* Remove superfluous spaces from the string */
+               char *opstrp = opcstr, *osendp;
+               char tmp[100], *p;
+               int slen = 0;
+
+               while (isspace(*opstrp))
                opstrp++;
 
-           osendp = opstrp;
-           while (*osendp) {
+               osendp = opstrp;
+               while (*osendp) {
                if (!isspace (*osendp))
-                   slen = osendp - opstrp + 1;
-               osendp++;
-           }
-           opstrp[slen] = 0;
-
-           if (no_insns > 0)
-               printf(",\n");
-           no_insns++;
-           strcpy (tmp, opstrp);
-           strcat (tmp, " ");
-           p = tmp;
-           while (!isspace(*p++));
-           *p = 0;
-           printf("/* %s */\n", tmp);
-           printf("{0x%04X,%2d,{", bitpattern, n_variable);
-           for (j = 0; j < 16; j++) {
-               printf("%2d", bitpos[j]);
-               if (j < 15)
-                   printf(",");
-           }
-           printf ("},0x%04X,%d,%d,%d,{", bitmask, cpulevel, uncpulevel, plevel);
-           for(i = 0; i < 5; i++) {
-               printf("{%d,%d}%s", flaguse[i], flagset[i], i == 4 ? "" : ",");
-           }
-           printf("},%2d,_T(\"%s\")}", sduse, opstrp);
-       }
+                       slen = osendp - opstrp + 1;
+                       osendp++;
+               }
+               opstrp[slen] = 0;
+
+               if (no_insns > 0)
+                       printf(",\n");
+               no_insns++;
+               strcpy (tmp, opstrp);
+               strcat (tmp, " ");
+               p = tmp;
+               while (!isspace(*p++));
+               *p = 0;
+               printf("/* %s */\n", tmp);
+               printf("{0x%04X,%2d,{", bitpattern, n_variable);
+               for (j = 0; j < 16; j++) {
+                       printf("%2d", bitpos[j]);
+                       if (j < 15)
+                               printf(",");
+               }
+               printf ("},0x%04X,%d,%d,%d,{", bitmask, cpulevel, uncpulevel, plevel);
+               for(i = 0; i < 5; i++) {
+                       printf("{%d,%d}%s", flaguse[i], flagset[i], i == 4 ? "" : ",");
+               }
+               printf("},%2d,_T(\"%s\"),%2d,%2d,%2d,%2d}", sduse, opstrp, head, tail, clocks, fetchmode);
     }
     printf("};\nint n_defs68k = %d;\n", no_insns);
     return 0;
index bbcae93175b6a9d0b6dba5fc5e85876a47de6a51..47e45f5fb0fae89ffd6b8907f9e06f886006c831 100644 (file)
@@ -38,6 +38,7 @@
 
 static int config_newfilesystem;
 static struct strlist *temp_lines;
+static struct strlist *error_lines;
 static struct zfile *default_file, *configstore;
 static int uaeconfig;
 static int unicode_config = 0;
@@ -2612,7 +2613,7 @@ struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, s
        if (index < 0 && (ci->type == UAEDEV_DIR || ci->type == UAEDEV_HDF) && ci->devname && _tcslen (ci->devname) > 0) {
                for (i = 0; i < p->mountitems; i++) {
                        if (p->mountconfig[i].ci.devname && !_tcscmp (p->mountconfig[i].ci.devname, ci->devname))
-                               return 0;
+                               return NULL;
                }
        }
        if (ci->type == UAEDEV_CD) {
@@ -2631,7 +2632,7 @@ struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, s
                                        if (p->mountconfig[i].ci.controller == ctrl) {
                                                ctrl++;
                                                if (ctrl == HD_CONTROLLER_IDE3 + 1 || ctrl == HD_CONTROLLER_SCSI6 + 1)
-                                                       return 0;
+                                                       return NULL;
                                        }
                                }
                                if (i == p->mountitems) {
@@ -2643,7 +2644,7 @@ struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, s
                if (ci->type == UAEDEV_CD) {
                        for (i = 0; i < p->mountitems; i++) {
                                if (p->mountconfig[i].ci.type == ci->type)
-                                       return 0;
+                                       return NULL;
                        }
                }
                uci = getuci (p);
@@ -2653,7 +2654,7 @@ struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int index, s
                uci = &p->mountconfig[index];
        }
        if (!uci)
-               return 0;
+               return NULL;
 
        memcpy (&uci->ci, ci, sizeof (struct uaedev_config_info));
        validatedevicename (uci->ci.devname);
@@ -5862,3 +5863,66 @@ void config_check_vsync (void)
        }
 }
 
+bool is_error_log (void)
+{
+       return error_lines != NULL;
+}
+TCHAR *get_error_log (void)
+{
+       strlist *sl;
+       int len = 0;
+       for (sl = error_lines; sl; sl = sl->next) {
+               len += _tcslen (sl->option) + 1;
+       }
+       if (!len)
+               return NULL;
+       TCHAR *s = xcalloc (TCHAR, len + 1);
+       for (sl = error_lines; sl; sl = sl->next) {
+               _tcscat (s, sl->option);
+               _tcscat (s, _T("\n"));
+       }
+       return s;
+}
+void error_log (const TCHAR *format, ...)
+{
+       TCHAR buffer[256], *bufp;
+       int bufsize = 256;
+       va_list parms;
+
+       if (format == NULL) {
+               struct strlist **ps = &error_lines;
+               while (*ps) {
+                       struct strlist *s = *ps;
+                       *ps = s->next;
+                       xfree (s->value);
+                       xfree (s->option);
+                       xfree (s);
+               }
+               return;
+       }
+
+       va_start (parms, format);
+       bufp = buffer;
+       for (;;) {
+               int count = _vsntprintf (bufp, bufsize - 1, format, parms);
+               if (count < 0) {
+                       bufsize *= 10;
+                       if (bufp != buffer)
+                               xfree (bufp);
+                       bufp = xmalloc (TCHAR, bufsize);
+                       continue;
+               }
+               break;
+       }
+       bufp[bufsize - 1] = 0;
+       write_log (_T("%s\n"), bufp);
+       va_end (parms);
+
+       strlist *u = xcalloc (struct strlist, 1);
+       u->option = my_strdup (bufp);
+       u->next = error_lines;
+       error_lines = u;
+
+       if (bufp != buffer)
+               xfree (bufp);
+}
index 775a67a8ff71342c441cee2826cd8207f2a80ce3..9c8d5d68097cd53cf2c764104e182a8f1c2d6840 100644 (file)
@@ -8399,7 +8399,7 @@ uae_u32 wait_cpu_cycle_read_ce020 (uaecptr addr, int mode)
        if (debug_dma)
                dr->dat = v;
 #endif
-       x_do_cycles_post (CYCLE_UNIT, v);
+       //x_do_cycles_post (CYCLE_UNIT / 2, v);
 
        return v;
 }
@@ -8464,7 +8464,7 @@ void wait_cpu_cycle_write_ce020 (uaecptr addr, int mode, uae_u32 v)
        else if (mode == 0)
                put_byte (addr, v);
 
-       x_do_cycles_post (CYCLE_UNIT, v);
+       //x_do_cycles_post (CYCLE_UNIT / 2, v);
 }
 
 void do_cycles_ce (unsigned long cycles)
index 39ca7c44d02349d8f96c7e38c8769af7e560abbc..4cff87ddfe96b76e1dc419db3dd95d8c9e3b3151 100644 (file)
--- a/debug.cpp
+++ b/debug.cpp
@@ -366,19 +366,19 @@ static int readregx (TCHAR **c, uae_u32 *valp)
                memmove (tmp, tmp + 1, sizeof (tmp) - sizeof (TCHAR));
                extra = 1;
        }
-       if (!_tcscmp (tmp, _T("USP"))) {
+       if (!_tcsncmp (tmp, _T("USP"), 3)) {
                addr = regs.usp;
                (*c) += 3;
-       } else if (!_tcscmp (tmp, _T("VBR"))) {
+       } else if (!_tcsncmp (tmp, _T("VBR"), 3)) {
                addr = regs.vbr;
                (*c) += 3;
-       } else if (!_tcscmp (tmp, _T("MSP"))) {
+       } else if (!_tcsncmp (tmp, _T("MSP"), 3)) {
                addr = regs.msp;
                (*c) += 3;
-       } else if (!_tcscmp (tmp, _T("ISP"))) {
+       } else if (!_tcsncmp (tmp, _T("ISP"), 3)) {
                addr = regs.isp;
                (*c) += 3;
-       } else if (!_tcscmp (tmp, _T("PC"))) {
+       } else if (!_tcsncmp (tmp, _T("PC"), 2)) {
                addr = regs.pc;
                (*c) += 2;
        } else if (tmp[0] == 'A' || tmp[0] == 'D') {
@@ -2516,8 +2516,10 @@ int debug_bankchange (int mode)
                        return -2;
                return v;
        }
-       if (mode >= 0)
+       if (mode >= 0) {
                initialize_memwatch (mode);
+               memwatch_setup ();
+       }
        return -1;
 }
 
@@ -3820,7 +3822,9 @@ static BOOL debug_line (TCHAR *input)
                case 'e': dump_custom_regs (tolower(*inptr) == 'a'); break;
                case 'r':
                        {
-                               if (more_params(&inptr))
+                               if (*inptr == 'c')
+                                       m68k_dumpcache ();
+                               else if (more_params(&inptr))
                                        m68k_modify (&inptr);
                                else
                                        m68k_dumpstate (&nextpc);
index 6696b0442129a11a423d0346e4ea8cbab1870820..b2880e7d2eb6441da0eea2155d0e0cecd37b788e 100644 (file)
--- a/disk.cpp
+++ b/disk.cpp
@@ -1884,7 +1884,7 @@ static int decode_buffer (uae_u16 *mbuf, int cyl, int drvsec, int ddhd, int file
                        continue;
                }
                if (((id & 0x00ff0000) >> 16) != cyl * 2 + side) {
-                       write_log (_T("Disk decode: mismatched track (%d <> %d) on sector %d header\n"), (id & 0x00ff0000) >> 16, cyl * 2 + side, trackoffs);
+                       write_log (_T("Disk decode: mismatched track (%d <> %d) on sector %d header (%08X)\n"), (id & 0x00ff0000) >> 16, cyl * 2 + side, trackoffs, id);
                        if (filetype == ADF_EXT2)
                                return 3;
                        continue;
@@ -2349,8 +2349,6 @@ bool disk_creatediskfile (const TCHAR *name, int type, drive_type adftype, const
        zfile_fclose (f);
        if (copyfrom)
                zfile_fseek (copyfrom, pos, SEEK_SET);
-       if (f)
-               DISK_history_add (name, -1, HISTORY_FLOPPY, TRUE);
        return ok;
 }
 
index af5c11cf2ffad9f53eb04f756c4b20215fd22dec..e4d4ed3fc984d6189142f27db755fbf5e1c86b3e 100644 (file)
@@ -515,7 +515,7 @@ static int set_filesys_volume (const TCHAR *rootdir, int *flags, bool *readonly,
                struct zvolume *zv;
                zv = zfile_fopen_archive (rootdir);
                if (!zv) {
-                       write_log (_T("'%s' is not a supported archive file\n"), rootdir);
+                       error_log (_T("'%s' is not a supported archive file."), rootdir);
                        return -1;
                }
                *zvp = zv;
@@ -525,11 +525,11 @@ static int set_filesys_volume (const TCHAR *rootdir, int *flags, bool *readonly,
                *flags = my_getvolumeinfo (rootdir);
                if (*flags < 0) {
                        if (rootdir && rootdir[0])
-                               write_log (_T("directory '%s' not found, mounting as empty drive\n"), rootdir);
+                               error_log (_T("directory '%s' not found, mounting as empty drive."), rootdir);
                        *emptydrive = 1;
                        *flags = 0;
                } else if ((*flags) & MYVOLUMEINFO_READONLY) {
-                       write_log (_T("'%s' set to read-only\n"), rootdir);
+                       error_log (_T("'%s' set to read-only."), rootdir);
                        *readonly = 1;
                }
        }
@@ -571,7 +571,7 @@ static int set_filesys_unit_1 (int nr, struct uaedev_config_info *ci)
                                break;
                }
                if (nr == MAX_FILESYSTEM_UNITS) {
-                       write_log (_T("No slot allocated for this unit\n"));
+                       error_log (_T("No slot allocated for this unit"));
                        return -1;
                }
        }
@@ -593,7 +593,7 @@ static int set_filesys_unit_1 (int nr, struct uaedev_config_info *ci)
                if (nr == i || !mountinfo.ui[i].open || mountinfo.ui[i].rootdir == NULL || is_hardfile (i) == FILESYS_CD)
                        continue;
                if (_tcslen (c.rootdir) > 0 && !_tcsicmp (mountinfo.ui[i].rootdir, c.rootdir)) {
-                       write_log (_T("directory/hardfile '%s' already added\n"), c.rootdir);
+                       error_log (_T("directory/hardfile '%s' already added."), c.rootdir);
                        return -1;
                }
        }
@@ -622,9 +622,11 @@ static int set_filesys_unit_1 (int nr, struct uaedev_config_info *ci)
                ui->volname = 0;
                if (ui->hf.ci.rootdir[0]) {
                        if (!hdf_open (&ui->hf) && !c.readonly) {
-                               write_log (_T("Attempting to open in read-only mode\n"));
+                               write_log (_T("Attempting to open '%s' in read-only mode.\n"), ui->hf.ci.rootdir);
                                ui->hf.ci.readonly = c.readonly = true;
-                               hdf_open (&ui->hf);
+                               if (hdf_open (&ui->hf)) {
+                                       error_log (_T("'%s' opened in read-only mode.\n"), ui->hf.ci.rootdir);
+                               }
                        }
                } else {
                        // empty drive?
@@ -632,22 +634,22 @@ static int set_filesys_unit_1 (int nr, struct uaedev_config_info *ci)
                }
                if (!ui->hf.drive_empty) {
                        if (ui->hf.handle_valid == 0) {
-                               write_log (_T("Hardfile %s not found\n"), ui->hf.device_name);
+                               error_log (_T("Hardfile '%s' not found."), ui->hf.ci.rootdir);
                                goto err;
                        }
                        if (ui->hf.ci.blocksize > ui->hf.virtsize || ui->hf.virtsize == 0) {
-                               write_log (_T("Hardfile %s too small\n"), ui->hf.device_name);
+                               error_log (_T("Hardfile '%s' too small."), ui->hf.ci.rootdir);
                                goto err;
                        }
                }
                if ((ui->hf.ci.blocksize & (ui->hf.ci.blocksize - 1)) != 0 || ui->hf.ci.blocksize == 0) {
-                       write_log (_T("Hardfile %s bad blocksize\n"), ui->hf.device_name);
+                       error_log (_T("Hardfile '%s' bad blocksize %d."), ui->hf.ci.rootdir, ui->hf.ci.blocksize);
                        goto err;
                }
                if ((ui->hf.ci.sectors || ui->hf.ci.surfaces || ui->hf.ci.reserved) &&
                        (ui->hf.ci.sectors < 1 || ui->hf.ci.surfaces < 1 || ui->hf.ci.surfaces > 1023 ||
                        ui->hf.ci.reserved < 0 || ui->hf.ci.reserved > 1023) != 0) {
-                               write_log (_T("Hardfile %s bad hardfile geometry\n"), ui->hf.device_name);
+                               error_log (_T("Hardfile '%s' bad hardfile geometry."), ui->hf.ci.rootdir);
                                goto err;
                }
                if (!ui->hf.ci.highcyl) {
index 1be9e28d574aafb0c0ba0ec60d40c1ccf17f256a..d1be1a2f52790dc19526c2cd398a707c227d1a5e 100644 (file)
--- a/gayle.cpp
+++ b/gayle.cpp
@@ -446,6 +446,16 @@ static void ide_fast_interrupt (struct ide_hdf *ide)
        ide->irq_delay = 1;
 }
 
+#if 0
+uae_u16 isideint(void)
+{
+       if (!(gayle_irq & 0x80))
+               return 0;
+       gayle_irq &= ~0x80;
+       return 0x8000;
+}
+#endif
+
 static void ide_interrupt_do (struct ide_hdf *ide)
 {
        uae_u8 os = ide->regs.ide_status;
@@ -843,9 +853,11 @@ static void do_packet_command (struct ide_hdf *ide)
                ide->regs.ide_status = 0;
                if (ide->scsi->status) {
                        // error
-                       ide->regs.ide_status = ATAPI_STATUS_CHK;
-                       ide->regs.ide_error = ide->scsi->status << 4;
+                       ide->regs.ide_error = (ide->scsi->sense[2] << 4) | 4;
                        atapi_data_done (ide);
+                       ide->regs.ide_status |= ATAPI_STATUS_CHK;
+                       atapi_set_size (ide);
+                       return;
                } else if (ide->scsi->data_len) {
                        // data in
                        memcpy (ide->secbuf, ide->scsi->buffer, ide->scsi->data_len);
index 2d631e1a93d82f1067a3c499f260a0c226ba37e3..8994d0ecdf173a84afaf3f98f3c31801f436be6b 100644 (file)
@@ -36,6 +36,7 @@ static int using_prefetch_020, using_ce020;
 static int using_exception_3;
 static int using_ce;
 static int using_tracer;
+static int using_waitstates;
 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;
@@ -92,6 +93,17 @@ static char *srcld, *dstld;
 static char *srcwd, *dstwd;
 static char *do_cycles, *disp000, *disp020;
 
+static void term (void)
+{
+       printf("Abort!\n");
+       abort ();
+}
+static void term (const char *err)
+{
+       printf ("%s\n", err);
+       term ();
+}
+
 static void read_counts (void)
 {
        FILE *file;
@@ -125,7 +137,7 @@ static void read_counts (void)
                }
        }
        if (nr != nr_cpuop_funcs)
-               abort ();
+               term ();
 }
 
 static char endlabelstr[80];
@@ -152,12 +164,35 @@ static void cpulimit (void)
 
 static void returncycles (char *s, int cycles)
 {
-       if (using_ce)
-               return;
-       if (using_ce020)
+       if (using_ce || using_ce020) {
                printf ("%sreturn;\n", s);
-       else
-               printf ("%sreturn %d * CYCLE_UNIT / 2;\n", s, cycles);
+               return;
+       }
+       printf ("%sreturn %d * CYCLE_UNIT / 2;\n", s, cycles);
+}
+
+static void addcycles_ce020 (char *name, int head, int tail, int cycles)
+{
+       if (!using_ce020)
+               return;
+       if (!head && !tail && !cycles)
+               return;
+       printf ("\t/* %d,%d,%d %s */\n", head, tail, cycles, name);
+}
+static void addcycles_ce020 (char *name, int head, int tail, int cycles, int ophead)
+{
+       if (!using_ce020)
+               return;
+       if (!head && !tail && !cycles && !ophead)
+               return;
+       count_cycles += cycles;
+       if (!ophead) {
+               addcycles_ce020 (name, head, tail, cycles);
+       } else if (ophead > 0) {
+               printf ("\t/* %d+%d=%d,%d,%d %s */\n", head, ophead, head + ophead, tail, cycles, name);
+       } else {
+               printf ("\t/* %d-%d=%d,%d,%d %s */\n", head, -ophead, head + ophead, tail, cycles, name);
+       }
 }
 
 static void addcycles_ce020 (int cycles)
@@ -165,9 +200,10 @@ static void addcycles_ce020 (int cycles)
        if (!using_ce020)
                return;
        if (cycles > 0)
-               printf ("\tusecycles_ce020 (%d * cpucycleunit);\n", cycles);
+               printf ("\t%s (%d);\n", do_cycles, cycles);
        count_cycles += cycles;
 }
+
 static void addcycles000 (int cycles)
 {
        if (!using_ce)
@@ -229,7 +265,7 @@ static int bit_size (int size)
        case sz_byte: return 8;
        case sz_word: return 16;
        case sz_long: return 32;
-       default: abort ();
+       default: term ();
        }
        return 0;
 }
@@ -240,7 +276,7 @@ static const char *bit_mask (int size)
        case sz_byte: return "0xff";
        case sz_word: return "0xffff";
        case sz_long: return "0xffffffff";
-       default: abort ();
+       default: term ();
        }
        return 0;
 }
@@ -419,7 +455,7 @@ static void fill_prefetch_full (void)
        } else if (using_prefetch_020) {
                did_prefetch = 1;
                if (cpu_level >= 3)
-                       printf ("\tfill_prefetch_0x0 ();\n");
+                       printf ("\tfill_prefetch_030 ();\n");
                else if (cpu_level == 2)
                        printf ("\tfill_prefetch_020 ();\n");
        }
@@ -487,8 +523,6 @@ static void fill_prefetch_finish (void)
                fill_prefetch_1 (m68k_pc_offset);
        }
        if (using_prefetch_020) {
-               if (count_cycles == 0)
-                       addcycles_ce020 (2);
                did_prefetch = 1;
        }
 }
@@ -581,6 +615,318 @@ static void syncmovepc (int getv, int flags)
 #endif
 }
 
+static int tail_ce020;
+
+static void addopcycles_ce20 (int h, int t, int c, int subhead)
+{
+       int largest = tail_ce020 > h ? tail_ce020: h;
+       if (largest) {
+               if (tail_ce020)
+                       printf ("\tregs.ce020_tail = get_cycles () - regs.ce020_tail;\n");
+               else
+                       printf ("\tregs.ce020_tail = 0;\n");
+               printf ("\tif (regs.ce020_tail < %d * cpucycleunit)\n", largest);
+               printf ("\t\tx_do_cycles (%d * cpucycleunit - regs.ce020_tail);\n", largest);
+       } else {
+               printf ("\t/* ea tail == op head */\n");
+       }
+       c = c - h - t;
+       // c = internal cycles needed after head cycles and before tail cycles. Not total cycles.
+       addcycles_ce020 ("op", h, t, c, -subhead);
+       //printf ("\tregs.irc = get_word_ce020_prefetch (%d);\n", m68k_pc_offset);
+       if (c > 0) {
+               printf ("\t%s (%d);\n", do_cycles, c);
+               count_cycles += c;
+       }
+       printf ("\tregs.ce020_tail = 0;\n");
+}
+
+static void addop_ce020 (instr *curi, int subhead)
+{
+       if (!using_ce020)
+               return;
+       int h = curi->head;
+       int t = curi->tail;
+       int c = curi->clocks;
+#if 0
+       if ((((curi->sduse & 2) && !isreg (curi->smode)) || (((curi->sduse >> 4) & 2) && !isreg (curi->dmode))) && using_waitstates) {
+               t += using_waitstates;
+               c += using_waitstates;
+       }
+#endif
+       addopcycles_ce20 (h, t, c, -subhead);
+}
+
+static void addcycles_ea_ce020 (char *ea, int h, int t, int c, int oph)
+{
+       if (!h && !h && !c && !oph)
+               return;
+
+       c = c - h - t;
+       if (!oph) {
+               printf ("\t/* %d,%d,%d %s */\n", h, t, c, ea);
+       } else {
+               if (oph && t)
+                       term ("Both op head and tail can't be non-zero");
+               if (oph > 0) {
+                       printf ("\t/* %d+%d=%d,%d,%d %s */\n", h, oph, h + oph, t, c, ea);
+                       h += oph;
+               } else {
+                       printf ("\t/* %d-%d=%d,%d,%d %s */\n", h, -oph, h + oph, t, c, ea);
+                       h += oph;
+               }
+       }
+       if (c > 0) {
+               printf ("\t%s (%d);\n", do_cycles, c);
+               count_cycles += c;
+       }
+       tail_ce020 = t;
+       if (t > 0)
+               printf ("\tregs.ce020_tail = get_cycles ();\n", h, t, c);
+}
+static void addcycles_ea_ce020 (char *ea, int h, int t, int c)
+{
+       addcycles_ea_ce020 (ea, h, t, c, 0);
+}
+
+#define SETCE020(h2,t2,c2) { h = h2; t = t2; c = c2; }
+#define SETCE020H(h2,t2,c2) { h = h2; oph = curi ? curi->head : 0; t = t2; c = c2; }
+
+static int gence020cycles_fiea (instr *curi, wordsizes ssize, amodes dmode)
+{
+       bool l = ssize == sz_long;
+       int h = 0, t = 0, c = 0, oph = 0;
+       switch (dmode)
+       {
+       case Dreg:
+       case Areg:
+               if (!l)
+                       SETCE020H(2, 0, 2)
+               else
+                       SETCE020H(4, 0, 4)
+               break;
+       case Aind: // (An)
+               if (!l)
+                       SETCE020(1, 1, 3)
+               else
+                       SETCE020(1, 0, 4)
+               break;
+       case Aipi: // (An)+
+               if (!l)
+                       SETCE020(2, 1, 5)
+               else
+                       SETCE020(4, 1, 7)
+               break;
+       case Apdi: // -(An)
+               if (!l)
+                       SETCE020(2, 2, 4)
+               else
+                       SETCE020(2, 0, 4)
+               break;
+       case Ad8r: // (d8,An,Xn)
+       case PC8r: // (d8,PC,Xn)
+               if (!l)
+                       SETCE020(6, 2, 8)
+               else
+                       SETCE020(8, 2, 10)
+               break;
+       case Ad16: // (d16,An)
+       case PC16: // (d16,PC,Xn)
+               if (!l)
+                       SETCE020(2, 0, 4)
+               else
+                       SETCE020(4, 0, 6)
+               break;
+       case absw:
+               if (!l)
+                       SETCE020(4, 2, 6)
+               else
+                       SETCE020(6, 2, 8)
+               break;
+       case absl:
+               if (!l)
+                       SETCE020(3, 0, 6)
+               else
+                       SETCE020(5, 0, 8)
+               break;
+       }
+       addcycles_ea_ce020 ("fiea", h, t, c, oph);
+       return oph;
+}
+
+
+static int gence020cycles_ciea (instr *curi, wordsizes ssize, amodes dmode)
+{
+       int h = 0, t = 0, c = 0, oph = 0;
+       bool l = ssize == sz_long;
+       switch (dmode)
+       {
+       case Dreg:
+       case Areg:
+               if (!l)
+                       SETCE020H(2, 0, 2)
+               else
+                       SETCE020H(4, 0, 4)
+               break;
+       case Aind: // (An)
+               if (!l)
+                       SETCE020H(2, 0, 2)
+               else
+                       SETCE020H(4, 0, 4)
+               break;
+       case Aipi: // (An)+
+               if (!l)
+                       SETCE020(2, 0, 4)
+               else
+                       SETCE020(4, 0, 6)
+               break;
+       case Apdi: // -(An)
+               if (!l)
+                       SETCE020H(2, 0, 2)
+               else
+                       SETCE020H(4, 0, 4)
+               break;
+       case Ad8r: // (d8,An,Xn)
+       case PC8r: // (d8,PC,Xn)
+               if (!l)
+                       SETCE020H(6, 0, 6)
+               else
+                       SETCE020H(8, 0, 8)
+               break;
+       case Ad16: // (d16,An)
+       case PC16: // (d16,PC,Xn)
+               if (!l)
+                       SETCE020H(4, 0, 4)
+               else
+                       SETCE020H(6, 0, 6)
+               break;
+       case absw:
+               if (!l)
+                       SETCE020H(4, 0, 4)
+               else
+                       SETCE020H(6, 0, 6)
+               break;
+       case absl:
+               if (!l)
+                       SETCE020H(6, 0, 6)
+               else
+                       SETCE020H(8, 0, 8)
+               break;
+       }
+       addcycles_ea_ce020 ("ciea", h, t, c, oph);
+       return oph;
+}
+
+
+static int gence020cycles_fea (amodes mode)
+{
+       int h = 0, t = 0, c = 0, ws = 0;
+       switch (mode)
+       {
+       case Dreg:
+       case Areg:
+               SETCE020(0, 0, 0)
+               break;
+       case Aind: // (An)
+               ws++;
+               SETCE020(1, 1, 3)
+               break;
+       case Aipi: // (An)+
+               ws++;
+               SETCE020(0, 1, 3)
+               break;
+       case Apdi: // -(An)
+               ws++;
+               SETCE020(2, 2, 4)
+               break;
+       case Ad8r: // (d8,An,Xn)
+       case PC8r: // (d8,PC,Xn)
+               ws++;
+               SETCE020(4, 2, 6)
+               break;
+       case Ad16: // (d16,An)
+       case PC16: // (d16,PC,Xn)
+               ws++;
+               SETCE020(2, 2, 4)
+               break;
+       case absw:
+               ws++;
+               SETCE020(2, 2, 4)
+               break;
+       case absl:
+               ws++;
+               SETCE020(1, 0, 4)
+               break;
+       }
+#if 0
+       if (using_waitstates) {
+               t += ws * using_waitstates;
+               c += ws * using_waitstates;
+       }
+#endif
+       addcycles_ea_ce020 ("fea", h, t, c);
+       return 0;
+}
+
+static int gence020cycles_cea (instr *curi, amodes mode)
+{
+       int h = 0, t = 0, c = 0, oph = 0;
+       switch (mode)
+       {
+       case Dreg:
+       case Areg:
+               SETCE020(0, 0, 0);
+               break;
+       case Aind: // (An)
+               SETCE020H(2 + h, 0, 2);
+               break;
+       case Aipi: // (An)+
+               SETCE020(0, 0, 2);
+               break;
+       case Apdi: // -(An)
+               SETCE020H(2, 0, 2)
+               break;
+       case Ad8r: // (d8,An,Xn)
+       case PC8r: // (d8,PC,Xn)
+               SETCE020H(4, 0, 4)
+               break;
+       case Ad16: // (d16,An)
+       case PC16: // (d16,PC,Xn)
+               SETCE020H(2, 0, 2)
+               break;
+       case absw:
+               SETCE020H(2, 0, 2)
+               break;
+       case absl:
+               SETCE020H(4, 0, 4)
+               break;
+       }
+       addcycles_ea_ce020 ("cea", h, t, c, oph);
+       return oph;
+}
+
+static int gence020cycles_jea (amodes mode)
+{
+       int h = 0, t = 0, c = 0;
+       switch (mode)
+       {
+       case Aind: // (An)
+               SETCE020(2, 0, 2)
+               break;
+       case Ad16: // (d16,An)
+       case PC16: // (d16,PC,Xn)
+               SETCE020(4, 0, 4)
+               break;
+       case absw:
+               SETCE020(2, 0, 2)
+               break;
+       case absl:
+               SETCE020(2, 0, 2)
+               break;
+       }
+       addcycles_ea_ce020 ("jea", h, t, c);
+       return 0;
+}
 
 /* getv == 1: fetch data; getv != 0: check for odd address. If movem != 0,
 * the calling routine handles Apdi and Aipi modes.
@@ -611,7 +957,7 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
        switch (mode) {
        case Dreg:
                if (movem)
-                       abort ();
+                       term ();
                if (getv == 1)
                        switch (size) {
                        case sz_byte:
@@ -633,13 +979,13 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
                                printf ("\tuae_s32 %s = m68k_dreg (regs, %s);\n", name, reg);
                                break;
                        default:
-                               abort ();
+                               term ();
                }
                syncmovepc (getv, flags);
                return;
        case Areg:
                if (movem)
-                       abort ();
+                       term ();
                if (getv == 1)
                        switch (size) {
                        case sz_word:
@@ -649,18 +995,16 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
                                printf ("\tuae_s32 %s = m68k_areg (regs, %s);\n", name, reg);
                                break;
                        default:
-                               abort ();
+                               term ();
                }
                syncmovepc (getv, flags);
                return;
        case Aind: // (An)
-               addcycles_ce020 (2);
                printf ("\tuaecptr %sa;\n", name);
                add_mmu040_movem (movem);
                printf ("\t%sa = m68k_areg (regs, %s);\n", name, reg);
                break;
        case Aipi: // (An)+
-               addcycles_ce020 (2);
                printf ("\tuaecptr %sa;\n", name);
                add_mmu040_movem (movem);
                printf ("\t%sa = m68k_areg (regs, %s);\n", name, reg);
@@ -682,9 +1026,8 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
                        printf ("\t%sa = m68k_areg (regs, %s) - %d;\n", name, reg, movem ? 0 : 4);
                        break;
                default:
-                       abort ();
+                       term ();
                }
-               addcycles_ce020 (2);
                if (!(flags & GF_APDI)) {
                        addcycles000 (2);
                        insn_n_cycles += 2;
@@ -692,14 +1035,12 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
                }
                break;
        case Ad16: // (d16,An)
-               addcycles_ce020 (2);
                printf ("\tuaecptr %sa;\n", name);
                add_mmu040_movem (movem);
                printf ("\t%sa = m68k_areg (regs, %s) + (uae_s32)(uae_s16)%s;\n", name, reg, gen_nextiword (flags));
                count_read_ea++; 
                break;
        case Ad8r: // (d8,An,Xn)
-               addcycles_ce020 (4);
                printf ("\tuaecptr %sa;\n", name);
                if (cpu_level > 1) {
                        if (next_cpu_level < 1)
@@ -721,14 +1062,12 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
                }
                break;
        case PC16: // (d16,PC,Xn)
-               addcycles_ce020 (2);
                printf ("\tuaecptr %sa;\n", name);
                add_mmu040_movem (movem);
                printf ("\t%sa = m68k_getpc () + %d;\n", name, m68k_pc_offset);
                printf ("\t%sa += (uae_s32)(uae_s16)%s;\n", name, gen_nextiword (flags));
                break;
        case PC8r: // (d8,PC,Xn)
-               addcycles_ce020 (4);
                printf ("\tuaecptr tmppc;\n");
                printf ("\tuaecptr %sa;\n", name);
                if (cpu_level > 1) {
@@ -753,73 +1092,66 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
 
                break;
        case absw:
-               addcycles_ce020 (4);
                printf ("\tuaecptr %sa;\n", name);
                add_mmu040_movem (movem);
                printf ("\t%sa = (uae_s32)(uae_s16)%s;\n", name, gen_nextiword (flags));
                break;
        case absl:
-               addcycles_ce020 (4);
                gen_nextilong2 ("uaecptr", namea, flags, movem);
                count_read_ea += 2;
                break;
        case imm:
+               // fetch immediate address
                if (getv != 1)
-                       abort ();
+                       term ();
                insn_n_cycles020++;
                switch (size) {
                case sz_byte:
-                       addcycles_ce020 (2 + 2);
                        printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte (flags));
                        count_read_ea++;
                        break;
                case sz_word:
-                       addcycles_ce020 (2 + 2);
                        printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword (flags));
                        count_read_ea++;
                        break;
                case sz_long:
-                       addcycles_ce020 (4 + 2);
                        gen_nextilong ("uae_s32", name, flags);
                        count_read_ea += 2;
                        break;
                default:
-                       abort ();
+                       term ();
                }
                syncmovepc (getv, flags);
                return;
        case imm0:
                if (getv != 1)
-                       abort ();
-               addcycles_ce020 (2);
+                       term ();
                printf ("\tuae_s8 %s = %s;\n", name, gen_nextibyte (flags));
                count_read_ea++;
                syncmovepc (getv, flags);
                return;
        case imm1:
                if (getv != 1)
-                       abort ();
-               addcycles_ce020 (2);
+                       term ();
                printf ("\tuae_s16 %s = %s;\n", name, gen_nextiword (flags));
                count_read_ea++;
                syncmovepc (getv, flags);
                return;
        case imm2:
                if (getv != 1)
-                       abort ();
-               addcycles_ce020 (4);
+                       term ();
                gen_nextilong ("uae_s32", name, flags);
                count_read_ea += 2;
                syncmovepc (getv, flags);
                return;
        case immi:
                if (getv != 1)
-                       abort ();
+                       term ();
                printf ("\tuae_u32 %s = %s;\n", name, reg);
                syncmovepc (getv, flags);
                return;
        default:
-               abort ();
+               term ();
        }
 
        syncmovepc (getv, flags);
@@ -858,14 +1190,14 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
                        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 ();
+                       default: term ();
                        }
                } else if (using_ce) {
                        switch (size) {
                        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 ();
+                       default: term ();
                        }
                } else if (using_mmu) {
                        if (flags & GF_FC) {
@@ -873,14 +1205,14 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
                                case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = sfc%s_get_byte (%sa);\n", name, mmu_postfix, name); break;
                                case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = sfc%s_get_word (%sa);\n", name, mmu_postfix, name); break;
                                case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = sfc%s_get_long (%sa);\n", name, mmu_postfix, name); break;
-                               default: abort ();
+                               default: term ();
                                }
                        } else {
                                switch (size) {
                                case sz_byte: insn_n_cycles += 4; printf ("\tuae_s8 %s = %s (%sa);\n", name, (flags & GF_LRMW) ? srcblrmw : (rmw ? srcbrmw : srcb), name); break;
                                case sz_word: insn_n_cycles += 4; printf ("\tuae_s16 %s = %s (%sa);\n", name, (flags & GF_LRMW) ? srcwlrmw : (rmw ? srcwrmw : srcw), name); break;
                                case sz_long: insn_n_cycles += 8; printf ("\tuae_s32 %s = %s (%sa);\n", name, (flags & GF_LRMW) ? srcllrmw : (rmw ? srclrmw : srcl), name); break;
-                               default: abort ();
+                               default: term ();
                                }
                        }
                } else {
@@ -888,7 +1220,7 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
                        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 ();
+                       default: term ();
                        }
                }
        }
@@ -910,7 +1242,7 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
                                printf ("\tm68k_areg (regs, %s) += 4;\n", reg);
                                break;
                        default:
-                               abort ();
+                               term ();
                        }
                        break;
                case Apdi:
@@ -926,15 +1258,65 @@ static void genamode2 (amodes mode, char *reg, wordsizes size, char *name, int g
        }
 }
 
-
-static void genamode (amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags)
+static void genamode (instr *curi, amodes mode, char *reg, wordsizes size, char *name, int getv, int movem, int flags)
 {
        int oldfixup = mmufixupstate;
+       int subhead = 0;
+       if (using_ce020 && curi) {
+               switch (curi->fetchmode)
+               {
+               case 1:
+                       subhead = gence020cycles_fea (mode);
+               break;
+               case 2:
+                       subhead = gence020cycles_cea (curi, mode);
+               break;
+               case 5:
+                       subhead = gence020cycles_jea (mode);
+               break;
+               }
+       }
        genamode2 (mode, reg, size, name, getv, movem, flags);
        if (using_mmu == 68040 && (oldfixup & 1)) {
                // we have fixup already active = this genamode call is destination mode and we can now clear previous source fixup.
                clearmmufixup (0);
        }
+       if (using_ce020 && curi)
+               addop_ce020 (curi, subhead);
+}
+
+
+static void genamodedual (instr *curi, amodes smode, char *sreg, wordsizes ssize, char *sname, int sgetv, int sflags,
+                                          amodes dmode, char *dreg, wordsizes dsize, char *dname, int dgetv, int dflags)
+{
+       int subhead = 0;
+       if (using_ce020) {
+               switch (curi->fetchmode)
+               {
+               case 1:
+                       if (smode >= imm)
+                               subhead = gence020cycles_fea(dmode);
+                       else
+                               subhead = gence020cycles_fea (smode);
+               break;
+               case 2:
+                       subhead = gence020cycles_cea (curi, smode);
+               break;
+               case 3:
+                       subhead = gence020cycles_fiea (curi, ssize, dmode);
+               break;
+               case 4:
+                       subhead = gence020cycles_ciea (curi, ssize, dmode);
+               break;
+               case 5:
+                       subhead = gence020cycles_jea (smode);
+               break;
+               }
+       }
+       genamode (NULL, smode, sreg, ssize, sname, sgetv, 0, sflags);
+       genamode (NULL, dmode, dreg, dsize, dname, dgetv, 0, dflags);
+       if (using_ce020)
+               addop_ce020 (curi, subhead);
 }
 
 static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, char *to, int store_dir, int flags)
@@ -957,7 +1339,7 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha
                        printf ("\tm68k_dreg (regs, %s) = (%s);\n", reg, from);
                        break;
                default:
-                       abort ();
+                       term ();
                }
                break;
        case Areg:
@@ -969,7 +1351,7 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha
                        printf ("\tm68k_areg (regs, %s) = (%s);\n", reg, from);
                        break;
                default:
-                       abort ();
+                       term ();
                }
                break;
        case Aind:
@@ -991,18 +1373,18 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha
                                break;
                        case sz_word:
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
-                                       abort ();
+                                       term ();
                                printf ("\t%s (%sa, %s);\n", dstw, to, from);
                                count_write++;
                                break;
                        case sz_long:
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
-                                       abort ();
+                                       term ();
                                printf ("\t%s (%sa, %s);\n", dstl, to, from);
                                count_write += 2;
                                break;
                        default:
-                               abort ();
+                               term ();
                        }
                } else if (using_ce) {
                        switch (size) {
@@ -1012,13 +1394,13 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha
                                break;
                        case sz_word:
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
-                                       abort ();
+                                       term ();
                                printf ("\tx_put_word (%sa, %s);\n", to, from);
                                count_write++;
                                break;
                        case sz_long:
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
-                                       abort ();
+                                       term ();
                                if (store_dir)
                                        printf ("\t%s (%sa + 2, %s); %s (%sa, %s >> 16);\n", dstw, to, from, dstw, to, from);
                                else
@@ -1026,7 +1408,7 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha
                                count_write += 2;
                                break;
                        default:
-                               abort ();
+                               term ();
                        }
                } else if (using_mmu) {
                        switch (size) {
@@ -1040,7 +1422,7 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha
                        case sz_word:
                                insn_n_cycles += 4;
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
-                                       abort ();
+                                       term ();
                                if (flags & GF_FC)
                                        printf ("\tdfc%s_put_word (%sa, %s);\n", mmu_postfix, to, from);
                                else
@@ -1049,14 +1431,14 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha
                        case sz_long:
                                insn_n_cycles += 8;
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
-                                       abort ();
+                                       term ();
                                if (flags & GF_FC)
                                        printf ("\tdfc%s_put_long (%sa, %s);\n", mmu_postfix, to, from);
                                else
                                        printf ("\t%s (%sa, %s);\n", (flags & GF_LRMW) ? dstllrmw : (candormw ? dstlrmw : dstl), to, from);
                                break;
                        default:
-                               abort ();
+                               term ();
                        }
                } else {
                        switch (size) {
@@ -1068,19 +1450,19 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha
                        case sz_word:
                                insn_n_cycles += 4;
                                if (cpu_level < 2 && (mode == PC16 || mode == PC8r))
-                                       abort ();
+                                       term ();
                                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 ();
+                                       term ();
                                printf ("\t%s (%sa, %s);\n", dstl, to, from);
                                count_write += 2;
                                break;
                        default:
-                               abort ();
+                               term ();
                        }
                }
                break;
@@ -1089,10 +1471,10 @@ static void genastore_2 (char *from, amodes mode, char *reg, wordsizes size, cha
        case imm1:
        case imm2:
        case immi:
-               abort ();
+               term ();
                break;
        default:
-               abort ();
+               term ();
        }
 }
 
@@ -1300,7 +1682,7 @@ static void genmovemel (uae_u16 opcode)
        count_read += table68k[opcode].size == sz_long ? 2 : 1;
        printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0));
        printf ("\tuae_u32 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
-       genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, mmu040_special_movem (opcode) ? 3 : 1, 0);
+       genamode (NULL, table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, mmu040_special_movem (opcode) ? 3 : 1, 0);
        addcycles_ce020 (8);
        start_brace ();
        if (using_mmu == 68030) {
@@ -1333,7 +1715,7 @@ static void genmovemel_ce (uae_u16 opcode)
        printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0));
        printf ("\tuae_u32 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;\n");
        printf ("\tuae_u32 v;\n");
-       genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, GF_AA);
+       genamode (NULL, table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, GF_AA);
        if (table68k[opcode].dmode == Ad8r || table68k[opcode].dmode == PC8r)
                addcycles000 (2);
        start_brace ();
@@ -1369,7 +1751,7 @@ static void genmovemle (uae_u16 opcode)
        count_write += table68k[opcode].size == sz_long ? 2 : 1;
 
        printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0));
-       genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, mmu040_special_movem (opcode) ? 3 : 1, 0);
+       genamode (NULL, table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, mmu040_special_movem (opcode) ? 3 : 1, 0);
        addcycles_ce020 (4);
        start_brace ();
        if (using_mmu >= 68030) {
@@ -1417,7 +1799,7 @@ static void genmovemle_ce (uae_u16 opcode)
 {
        int size = table68k[opcode].size == sz_long ? 4 : 2;
        printf ("\tuae_u16 mask = %s;\n", gen_nextiword (0));
-       genamode (table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, GF_AA);
+       genamode (NULL, table68k[opcode].dmode, "dstreg", table68k[opcode].size, "src", 2, 1, GF_AA);
 
        if (table68k[opcode].dmode == Ad8r || table68k[opcode].dmode == PC8r) {
                addcycles000 (2);
@@ -1493,7 +1875,7 @@ static void genflags_normal (flagtypes type, wordsizes size, char *value, char *
                strcpy (usstr, "((uae_u32)(");
                break;
        default:
-               abort ();
+               term ();
        }
        strcpy (unsstr, usstr);
 
@@ -1565,8 +1947,8 @@ static void genflags_normal (flagtypes type, wordsizes size, char *value, char *
        switch (type) {
        case flag_logical:
                printf ("\tCLEAR_CZNV ();\n");
-               printf ("\tSET_ZFLG   (%s == 0);\n", vstr);
-               printf ("\tSET_NFLG   (%s < 0);\n", vstr);
+               printf ("\tSET_ZFLG (%s == 0);\n", vstr);
+               printf ("\tSET_NFLG (%s < 0);\n", vstr);
                break;
        case flag_logical_noclobber:
                printf ("\tSET_ZFLG (%s == 0);\n", vstr);
@@ -1720,7 +2102,7 @@ static const char *cmask (wordsizes size)
        case sz_byte: return "0x80";
        case sz_word: return "0x8000";
        case sz_long: return "0x80000000";
-       default: abort ();
+       default: term ();
        }
 }
 
@@ -1775,6 +2157,7 @@ static void resetvars (void)
        mmudisp020cnt = 0;
        candormw = false;
        rmw_varname[0] = 0;
+       tail_ce020 = 0;
        
        prefetch_long = NULL;
        srcli = NULL;
@@ -1827,8 +2210,8 @@ static void resetvars (void)
                        nextw = "next_iword_020ce";
                        nextl = "next_ilong_020ce";
                } else if (using_ce020 == 2) {
-                       // 68030/40/60 CE
-                       disp020 = "x_get_disp_ea_ce020";
+                       // 68030 CE
+                       disp020 = "x_get_disp_ea_ce030";
                        prefetch_long = "get_long_ce030_prefetch";
                        prefetch_word = "get_word_ce030_prefetch";
                        srcli = "x_get_ilong";
@@ -1840,6 +2223,7 @@ static void resetvars (void)
                        dstw = "x_put_word";
                        srcb = "x_get_byte";
                        dstb = "x_put_byte";
+                       do_cycles = "do_cycles_ce020";
                        nextw = "next_iword_030ce";
                        nextl = "next_ilong_030ce";
                } else if (using_prefetch_020) {
@@ -2062,8 +2446,9 @@ static void gen_opcode (unsigned long int opcode)
        case i_EOR:
        {
                int c = 0;
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_RMW);
+               genamodedual (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, curi->dmode, "dstreg", curi->size, "dst", 1, GF_RMW);
+//             genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+//             genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_RMW);
                printf ("\tsrc %c= dst;\n", curi->mnemo == i_OR ? '|' : curi->mnemo == i_AND ? '&' : '^');
                genflags (flag_logical, curi->size, "src", "", "");
                if (curi->dmode == Dreg && curi->size == sz_long) {
@@ -2071,8 +2456,6 @@ static void gen_opcode (unsigned long int opcode)
                        if (curi->smode == imm || curi->smode == Dreg)
                                c += 2;
                }
-               if (curi->dmode != Dreg)
-                       addcycles_ce020 (4);
                fill_prefetch_next ();
                if (c > 0)
                        addcycles000 (c);
@@ -2083,12 +2466,11 @@ static void gen_opcode (unsigned long int opcode)
        case i_ORSR:
        case i_EORSR:
                printf ("\tMakeSR ();\n");
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                dummy_prefetch ();
                if (curi->size == sz_byte) {
                        printf ("\tsrc &= 0xFF;\n");
                }
-               addcycles_ce020 (12);
                addcycles000 (8);
                fill_prefetch_next ();
                printf ("\tregs.sr %c= src;\n", curi->mnemo == i_EORSR ? '^' : '|');
@@ -2096,12 +2478,11 @@ static void gen_opcode (unsigned long int opcode)
                break;
        case i_ANDSR:
                printf ("\tMakeSR ();\n");
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                dummy_prefetch ();
                if (curi->size == sz_byte) {
                        printf ("\tsrc |= 0xFF00;\n");
                }
-               addcycles_ce020 (12);
                addcycles000 (8);
                fill_prefetch_next ();
                printf ("\tregs.sr &= src;\n");
@@ -2110,16 +2491,17 @@ static void gen_opcode (unsigned long int opcode)
        case i_SUB:
        {
                int c = 0;
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_RMW);
+               genamodedual (curi,
+                       curi->smode, "srcreg", curi->size, "src", 1, 0,
+                       curi->dmode, "dstreg", curi->size, "dst", 1, GF_RMW);
+               //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_RMW);
                if (curi->dmode == Dreg) {
                        if (curi->size == sz_long) {
                                c += 2;
                                if (curi->smode == imm || curi->smode == immi || curi->smode == Dreg)
                                        c += 2;
                        }
-               } else {
-                       addcycles_ce020 (4);
                }
                fill_prefetch_next ();
                if (c > 0)
@@ -2132,8 +2514,11 @@ static void gen_opcode (unsigned long int opcode)
        case i_SUBA:
        {
                int c = 0;
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, GF_RMW);
+               genamodedual (curi,
+                       curi->smode, "srcreg", curi->size, "src", 1, 0,
+                       curi->dmode, "dstreg", sz_long, "dst", 1, GF_RMW);
+               //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               //genamode (curi, curi->dmode, "dstreg", sz_long, "dst", 1, 0, GF_RMW);
                if (curi->smode == immi) {
                        // SUBAQ.x is always 8 cycles
                        c += 4;
@@ -2153,12 +2538,11 @@ static void gen_opcode (unsigned long int opcode)
        case i_SUBX:
                if (!isreg (curi->smode))
                        addcycles000 (2);
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
-               genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA | GF_RMW);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
+               genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA | GF_RMW);
                fill_prefetch_next ();
                if (curi->size == sz_long && isreg (curi->smode))
                        addcycles000 (4);
-               addcycles_ce020 (isreg (curi->smode) ? 2 : 12);
                start_brace ();
                printf ("\tuae_u32 newv = dst - src - (GET_XFLG () ? 1 : 0);\n");
                genflags (flag_subx, curi->size, "newv", "src", "dst");
@@ -2168,8 +2552,8 @@ static void gen_opcode (unsigned long int opcode)
        case i_SBCD:
                if (!isreg (curi->smode))
                        addcycles000 (2);
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
-               genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA | GF_RMW);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
+               genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA | GF_RMW);
                fill_prefetch_next ();
                start_brace ();
                printf ("\tuae_u16 newv_lo = (dst & 0xF) - (src & 0xF) - (GET_XFLG () ? 1 : 0);\n");
@@ -2192,25 +2576,23 @@ static void gen_opcode (unsigned long int opcode)
                }
                if (isreg (curi->smode)) {
                        addcycles000 (2);
-                       addcycles_ce020 (4);
-               } else {
-                       addcycles_ce020 (16);
                }
                genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
                break;
        case i_ADD:
        {
                int c = 0;
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_RMW);
+               genamodedual (curi,
+                       curi->smode, "srcreg", curi->size, "src", 1, 0,
+                       curi->dmode, "dstreg", curi->size, "dst", 1, GF_RMW);
+               //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_RMW);
                if (curi->dmode == Dreg) {
                        if (curi->size == sz_long) {
                                c += 2;
                                if (curi->smode == imm || curi->smode == immi || curi->smode == Dreg)
                                        c += 2;
                        }
-               } else {
-                       addcycles_ce020 (4);
                }
                fill_prefetch_next ();
                if (c > 0)
@@ -2223,8 +2605,11 @@ static void gen_opcode (unsigned long int opcode)
        case i_ADDA:
        {
                int c = 0;
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, GF_RMW);
+               genamodedual (curi,
+                       curi->smode, "srcreg", curi->size, "src", 1, 0,
+                       curi->dmode, "dstreg", sz_long, "dst", 1, GF_RMW);
+               //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               //genamode (curi, curi->dmode, "dstreg", sz_long, "dst", 1, 0, GF_RMW);
                if (curi->smode == immi) {
                        // ADDAQ.x is always 8 cycles
                        c += 4;
@@ -2244,12 +2629,11 @@ static void gen_opcode (unsigned long int opcode)
        case i_ADDX:
                if (!isreg (curi->smode))
                        addcycles000 (2);
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
-               genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA | GF_RMW);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
+               genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA | GF_RMW);
                fill_prefetch_next ();
                if (curi->size == sz_long && isreg (curi->smode))
                        addcycles000 (4);
-               addcycles_ce020 (isreg (curi->smode) ? 2 : 12);
                start_brace ();
                printf ("\tuae_u32 newv = dst + src + (GET_XFLG () ? 1 : 0);\n");
                genflags (flag_addx, curi->size, "newv", "src", "dst");
@@ -2259,8 +2643,8 @@ static void gen_opcode (unsigned long int opcode)
        case i_ABCD:
                if (!isreg (curi->smode))
                        addcycles000 (2);
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
-               genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA | GF_RMW);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
+               genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA | GF_RMW);
                fill_prefetch_next ();
                start_brace ();
                printf ("\tuae_u16 newv_lo = (src & 0xF) + (dst & 0xF) + (GET_XFLG () ? 1 : 0);\n");
@@ -2285,28 +2669,23 @@ static void gen_opcode (unsigned long int opcode)
                }
                if (isreg (curi->smode)) {
                        addcycles000 (2);
-                       addcycles_ce020 (4);
-               } else {
-                       addcycles_ce020 (16);
                }
                genastore ("newv", curi->dmode, "dstreg", curi->size, "dst");
                break;
        case i_NEG:
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW);
                fill_prefetch_next ();
                if (isreg (curi->smode) && curi->size == sz_long)
                        addcycles000 (2);
-               addcycles_ce020 (isreg (curi->smode) ? 2 : 4);
                start_brace ();
                genflags (flag_sub, curi->size, "dst", "src", "0");
                genastore_rev ("dst", curi->smode, "srcreg", curi->size, "src");
                break;
        case i_NEGX:
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW);
                fill_prefetch_next ();
                if (isreg (curi->smode) && curi->size == sz_long)
                        addcycles000 (2);
-               addcycles_ce020 (isreg (curi->smode) ? 2 : 4);
                start_brace ();
                printf ("\tuae_u32 newv = 0 - src - (GET_XFLG () ? 1 : 0);\n");
                genflags (flag_subx, curi->size, "newv", "src", "0");
@@ -2314,10 +2693,9 @@ static void gen_opcode (unsigned long int opcode)
                genastore_rev ("newv", curi->smode, "srcreg", curi->size, "src");
                break;
        case i_NBCD:
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW);
                if (isreg (curi->smode))
                        addcycles000 (2);
-               addcycles_ce020 (6);
                fill_prefetch_next ();
                start_brace ();
                printf ("\tuae_u16 newv_lo = - (src & 0xF) - (GET_XFLG () ? 1 : 0);\n");
@@ -2343,35 +2721,34 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("newv", curi->smode, "srcreg", curi->size, "src");
                break;
        case i_CLR:
-               genamode (curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0);
                fill_prefetch_next ();
                if (isreg (curi->smode) && curi->size == sz_long)
                        addcycles000 (2);
-               addcycles_ce020 (isreg (curi->smode) ? 2 : 4);
                genflags (flag_logical, curi->size, "0", "", "");
                genastore_rev ("0", curi->smode, "srcreg", curi->size, "src");
                break;
        case i_NOT:
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW);
                fill_prefetch_next ();
                if (isreg (curi->smode) && curi->size == sz_long)
                        addcycles000 (2);
-               addcycles_ce020 (isreg (curi->smode) ? 2 : 4);
                start_brace ();
                printf ("\tuae_u32 dst = ~src;\n");
                genflags (flag_logical, curi->size, "dst", "", "");
                genastore_rev ("dst", curi->smode, "srcreg", curi->size, "src");
                break;
        case i_TST:
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
-               addcycles_ce020 (2);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                fill_prefetch_next ();
                genflags (flag_logical, curi->size, "src", "", "");
                break;
        case i_BTST:
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_IR2IRC);
-               addcycles_ce020 (4);
+               genamodedual (curi,
+                       curi->smode, "srcreg", curi->size, "src", 1, 0,
+                       curi->dmode, "dstreg", curi->size, "dst", 1, GF_IR2IRC);
+               //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_IR2IRC);
                fill_prefetch_next ();
                bsetcycles (curi);
                printf ("\tSET_ZFLG (1 ^ ((dst >> src) & 1));\n");
@@ -2383,9 +2760,11 @@ static void gen_opcode (unsigned long int opcode)
                //during instruction's read access CPU data lines appear as zero to outside world,
                // (normally previously fetched data appears in data lines if reading write-only register)
                // this allows stupid things like bset #2,$dff096 to work "correctly"
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_IR2IRC | GF_RMW);
-               addcycles_ce020 (4);
+               genamodedual (curi,
+                       curi->smode, "srcreg", curi->size, "src", 1, 0,
+                       curi->dmode, "dstreg", curi->size, "dst", 1, GF_IR2IRC | GF_RMW);
+               //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_IR2IRC | GF_RMW);
                fill_prefetch_next ();
                bsetcycles (curi);
                // bclr needs 1 extra cycle
@@ -2405,16 +2784,21 @@ static void gen_opcode (unsigned long int opcode)
                break;
        case i_CMPM:
                // confirmed
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
-               genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
+               genamodedual (curi,
+                       curi->smode, "srcreg", curi->size, "src", 1, GF_AA,
+                       curi->dmode, "dstreg", curi->size, "dst", 1, GF_AA);
+               //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA);
+               //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_AA);
                fill_prefetch_next ();
-               addcycles_ce020 (9);
                start_brace ();
                genflags (flag_cmp, curi->size, "newv", "src", "dst");
                break;
        case i_CMP:
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
+               genamodedual (curi,
+                       curi->smode, "srcreg", curi->size, "src", 1, GF_AA,
+                       curi->dmode, "dstreg", curi->size, "dst", 1, GF_AA);
+               //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
                fill_prefetch_next ();
                if (curi->dmode == Dreg && curi->size == sz_long)
                        addcycles000 (2);
@@ -2422,18 +2806,20 @@ static void gen_opcode (unsigned long int opcode)
                genflags (flag_cmp, curi->size, "newv", "src", "dst");
                break;
        case i_CMPA:
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
+               genamodedual (curi,
+                       curi->smode, "srcreg", curi->size, "src", 1, 0,
+                       curi->dmode, "dstreg", sz_long, "dst", 1, 0);
+               //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               //genamode (curi, curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
                fill_prefetch_next ();
                addcycles000 (4);
-               addcycles_ce020 (4);
                start_brace ();
                genflags (flag_cmp, sz_long, "newv", "src", "dst");
                break;
                /* The next two are coded a little unconventional, but they are doing
                * weird things... */
        case i_MVPRM: // MOVEP R->M
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                printf ("\tuaecptr memp = m68k_areg (regs, dstreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword (0));
                if (curi->size == sz_word) {
                        printf ("\t%s (memp, src >> 8);\n\t%s (memp + 2, src);\n", dstb, dstb);
@@ -2447,7 +2833,7 @@ static void gen_opcode (unsigned long int opcode)
                break;
        case i_MVPMR: // MOVEP M->R
                printf ("\tuaecptr memp = m68k_areg (regs, srcreg) + (uae_s32)(uae_s16)%s;\n", gen_nextiword (0));
-               genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
+               genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
                if (curi->size == sz_word) {
                        printf ("\tuae_u16 val = (%s (memp) << 8) + %s (memp + 2);\n", srcb, srcb);
                        count_read += 2;
@@ -2470,31 +2856,103 @@ static void gen_opcode (unsigned long int opcode)
                        * - move.x xxx,[at least 1 extension word here] = fetch 1 extension word before (xxx)
                        *
                        */
-                       int prefetch_done = 0, flags;
-                       int dualprefetch = curi->dmode == absl && (curi->smode != Dreg && curi->smode != Areg && curi->smode != imm);
-                       genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_MOVE);
-                       flags = 1 | (dualprefetch ? GF_NOREFILL : 0);
-                       genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, flags | GF_MOVE);
-                       if (curi->mnemo == i_MOVEA && curi->size == sz_word)
-                               printf ("\tsrc = (uae_s32)(uae_s16)src;\n");
-                       if (curi->dmode == Apdi) {
-                               fill_prefetch_next ();
-                               prefetch_done = 1;
-                       }
-                       if (curi->mnemo == i_MOVE)
-                               genflags (flag_logical, curi->size, "src", "", "");
-                       genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
-                       sync_m68k_pc ();
-                       if (dualprefetch) {
-                               fill_prefetch_full_000 ();
-                               prefetch_done = 1;
+                       if (using_ce020) {
+                               // MOVE is too complex to handle in table68k
+                               int h = 0, t = 0, c = 0, subhead = 0;
+                               bool fea = false;
+                               if (isreg (curi->smode) && isreg (curi->dmode)) {
+                                       // MOVE Rn,Rn
+                                       h = 2; t = 0; c = 2;
+                               } else if (isreg (curi->dmode)) {
+                                       // MOVE EA,Rn
+                                       h = 0; t = 0; c = 2;
+                                       fea = true;
+                               } else if (curi->dmode == Aind) {
+                                       if (isreg (curi->smode)) {
+                                               // MOVE Rn,(An)
+                                               h = 0; t = 1; c = 3;
+                                       } else {
+                                               // MOVE SOURCE,(An)
+                                               h = 2; t = 0; c = 4;
+                                               fea = true;
+                                       }
+                               } else if (curi->dmode == Aipi) {
+                                       if (isreg (curi->smode)) {
+                                               // MOVE Rn,(An)+
+                                               h = 0; t = 1; c = 3;
+                                       } else {
+                                               // MOVE SOURCE,(An)+
+                                               h = 2; t = 0; c = 4;
+                                               fea = true;
+                                       }
+                               } else if (curi->dmode == Apdi) {
+                                       if (isreg (curi->smode)) {
+                                               // MOVE Rn,-(An)
+                                               h = 0; t = 2; c = 4;
+                                       } else {
+                                               // MOVE SOURCE,-(An)
+                                               h = 2; t = 0; c = 4;
+                                               fea = true;
+                                       }
+                               } else if (curi->dmode == Ad16) {
+                                       h = 2; t = 0; c = 4;
+                                       fea = true;
+                               } else if (curi->dmode == Ad8r) {
+                                       h = 4; t = 0; c = 6;
+                                       fea = true;
+                               } else if (curi->dmode == absw) {
+                                       h = 2; t = 0; c = 4;
+                                       fea = true;
+                               } else if (curi->dmode == absl) {
+                                       h = 0; t = 0; c = 6;
+                                       fea = true;
+                               } else {
+                                       h = 4; t = 0; c = 6;
+                                       fea = true;
+                               }
+                               if (fea) {
+                                       if (curi->smode == imm)
+                                               subhead = gence020cycles_fiea (curi, curi->size, Dreg);
+                                       else
+                                               subhead = gence020cycles_fea (curi->smode);
+                               }
+                               genamode2 (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_MOVE);
+                               genamode2 (curi->dmode, "dstreg", curi->size, "dst", 2, 0, GF_MOVE);
+                               addopcycles_ce20 (h, t, c, -subhead);
+                               if (curi->mnemo == i_MOVEA && curi->size == sz_word)
+                                       printf ("\tsrc = (uae_s32)(uae_s16)src;\n");
+                               if (curi->mnemo == i_MOVE)
+                                       genflags (flag_logical, curi->size, "src", "", "");
+                               genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
+                               sync_m68k_pc ();
+
+                       } else {
+                               int prefetch_done = 0, flags;
+                               int dualprefetch = curi->dmode == absl && (curi->smode != Dreg && curi->smode != Areg && curi->smode != imm);
+                               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_MOVE);
+                               flags = 1 | (dualprefetch ? GF_NOREFILL : 0);
+                               genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, flags | GF_MOVE);
+                               if (curi->mnemo == i_MOVEA && curi->size == sz_word)
+                                       printf ("\tsrc = (uae_s32)(uae_s16)src;\n");
+                               if (curi->dmode == Apdi) {
+                                       fill_prefetch_next ();
+                                       prefetch_done = 1;
+                               }
+                               if (curi->mnemo == i_MOVE)
+                                       genflags (flag_logical, curi->size, "src", "", "");
+                               genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
+                               sync_m68k_pc ();
+                               if (dualprefetch) {
+                                       fill_prefetch_full_000 ();
+                                       prefetch_done = 1;
+                               }
+                               if (!prefetch_done)
+                                       fill_prefetch_next ();
                        }
-                       if (!prefetch_done)
-                               fill_prefetch_next ();
                }
                break;
        case i_MVSR2: // MOVE FROM SR
-               genamode (curi->smode, "srcreg", sz_word, "src", 2, 0, 0);
+               genamode (curi, curi->smode, "srcreg", sz_word, "src", 2, 0, 0);
                fill_prefetch_next ();
                if (isreg (curi->smode))
                        addcycles000 (2);
@@ -2505,36 +2963,36 @@ static void gen_opcode (unsigned long int opcode)
                        genastore ("regs.sr", curi->smode, "srcreg", sz_word, "src");
                break;
        case i_MV2SR: // MOVE TO SR
-               genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
+               genamode (curi, curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
                if (curi->size == sz_byte) {
                        // MOVE TO CCR
                        dummy_prefetch ();
                        addcycles000 (4);
-                       addcycles_ce020 (4);
                        printf ("\tMakeSR ();\n\tregs.sr &= 0xFF00;\n\tregs.sr |= src & 0xFF;\n");
                } else {
                        // MOVE TO SR
                        dummy_prefetch ();
                        addcycles000 (4);
-                       addcycles_ce020 (8);
                        printf ("\tregs.sr = src;\n");
                }
                printf ("\tMakeFromSR ();\n");
                fill_prefetch_next ();
                break;
        case i_SWAP:
-               genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, 0);
+               genamode (curi, curi->smode, "srcreg", sz_long, "src", 1, 0, 0);
                fill_prefetch_next ();
                start_brace ();
-               addcycles_ce020 (4);
                printf ("\tuae_u32 dst = ((src >> 16)&0xFFFF) | ((src&0xFFFF)<<16);\n");
                genflags (flag_logical, sz_long, "dst", "", "");
                genastore ("dst", curi->smode, "srcreg", sz_long, "src");
                break;
        case i_EXG:
                // confirmed
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
+               genamodedual (curi,
+                       curi->smode, "srcreg", curi->size, "src", 1, 0,
+                       curi->dmode, "dstreg", curi->size, "dst", 1, 0);
+               //genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
                fill_prefetch_next ();
                addcycles000 (2);
                genastore ("dst", curi->smode, "srcreg", curi->size, "src");
@@ -2542,15 +3000,14 @@ static void gen_opcode (unsigned long int opcode)
                break;
        case i_EXT:
                // confirmed
-               genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, 0);
+               genamode (curi, curi->smode, "srcreg", sz_long, "src", 1, 0, 0);
                fill_prefetch_next ();
-               addcycles_ce020 (4);
                start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 dst = (uae_s32)(uae_s8)src;\n"); break;
                case sz_word: printf ("\tuae_u16 dst = (uae_s16)(uae_s8)src;\n"); break;
                case sz_long: printf ("\tuae_u32 dst = (uae_s32)(uae_s16)src;\n"); break;
-               default: abort ();
+               default: term ();
                }
                genflags (flag_logical,
                        curi->size == sz_word ? sz_word : sz_long, "dst", "", "");
@@ -2572,7 +3029,7 @@ static void gen_opcode (unsigned long int opcode)
                        genmovemle (opcode);
                break;
        case i_TRAP:
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                gen_set_fault_pc ();
                sync_m68k_pc ();
                printf ("\tException (src + 32);\n");
@@ -2580,15 +3037,13 @@ static void gen_opcode (unsigned long int opcode)
                m68k_pc_offset = 0;
                break;
        case i_MVR2USP:
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                fill_prefetch_next ();
-               addcycles_ce020 (2);
                printf ("\tregs.usp = src;\n");
                break;
        case i_MVUSP2R:
-               genamode (curi->smode, "srcreg", curi->size, "src", 2, 0, 0);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 2, 0, 0);
                fill_prefetch_next ();
-               addcycles_ce020 (2);
                genastore ("regs.usp", curi->smode, "srcreg", curi->size, "src");
                break;
        case i_RESET:
@@ -2596,7 +3051,6 @@ static void gen_opcode (unsigned long int opcode)
                printf ("\tcpureset ();\n");
                sync_m68k_pc ();
                addcycles000 (128);
-               addcycles_ce020 (518);
                if (using_prefetch) {
                        printf ("\t%s (2);\n", prefetch_word);
                        m68k_pc_offset = 0;
@@ -2604,19 +3058,15 @@ static void gen_opcode (unsigned long int opcode)
                break;
        case i_NOP:
                fill_prefetch_next ();
-               addcycles_ce020 (2);
-               if (using_ce020)
-                       printf ("\t%s (6);\n", do_cycles);
                break;
        case i_STOP:
                if (using_prefetch) {
                        printf ("\tregs.sr = regs.irc;\n");
                        m68k_pc_offset += 2;
                } else {
-                       genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+                       genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                        printf ("\tregs.sr = src;\n");
                }
-               addcycles_ce020 (8);
                printf ("\tMakeFromSR ();\n");
                printf ("\tm68k_setstopped ();\n");
                sync_m68k_pc ();
@@ -2624,10 +3074,10 @@ static void gen_opcode (unsigned long int opcode)
                did_prefetch = -1;
                break;
        case i_LPSTOP: /* 68060 */
-               printf ("\tuae_u16 sw = x_get_iword (2);\n");
+               printf ("\tuae_u16 sw = %s (2);\n", srcwi);
                printf ("\tuae_u16 sr;\n");
                printf ("\tif (sw != (0x100|0x80|0x40)) { Exception (4); goto %s; }\n", endlabelstr);
-               printf ("\tsr = x_get_iword (4);\n");
+               printf ("\tsr = %s (4);\n", srcwi);
                printf ("\tif (!(sr & 0x8000)) { Exception (8); goto %s; }\n", endlabelstr);
                printf ("\tregs.sr = sr;\n");
                printf ("\tMakeFromSR ();\n");
@@ -2638,8 +3088,8 @@ static void gen_opcode (unsigned long int opcode)
                break;
        case i_RTE:
                if (cpu_level == 0) {
-                       genamode (Aipi, "7", sz_word, "sr", 1, 0, GF_NOREFILL);
-                       genamode (Aipi, "7", sz_long, "pc", 1, 0, GF_NOREFILL);
+                       genamode (NULL, Aipi, "7", sz_word, "sr", 1, 0, GF_NOREFILL);
+                       genamode (NULL, Aipi, "7", sz_long, "pc", 1, 0, GF_NOREFILL);
                        printf ("\tregs.sr = sr;\n");
                        setpc ("pc");
                        printf ("\tMakeFromSR ();\n");
@@ -2696,13 +3146,12 @@ static void gen_opcode (unsigned long int opcode)
                break;
        case i_RTD:
                if (using_mmu) {
-                       genamode (curi->smode, "srcreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0);
-                       genamode (Aipi, "7", sz_long, "pc", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0);
+                       genamode (curi, curi->smode, "srcreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0);
+                       genamode (NULL, Aipi, "7", sz_long, "pc", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0);
                        printf ("\tm68k_areg(regs, 7) += offs;\n");
                } else {
-                       genamode (Aipi, "7", sz_long, "pc", 1, 0, 0);
-                       genamode (curi->smode, "srcreg", curi->size, "offs", 1, 0, 0);
-                       addcycles_ce020 (10);
+                       genamode (NULL, Aipi, "7", sz_long, "pc", 1, 0, 0);
+                       genamode (curi, 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, pc);\n", opcode);
@@ -2723,17 +3172,16 @@ static void gen_opcode (unsigned long int opcode)
                // ce confirmed
                if (using_mmu) {
                        addmmufixup ("srcreg");
-                       genamode (curi->dmode, "dstreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0);
-                       genamode (Apdi, "7", sz_long, "old", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, 0);
-                       genamode (curi->smode, "srcreg", sz_long, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0);
+                       genamode (NULL, curi->dmode, "dstreg", curi->size, "offs", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0);
+                       genamode (NULL, Apdi, "7", sz_long, "old", GENA_GETV_FETCH_ALIGN, GENA_MOVEM_DO_INC, 0);
+                       genamode (NULL, curi->smode, "srcreg", sz_long, "src", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, 0);
                        genastore ("m68k_areg(regs, 7)", curi->smode, "srcreg", sz_long, "src");
                        printf ("\tm68k_areg(regs, 7) += offs;\n");
                        genastore ("src", Apdi, "7", sz_long, "old");
                } else {
-                       genamode (Apdi, "7", sz_long, "old", 2, 0, GF_AA);
-                       genamode (curi->smode, "srcreg", sz_long, "src", 1, 0, GF_AA);
-                       genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0, 0);
-                       addcycles_ce020 (5);
+                       genamode (NULL, Apdi, "7", sz_long, "old", 2, 0, GF_AA);
+                       genamode (NULL, curi->smode, "srcreg", sz_long, "src", 1, 0, GF_AA);
+                       genamode (NULL, curi->dmode, "dstreg", curi->size, "offs", 1, 0, 0);
                        genastore ("src", Apdi, "7", sz_long, "old");
                        genastore ("m68k_areg (regs, 7)", curi->smode, "srcreg", sz_long, "src");
                        printf ("\tm68k_areg (regs, 7) += offs;\n");
@@ -2743,22 +3191,20 @@ static void gen_opcode (unsigned long int opcode)
        case i_UNLK:
                // ce confirmed
                if (using_mmu) {
-                       genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+                       genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                        printf ("\tuae_s32 old = %s (src);\n", srcl);
                        printf ("\tm68k_areg (regs, 7) = src + 4;\n");
                        printf ("\tm68k_areg (regs, srcreg) = old;\n");
                } else {
-                       genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+                       genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                        printf ("\tm68k_areg (regs, 7) = src;\n");
-                       genamode (Aipi, "7", sz_long, "old", 1, 0, 0);
-                       addcycles_ce020 (6);
+                       genamode (NULL, Aipi, "7", sz_long, "old", 1, 0, 0);
                        fill_prefetch_next ();
                        genastore ("old", curi->smode, "srcreg", curi->size, "src");
                }
                break;
        case i_RTS:
                printf ("\tuaecptr pc = m68k_getpc ();\n");
-               addcycles_ce020 (10);
                if (using_ce020 == 1)
                        printf ("\tm68k_do_rts_ce020 ();\n");
                else if (using_ce020 == 2)
@@ -2773,10 +3219,12 @@ static void gen_opcode (unsigned long int opcode)
                printf ("\t\tuaecptr faultpc = m68k_getpc ();\n");
                setpc ("pc");
                printf ("\t\texception3i (0x%04X, faultpc);\n", opcode);
+               printf ("\t\tgoto %s;\n", endlabelstr);
                printf ("\t}\n");
                count_read += 2;
                m68k_pc_offset = 0;
                fill_prefetch_full ();
+           need_endlabel = 1;
                break;
        case i_TRAPV:
                sync_m68k_pc ();
@@ -2790,9 +3238,8 @@ static void gen_opcode (unsigned long int opcode)
        case i_RTR:
                printf ("\tuaecptr oldpc = m68k_getpc ();\n");
                printf ("\tMakeSR ();\n");
-               genamode (Aipi, "7", sz_word, "sr", 1, 0, 0);
-               genamode (Aipi, "7", sz_long, "pc", 1, 0, 0);
-               addcycles_ce020 (10);
+               genamode (NULL, Aipi, "7", sz_word, "sr", 1, 0, 0);
+               genamode (NULL, Aipi, "7", sz_long, "pc", 1, 0, 0);
                printf ("\tregs.sr &= 0xFF00; sr &= 0xFF;\n");
                printf ("\tregs.sr |= sr;\n");
                setpc ("pc");
@@ -2801,14 +3248,15 @@ static void gen_opcode (unsigned long int opcode)
                printf ("\t\tuaecptr faultpc = m68k_getpc ();\n");
                setpc ("oldpc");
                printf ("\t\texception3i (0x%04X, faultpc);\n", opcode);
+               printf ("\t\tgoto %s;\n", endlabelstr);
                printf ("\t}\n");
                m68k_pc_offset = 0;
                fill_prefetch_full ();
+           need_endlabel = 1;
                break;
        case i_JSR: // TODO: check stack write order
-               genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA|GF_NOREFILL);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA|GF_NOREFILL);
                start_brace ();
-               addcycles_ce020 (5);
                printf ("\tuaecptr oldpc = m68k_getpc () + %d;\n", m68k_pc_offset);
                if (using_exception_3) {
                        printf ("\tif (srca & 1) {\n");
@@ -2843,7 +3291,7 @@ static void gen_opcode (unsigned long int opcode)
                fill_prefetch_next ();
                break;
        case i_JMP:
-               genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA | ((curi->smode == Ad8r || curi->smode == PC8r) ? 0 : GF_NOREFILL));
+               genamode (curi, 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, srca);\n");
@@ -2851,7 +3299,6 @@ static void gen_opcode (unsigned long int opcode)
                        printf ("\t}\n");
                        need_endlabel = 1;
                }
-               addcycles_ce020 (4);
                if (curi->smode == Ad16 || curi->smode == Ad8r || curi->smode == absw || curi->smode == PC16 || curi->smode == PC8r)
                        addcycles000 (2);
                setpc ("srca");
@@ -2868,7 +3315,7 @@ static void gen_opcode (unsigned long int opcode)
                if (curi->size == sz_long && cpu_level < 2) {
                        printf ("\tuae_u32 src = 0xffffffff;\n");
                } else {
-                       genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA|GF_NOREFILL);
+                       genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA|GF_NOREFILL);
                }
                printf ("\ts = (uae_s32)src + 2;\n");
                if (using_exception_3) {
@@ -2879,7 +3326,6 @@ static void gen_opcode (unsigned long int opcode)
                        need_endlabel = 1;
                }
                addcycles000 (2);
-               addcycles_ce020 (7);
                if (using_ce020 == 1) {
                        printf ("\tm68k_do_bsr_ce020 (m68k_getpc () + %d, s);\n", m68k_pc_offset);
                } else if (using_ce020 == 2) {
@@ -2915,7 +3361,7 @@ static void gen_opcode (unsigned long int opcode)
                                        next_cpu_level = 1;
                        }
                }
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_NOREFILL);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_NOREFILL);
                addcycles000 (2);
                printf ("\tif (!cctrue (%d)) goto didnt_jump;\n", curi->cc);
                if (using_exception_3) {
@@ -2957,20 +3403,21 @@ static void gen_opcode (unsigned long int opcode)
                insn_n_cycles = curi->size == sz_byte ? 8 : 12;
                break;
        case i_LEA:
-               genamode (curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA);
-               genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, GF_AA);
+               genamodedual (curi,
+                       curi->smode, "srcreg", curi->size, "src", 0, GF_AA,
+                       curi->dmode, "dstreg", curi->size, "dst", 2, GF_AA);
+               //genamode (curi, curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA);
+               //genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, GF_AA);
                if (curi->smode == Ad8r || curi->smode == PC8r)
                        addcycles000 (2);
                fill_prefetch_next ();
                if (curi->smode == Ad8r || curi->smode == PC8r)
                        addcycles000 (2);
-               addcycles_ce020 (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);
-               addcycles_ce020 (5);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 0, 0, GF_AA);
+               genamode (NULL, Apdi, "7", sz_long, "dst", 2, 0, GF_AA);
                if (curi->smode == Ad8r || curi->smode == PC8r)
                        addcycles000 (2);
                if (!(curi->smode == absw || curi->smode == absl))
@@ -2982,8 +3429,8 @@ static void gen_opcode (unsigned long int opcode)
                        fill_prefetch_next ();
                break;
        case i_DBcc:
-               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);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_AA | GF_NOREFILL);
+               genamode (curi, curi->dmode, "dstreg", curi->size, "offs", 1, 0, GF_AA | GF_NOREFILL);
                printf ("\tuaecptr oldpc = m68k_getpc ();\n");
                addcycles000 (2);
                printf ("\tif (!cctrue (%d)) {\n", curi->cc);
@@ -3023,10 +3470,9 @@ static void gen_opcode (unsigned long int opcode)
                break;
        case i_Scc:
                // confirmed
-               genamode (curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0);
                start_brace ();
                fill_prefetch_next();
-               addcycles_ce020 (isreg (curi->smode) ? 4 : 6);
                start_brace ();
                printf ("\tint val = cctrue (%d) ? 0xff : 0;\n", curi->cc);
                if (using_ce) {
@@ -3038,8 +3484,9 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("val", curi->smode, "srcreg", curi->size, "src");
                break;
        case i_DIVU:
-               genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
+               genamodedual (curi,
+                       curi->smode, "srcreg", sz_word, "src", 1, 0,
+                       curi->dmode, "dstreg", sz_long, "dst", 1, 0);
                printf ("\tCLEAR_CZNV ();\n");
                printf ("\tif (src == 0) {\n");
                if (cpu_level > 0)
@@ -3055,11 +3502,9 @@ static void gen_opcode (unsigned long int opcode)
                        start_brace ();
                        printf ("\t\tint cycles = (getDivu68kCycles((uae_u32)dst, (uae_u16)src));\n");
                        addcycles000_3 ("\t\t");
-               } else if (using_ce020) {
-                       addcycles_ce020 (44);
                }
                /* The N flag appears to be set each time there is an overflow.
-               * Weird. but 68020 only sets N when dst is negative.. */
+                * Weird. but 68020 only sets N when dst is negative.. */
                printf ("\t\tif (newv > 0xffff) {\n");
                printf ("\t\t\tSET_VFLG (1);\n");
 #ifdef UNDEF68020
@@ -3080,8 +3525,9 @@ static void gen_opcode (unsigned long int opcode)
                need_endlabel = 1;
                break;
        case i_DIVS:
-               genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", sz_long, "dst", 1, 0, 0);
+               genamodedual (curi,
+                       curi->smode, "srcreg", sz_word, "src", 1, 0,
+                       curi->dmode, "dstreg", sz_long, "dst", 1, 0);
                printf ("\tif (src == 0) {\n");
                if (cpu_level > 0)
                        printf ("\t\tdivbyzero_special (1, dst);\n");
@@ -3095,8 +3541,6 @@ static void gen_opcode (unsigned long int opcode)
                        start_brace ();
                        printf ("\t\tint cycles = (getDivs68kCycles((uae_s32)dst, (uae_s16)src));\n");
                        addcycles000_3 ("\t\t");
-               } else if (using_ce020) {
-                       addcycles_ce020 (56);
                }
                printf ("\tif (dst == 0x80000000 && src == -1) {\n");
                printf ("\t\tSET_VFLG (1);\n");
@@ -3125,8 +3569,9 @@ static void gen_opcode (unsigned long int opcode)
                need_endlabel = 1;
                break;
        case i_MULU:
-               genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0, 0);
+               genamodedual (curi,
+                       curi->smode, "srcreg", sz_word, "src", 1, 0,
+                       curi->dmode, "dstreg", sz_word, "dst", 1, 0);
                fill_prefetch_next();
                start_brace ();
                printf ("\tuae_u32 newv = (uae_u32)(uae_u16)dst * (uae_u32)(uae_u16)src;\n");
@@ -3137,8 +3582,6 @@ static void gen_opcode (unsigned long int opcode)
                        printf ("\tfor(bits = 0; bits < 16 && src; bits++, src >>= 1)\n");
                        printf ("\t\tif (src & 1) cycles += 2;\n");
                        addcycles000_3 ("\t");
-               } else if (using_ce020) {
-                       addcycles_ce020 (27);
                }
                genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
                sync_m68k_pc ();
@@ -3147,8 +3590,9 @@ static void gen_opcode (unsigned long int opcode)
                insn_n_cycles += (70 - 38) / 2 + 38; /* average */
                break;
        case i_MULS:
-               genamode (curi->smode, "srcreg", sz_word, "src", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", sz_word, "dst", 1, 0, 0);
+               genamodedual (curi,
+                       curi->smode, "srcreg", sz_word, "src", 1, 0,
+                       curi->dmode, "dstreg", sz_word, "dst", 1, 0);
                fill_prefetch_next();
                start_brace ();
                printf ("\tuae_u32 newv = (uae_s32)(uae_s16)dst * (uae_s32)(uae_s16)src;\n");
@@ -3162,8 +3606,6 @@ static void gen_opcode (unsigned long int opcode)
                        printf ("\tfor(bits = 0; bits < 16 && usrc; bits++, usrc >>= 1)\n");
                        printf ("\t\tif ((usrc & 3) == 1 || (usrc & 3) == 2) cycles += 2;\n");
                        addcycles000_3 ("\t");
-               } else if (using_ce020) {
-                       addcycles_ce020 (27);
                }
                genastore ("newv", curi->dmode, "dstreg", sz_long, "dst");
                count_cycles += 38 - 4;
@@ -3171,8 +3613,8 @@ static void gen_opcode (unsigned long int opcode)
                insn_n_cycles += (70 - 38) / 2 + 38; /* average */
                break;
        case i_CHK:
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
                sync_m68k_pc ();
                addcycles000 (4);
                printf ("\tif (dst > src) {\n");
@@ -3190,8 +3632,8 @@ static void gen_opcode (unsigned long int opcode)
                need_endlabel = 1;
                break;
        case i_CHK2:
-               genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
+               genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
+               genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
                fill_prefetch_0 ();
                printf ("\t{uae_s32 upper,lower,reg = regs.regs[(extra >> 12) & 15];\n");
                switch (curi->size) {
@@ -3207,7 +3649,7 @@ static void gen_opcode (unsigned long int opcode)
                        printf ("\tlower = %s (dsta); upper = %s (dsta + 4);\n", srcl, srcl);
                        break;
                default:
-                       abort ();
+                       term ();
                }
                printf ("\tSET_ZFLG (upper == reg || lower == reg);\n");
                printf ("\tSET_CFLG_ALWAYS (lower <= upper ? reg < lower || reg > upper : reg > upper || reg < lower);\n");
@@ -3216,16 +3658,18 @@ static void gen_opcode (unsigned long int opcode)
                break;
 
        case i_ASR:
-               genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
-               addcycles_ce020 (6);
+               genamodedual (curi,
+                       curi->smode, "srcreg", curi->size, "cnt", 1, 0,
+                       curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
+               //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
+               //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
                fill_prefetch_next();
                start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
-               default: abort ();
+               default: term ();
                }
                printf ("\tuae_u32 sign = (%s & val) >> %d;\n", cmask (curi->size), bit_size (curi->size) - 1);
                printf ("\tint ccnt = cnt & 63;\n");
@@ -3253,16 +3697,18 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("val", curi->dmode, "dstreg", curi->size, "data");
                break;
        case i_ASL:
-               genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
-               addcycles_ce020 (8);
+               genamodedual (curi,
+                       curi->smode, "srcreg", curi->size, "cnt", 1, 0,
+                       curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
+               //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
+               //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
                fill_prefetch_next();
                start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
-               default: abort ();
+               default: term ();
                }
                printf ("\tint ccnt = cnt & 63;\n");
                printf ("\tcnt &= 63;\n");
@@ -3293,16 +3739,18 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("val", curi->dmode, "dstreg", curi->size, "data");
                break;
        case i_LSR:
-               genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
-               addcycles_ce020 (source_is_imm1_8 (curi) ? 4 : 6);
+               genamodedual (curi,
+                       curi->smode, "srcreg", curi->size, "cnt", 1, 0,
+                       curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
+               //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
+               //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
                fill_prefetch_next();
                start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
-               default: abort ();
+               default: term ();
                }
                printf ("\tint ccnt = cnt & 63;\n");
                printf ("\tcnt &= 63;\n");
@@ -3326,16 +3774,18 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("val", curi->dmode, "dstreg", curi->size, "data");
                break;
        case i_LSL:
-               genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
-               addcycles_ce020 (source_is_imm1_8 (curi) ? 4 : 6);
+               genamodedual (curi,
+                       curi->smode, "srcreg", curi->size, "cnt", 1, 0,
+                       curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
+               //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
+               //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
                fill_prefetch_next();
                start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
-               default: abort ();
+               default: term ();
                }
                printf ("\tint ccnt = cnt & 63;\n");
                printf ("\tcnt &= 63;\n");
@@ -3359,16 +3809,18 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("val", curi->dmode, "dstreg", curi->size, "data");
                break;
        case i_ROL:
-               genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
-               addcycles_ce020 (8);
+               genamodedual (curi,
+                       curi->smode, "srcreg", curi->size, "cnt", 1, 0,
+                       curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
+               //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
+               //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
                fill_prefetch_next ();
                start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
-               default: abort ();
+               default: term ();
                }
                printf ("\tint ccnt = cnt & 63;\n");
                printf ("\tcnt &= 63;\n");
@@ -3390,16 +3842,18 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("val", curi->dmode, "dstreg", curi->size, "data");
                break;
        case i_ROR:
-               genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
-               addcycles_ce020 (8);
+               genamodedual (curi,
+                       curi->smode, "srcreg", curi->size, "cnt", 1, 0,
+                       curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
+               //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
+               //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
                fill_prefetch_next ();
                start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
-               default: abort ();
+               default: term ();
                }
                printf ("\tint ccnt = cnt & 63;\n");
                printf ("\tcnt &= 63;\n");
@@ -3421,16 +3875,18 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("val", curi->dmode, "dstreg", curi->size, "data");
                break;
        case i_ROXL:
-               genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
-               addcycles_ce020 (12);
+               genamodedual (curi,
+                       curi->smode, "srcreg", curi->size, "cnt", 1, 0,
+                       curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
+               //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
+               //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
                fill_prefetch_next ();
                start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
-               default: abort ();
+               default: term ();
                }
                printf ("\tint ccnt = cnt & 63;\n");
                printf ("\tcnt &= 63;\n");
@@ -3455,16 +3911,18 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("val", curi->dmode, "dstreg", curi->size, "data");
                break;
        case i_ROXR:
-               genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
-               genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
-               addcycles_ce020 (12);
+               genamodedual (curi,
+                       curi->smode, "srcreg", curi->size, "cnt", 1, 0,
+                       curi->dmode, "dstreg", curi->size, "data", 1, GF_RMW);
+               //genamode (curi, curi->smode, "srcreg", curi->size, "cnt", 1, 0, 0);
+               //genamode (curi, curi->dmode, "dstreg", curi->size, "data", 1, 0, GF_RMW);
                fill_prefetch_next ();
                start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
-               default: abort ();
+               default: term ();
                }
                printf ("\tint ccnt = cnt & 63;\n");
                printf ("\tcnt &= 63;\n");
@@ -3492,15 +3950,14 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("val", curi->dmode, "dstreg", curi->size, "data");
                break;
        case i_ASRW:
-               genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
-               addcycles_ce020 (5);
+               genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
                fill_prefetch_next ();
                start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
-               default: abort ();
+               default: term ();
                }
                printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size));
                printf ("\tuae_u32 cflg = val & 1;\n");
@@ -3511,15 +3968,14 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("val", curi->smode, "srcreg", curi->size, "data");
                break;
        case i_ASLW:
-               genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
-               addcycles_ce020 (6);
+               genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
                fill_prefetch_next ();
                start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
-               default: abort ();
+               default: term ();
                }
                printf ("\tuae_u32 sign = %s & val;\n", cmask (curi->size));
                printf ("\tuae_u32 sign2;\n");
@@ -3532,15 +3988,14 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("val", curi->smode, "srcreg", curi->size, "data");
                break;
        case i_LSRW:
-               genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
-               addcycles_ce020 (5);
+               genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
                fill_prefetch_next ();
                start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u32 val = (uae_u8)data;\n"); break;
                case sz_word: printf ("\tuae_u32 val = (uae_u16)data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
-               default: abort ();
+               default: term ();
                }
                printf ("\tuae_u32 carry = val & 1;\n");
                printf ("\tval >>= 1;\n");
@@ -3550,15 +4005,14 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("val", curi->smode, "srcreg", curi->size, "data");
                break;
        case i_LSLW:
-               genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
-               addcycles_ce020 (5);
+               genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
                fill_prefetch_next ();
                start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
-               default: abort ();
+               default: term ();
                }
                printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size));
                printf ("\tval <<= 1;\n");
@@ -3568,15 +4022,14 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("val", curi->smode, "srcreg", curi->size, "data");
                break;
        case i_ROLW:
-               genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
-               addcycles_ce020 (7);
+               genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
                fill_prefetch_next ();
                start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
-               default: abort ();
+               default: term ();
                }
                printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size));
                printf ("\tval <<= 1;\n");
@@ -3586,15 +4039,14 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("val", curi->smode, "srcreg", curi->size, "data");
                break;
        case i_RORW:
-               genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
-               addcycles_ce020 (7);
+               genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
                fill_prefetch_next ();
                start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
-               default: abort ();
+               default: term ();
                }
                printf ("\tuae_u32 carry = val & 1;\n");
                printf ("\tval >>= 1;\n");
@@ -3604,15 +4056,14 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("val", curi->smode, "srcreg", curi->size, "data");
                break;
        case i_ROXLW:
-               genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
-               addcycles_ce020 (5);
+               genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
                fill_prefetch_next ();
                start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
-               default: abort ();
+               default: term ();
                }
                printf ("\tuae_u32 carry = val & %s;\n", cmask (curi->size));
                printf ("\tval <<= 1;\n");
@@ -3623,15 +4074,14 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("val", curi->smode, "srcreg", curi->size, "data");
                break;
        case i_ROXRW:
-               genamode (curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
-               addcycles_ce020 (5);
+               genamode (curi, curi->smode, "srcreg", curi->size, "data", 1, 0, GF_RMW);
                fill_prefetch_next ();
                start_brace ();
                switch (curi->size) {
                case sz_byte: printf ("\tuae_u8 val = data;\n"); break;
                case sz_word: printf ("\tuae_u16 val = data;\n"); break;
                case sz_long: printf ("\tuae_u32 val = data;\n"); break;
-               default: abort ();
+               default: term ();
                }
                printf ("\tuae_u32 carry = val & 1;\n");
                printf ("\tval >>= 1;\n");
@@ -3642,18 +4092,16 @@ static void gen_opcode (unsigned long int opcode)
                genastore ("val", curi->smode, "srcreg", curi->size, "data");
                break;
        case i_MOVEC2:
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                fill_prefetch_next ();
-               addcycles_ce020 (6);
                start_brace ();
                printf ("\tint regno = (src >> 12) & 15;\n");
                printf ("\tuae_u32 *regp = regs.regs + regno;\n");
                printf ("\tif (! m68k_movec2(src & 0xFFF, regp)) goto %s;\n", endlabelstr);
                break;
        case i_MOVE2C:
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
                fill_prefetch_next ();
-               addcycles_ce020 (12);
                start_brace ();
                printf ("\tint regno = (src >> 12) & 15;\n");
                printf ("\tuae_u32 *regp = regs.regs + regno;\n");
@@ -3662,8 +4110,8 @@ static void gen_opcode (unsigned long int opcode)
        case i_CAS:
                {
                        int old_brace_level;
-                       genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_LRMW);
-                       genamode (curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_LRMW);
+                       genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_LRMW);
+                       genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, GF_LRMW);
                        if (cpu_level == 5 && curi->size > 0) {
                                printf ("\tif ((dsta & %d) && currprefs.int_no_unimplemented && get_cpu_model () == 68060) {\n", curi->size == 1 ? 1 : 3);
                                if (curi->dmode == Aipi || curi->dmode == Apdi)
@@ -3710,7 +4158,7 @@ static void gen_opcode (unsigned long int opcode)
                }
                break;
        case i_CAS2:
-               genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, GF_LRMW);
+               genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, GF_LRMW);
                printf ("\tuae_u32 rn1 = regs.regs[(extra >> 28) & 15];\n");
                printf ("\tuae_u32 rn2 = regs.regs[(extra >> 12) & 15];\n");
                if (curi->size == sz_word) {
@@ -3748,14 +4196,14 @@ static void gen_opcode (unsigned long int opcode)
        case i_MOVES: /* ignore DFC and SFC when using_mmu == false */
                {
                        int old_brace_level;
-                       genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
+                       genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
                        printf ("\tif (extra & 0x800)\n");
                        {
                                int old_m68k_pc_offset = m68k_pc_offset;
                                old_brace_level = n_braces;
                                start_brace ();
                                printf ("\tuae_u32 src = regs.regs[(extra >> 12) & 15];\n");
-                               genamode (curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
+                               genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, 0);
                                genastore_fc ("src", curi->dmode, "dstreg", curi->size, "dst");
                                pop_braces (old_brace_level);
                                m68k_pc_offset = old_m68k_pc_offset;
@@ -3763,13 +4211,13 @@ static void gen_opcode (unsigned long int opcode)
                        printf ("else");
                        {
                                start_brace ();
-                               genamode (curi->dmode, "dstreg", curi->size, "src", 1, 0, GF_FC);
+                               genamode (curi, curi->dmode, "dstreg", curi->size, "src", 1, 0, GF_FC);
                                printf ("\tif (extra & 0x8000) {\n");
                                switch (curi->size) {
                                case sz_byte: printf ("\tm68k_areg (regs, (extra >> 12) & 7) = (uae_s32)(uae_s8)src;\n"); break;
                                case sz_word: printf ("\tm68k_areg (regs, (extra >> 12) & 7) = (uae_s32)(uae_s16)src;\n"); break;
                                case sz_long: printf ("\tm68k_areg (regs, (extra >> 12) & 7) = src;\n"); break;
-                               default: abort ();
+                               default: term ();
                                }
                                printf ("\t} else {\n");
                                genastore ("src", Dreg, "(extra >> 12) & 7", curi->size, "");
@@ -3794,26 +4242,20 @@ static void gen_opcode (unsigned long int opcode)
                break;
        case i_TRAPcc:
                if (curi->smode != am_unknown && curi->smode != am_illg)
-                       genamode (curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0);
+                       genamode (curi, curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0);
                fill_prefetch_0 ();
                printf ("\tif (cctrue (%d)) { Exception (7); goto %s; }\n", curi->cc, endlabelstr);
                need_endlabel = 1;
                break;
        case i_DIVL:
-               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 / 3);
-               }
+               genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
+               genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
                sync_m68k_pc ();
                printf ("\tm68k_divl(opcode, dst, extra);\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 / 3);
-               }
+               genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
+               genamode (curi, curi->dmode, "dstreg", curi->size, "dst", 1, 0, 0);
                sync_m68k_pc ();
                printf ("\tm68k_mull(opcode, dst, extra);\n");
                break;
@@ -3840,8 +4282,8 @@ static void gen_opcode (unsigned long int opcode)
                                putb = "put_bitfield";
                        }
 
-                       genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
-                       genamode (curi->dmode, "dstreg", sz_long, "dst", 2, 0, 0);
+                       genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
+                       genamode (curi, curi->dmode, "dstreg", sz_long, "dst", 2, 0, 0);
                        start_brace ();
                        printf ("\tuae_u32 bdata[2];\n");
                        printf ("\tuae_s32 offset = extra & 0x800 ? m68k_dreg(regs, (extra >> 6) & 7) : (extra >> 6) & 0x1f;\n");
@@ -3948,11 +4390,10 @@ static void gen_opcode (unsigned long int opcode)
                }
                break;
        case i_TAS:
-               genamode (curi->smode, "srcreg", curi->size, "src", 1, 0, GF_LRMW);
+               genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_LRMW);
                genflags (flag_logical, curi->size, "src", "", "");
                if (!isreg (curi->smode))
                        addcycles000 (2);
-               addcycles_ce020 (isreg (curi->smode) ? 4 : 12);
                fill_prefetch_next ();
                printf ("\tsrc |= 0x80;\n");
                if (cpu_level >= 2 || curi->smode == Dreg || !using_ce) {
@@ -3969,19 +4410,19 @@ static void gen_opcode (unsigned long int opcode)
                break;
        case i_FPP:
                fpulimit();
-               genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
+               genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
                sync_m68k_pc ();
                printf ("\tfpuop_arithmetic(opcode, extra);\n");
                break;
        case i_FDBcc:
                fpulimit();
-               genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
+               genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
                sync_m68k_pc ();
                printf ("\tfpuop_dbcc (opcode, extra);\n");
                break;
        case i_FScc:
                fpulimit();
-               genamode (curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
+               genamode (curi, curi->smode, "srcreg", curi->size, "extra", 1, 0, 0);
                sync_m68k_pc ();
                printf ("\tfpuop_scc (opcode, extra);\n");
                break;
@@ -3990,7 +4431,7 @@ static void gen_opcode (unsigned long int opcode)
                printf ("\tuaecptr oldpc = m68k_getpc ();\n");
                printf ("\tuae_u16 extra = %s;\n", gen_nextiword (0));
                if (curi->smode != am_unknown && curi->smode != am_illg)
-                       genamode (curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0);
+                       genamode (curi, curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0);
                sync_m68k_pc ();
                printf ("\tfpuop_trapcc (opcode, oldpc, extra);\n");
                break;
@@ -3999,7 +4440,7 @@ static void gen_opcode (unsigned long int opcode)
                sync_m68k_pc ();
                start_brace ();
                printf ("\tuaecptr pc = m68k_getpc ();\n");
-               genamode (curi->dmode, "srcreg", curi->size, "extra", 1, 0, 0);
+               genamode (curi, curi->dmode, "srcreg", curi->size, "extra", 1, 0, 0);
                sync_m68k_pc ();
                printf ("\tfpuop_bcc (opcode, pc,extra);\n");
                break;
@@ -4053,8 +4494,8 @@ static void gen_opcode (unsigned long int opcode)
                        } else {
                                /* Other variants */
                                printf ("\tuae_u32 v[4];\n");
-                               genamode (curi->smode, "srcreg", curi->size, "mems", 0, 2, 0);
-                               genamode (curi->dmode, "dstreg", curi->size, "memd", 0, 2, 0);
+                               genamode (curi, curi->smode, "srcreg", curi->size, "mems", 0, 2, 0);
+                               genamode (curi, curi->dmode, "dstreg", curi->size, "memd", 0, 2, 0);
                                printf ("\tmemsa &= ~15;\n");
                                printf ("\tmemda &= ~15;\n");
                                if (using_mmu >= 68040) {
@@ -4097,12 +4538,12 @@ static void gen_opcode (unsigned long int opcode)
                if (curi->smode == Areg || curi->smode == Dreg)
                        printf("\tuae_u16 extraa = 0;\n");
                else
-                       genamode (curi->smode, "srcreg", curi->size, "extra", 0, 0, 0);
+                       genamode (curi, curi->smode, "srcreg", curi->size, "extra", 0, 0, 0);
                sync_m68k_pc ();
                printf ("\tmmu_op30 (pc, opcode, extra, extraa);\n");
                break;
        default:
-               abort ();
+               term ();
                break;
        }
        finish_braces ();
@@ -4114,8 +4555,6 @@ static void gen_opcode (unsigned long int opcode)
        }
        if (did_prefetch >= 0)
                fill_prefetch_finish ();
-//     if (!count_cycles)
-//             addcycles_ce020 (2);
        sync_m68k_pc ();
        did_prefetch = 0;
 }
@@ -4300,7 +4739,7 @@ static void generate_one_opcode (int rp, char *extra)
        case 4: smsk = 7; break;
        case 5: smsk = 63; break;
        case 7: smsk = 3; break;
-       default: abort ();
+       default: term ();
        }
        dmsk = 7;
 
@@ -4457,6 +4896,7 @@ static void generate_cpu (int id, int mode)
        using_ce = 0;
        using_ce020 = 0;
        using_mmu = 0;
+       using_waitstates = 0;
        mmu_postfix = "";
 
        if (id == 11 || id == 12) { // 11 = 68000 prefetch, 12 = 68000 cycle-exact
@@ -4477,6 +4917,10 @@ static void generate_cpu (int id, int mode)
                cpu_level = 2;
                using_ce020 = 1;
                using_prefetch_020 = 2;
+               // timing tables are from 030 which has 2
+               // clock memory accesses, 68020 has 3 clock
+               // memory accesses
+               using_waitstates = 1;
                read_counts ();
                for (rp = 0; rp < nr_cpuop_funcs; rp++)
                        opcode_next_clev[rp] = cpu_level;
index 633a6ac81576f0a943db73f25c66da51ff55ed43..a03bc4c96d238834a0242f9e9ac713a20dd25f29 100644 (file)
@@ -637,6 +637,7 @@ int is_surface_bgr(DisplaySurface *surface)
 static uaecptr fixaddr_bs (uaecptr addr, int mask, int *bs)
 {
        bool swapped = false;
+       addr &= gfxmem_bank.mask;
        if (p4z2) {
                if (addr < 0x200000) {
                        addr |= p4_vram_bank[0];
index f72c79ad2efe0697747f51105c6841b17e157d53..c5f43c38677f6af19586ec4e81baa1e68872f9b7 100644 (file)
@@ -36,6 +36,7 @@ extern void update_sound (double freq, int longframe, int linetoggle);
 extern void led_filter_audio (void);
 extern void set_audio (void);
 extern int audio_activate (void);
+extern void audio_deactivate (void);
 extern void audio_vsync (void);
 
 extern void audio_sampleripper(int);
index b71c61dbddce34eeb196b967e085af6e9cecdbc6..2284d4c05d72ac2abd5d829791b6c3d86618a24e 100644 (file)
@@ -40,6 +40,14 @@ STATIC_INLINE uae_u32 get_long_020_prefetch (int o)
 
 #ifdef CPUEMU_21
 
+#define CE020_INITCYCLES() \
+       int head = 0, tail = 0, cycles = 0; \
+       unsigned int cu = get_cycles ();
+#define CE020_SAVECYCLES(h,t,c) \
+       head = h; tail = t; cycles = c;
+#define CE020_COUNTCYCLES()
+
+
 STATIC_INLINE void do_cycles_ce020 (int clocks)
 {
        x_do_cycles (clocks * cpucycleunit);
index 8f647a2d3b90f9b1452e34eb5e4883592a13f395..6c726d94ef26e064678477911274b2bd00d36519 100644 (file)
@@ -109,6 +109,7 @@ struct cache030
        uae_u32 tag;
 };
 
+#if 0
 #define CACHESETS040 64
 #define CACHELINES040 4
 struct cache040
@@ -117,6 +118,7 @@ struct cache040
        bool valid[CACHELINES040];
        uae_u32 tag[CACHELINES040];
 };
+#endif
 
 struct mmufixup
 {
@@ -183,6 +185,7 @@ struct regstruct
        uae_u32 cacheholdingdata020;
        uae_u32 cacheholdingaddr020;
        int ce020memcycles;
+       int ce020_tail;
 };
 
 extern struct regstruct regs;
@@ -374,6 +377,7 @@ extern void (*x_do_cycles_post)(unsigned long, uae_u32);
 
 extern uae_u32 REGPARAM3 x_get_disp_ea_020 (uae_u32 base, int idx) REGPARAM;
 extern uae_u32 REGPARAM3 x_get_disp_ea_ce020 (uae_u32 base, int idx) REGPARAM;
+extern uae_u32 REGPARAM3 x_get_disp_ea_ce030 (uae_u32 base, int idx) REGPARAM;
 extern uae_u32 REGPARAM3 x_get_bitfield (uae_u32 src, uae_u32 bdata[2], uae_s32 offset, int width) REGPARAM;
 extern void REGPARAM3 x_put_bitfield (uae_u32 dst, uae_u32 bdata[2], uae_u32 val, uae_s32 offset, int width) REGPARAM;
 
@@ -408,6 +412,7 @@ extern void init_m68k_full (void);
 extern void m68k_go (int);
 extern void m68k_dumpstate (uaecptr *);
 extern void m68k_dumpstate (uaecptr, uaecptr *);
+extern void m68k_dumpcache (void);
 extern int getDivu68kCycles (uae_u32 dividend, uae_u16 divisor);
 extern int getDivs68kCycles (uae_s32 dividend, uae_s16 divisor);
 extern void divbyzero_special (bool issigned, uae_s32 dst);
@@ -440,8 +445,6 @@ extern void cpu_halt (int id);
 extern void fill_prefetch (void);
 extern void fill_prefetch_020 (void);
 extern void fill_prefetch_030 (void);
-extern void fill_prefetch_040 (void);
-extern void fill_prefetch_0x0 (void);
 
 #define CPU_OP_NAME(a) op ## a
 
index 58074cc635254d80046964ec0a9f944f46242a8a..3614f57705446f18ffad2e2de6331086bf0e97a6 100644 (file)
@@ -605,6 +605,10 @@ extern struct uaedev_config_data *add_filesys_config (struct uae_prefs *p, int i
 extern bool get_hd_geometry (struct uaedev_config_info *);
 extern void uci_set_defaults (struct uaedev_config_info *uci, bool rdb);
 
+extern void error_log (const TCHAR*, ...);
+extern TCHAR *get_error_log (void);
+extern bool is_error_log (void);
+
 extern void default_prefs (struct uae_prefs *, int);
 extern void discard_prefs (struct uae_prefs *, int);
 
index 871973df667bd8db7a82428fff973c8f61bba733..81f6af1699654dfea936d55256bd7b3bdd1d9aab 100644 (file)
@@ -73,6 +73,8 @@ struct instr_def {
     } flaginfo[5];
     uae_u8 sduse;
     const TCHAR *opcstr;
+       // 68020/030 timing
+       int head, tail, clocks, fetchmode;
 };
 
 extern struct instr_def defs68k[];
@@ -99,6 +101,7 @@ extern struct instr {
     unsigned int clev:3, unimpclev:3;
     unsigned int isjmp:1;
     unsigned int unused2:1;
+       unsigned char head, tail, clocks, fetchmode;
 } *table68k;
 
 extern void read_table68k (void);
index 9d8b186eec7c83ec06911d0be2b5bc778a305891..bfd43cf2890c7df0738f0bf7b2c0e833bd16c0f7 100644 (file)
@@ -141,6 +141,9 @@ extern uae_u8 *save_scsi_dmac (int *len, uae_u8*);
 extern uae_u8 *save_scsi_device (int num, int *len, uae_u8 *dstptr);
 extern uae_u8 *restore_scsi_device (uae_u8 *src);
 
+extern uae_u8 *save_scsidev (int num, int *len, uae_u8 *dstptr);
+extern uae_u8 *restore_scsidev (uae_u8 *src);
+
 extern uae_u8 *restore_filesys (uae_u8 *src);
 extern uae_u8 *save_filesys (int num, int *len);
 extern uae_u8 *restore_filesys_common (uae_u8 *src);
index 71cbc9a0f5087a35e266e95905785e14d7c5c12d..d359f09d5f561fcdb9b7fab66b37d3c0657a4e01 100644 (file)
@@ -15,6 +15,7 @@ struct scsi_data_tape
        int beom;
        bool wp;
        bool nomedia;
+       bool unloaded;
 };
 
 struct scsi_data
index 3ad739e00f15da23ad08eb1f660149af3ff7e544..08f6d3a3c0e00d54c547824c35ba4a1b8531a171 100644 (file)
--- a/main.cpp
+++ b/main.cpp
@@ -148,14 +148,22 @@ void discard_prefs (struct uae_prefs *p, int type)
 
 static void fixup_prefs_dim2 (struct wh *wh)
 {
-       if (wh->width < 160)
+       if (wh->width < 160) {
+               error_log (_T("Width (%d) must be at least 128."), wh->width);
                wh->width = 160;
-       if (wh->height < 128)
+       }
+       if (wh->height < 128) {
+               error_log (_T("Height (%d) must be at least 128."), wh->height);
                wh->height = 128;
-       if (wh->width > max_uae_width)
+       }
+       if (wh->width > max_uae_width) {
+               error_log (_T("Width (%d) must be at least %d."), wh->width, max_uae_width);
                wh->width = max_uae_width;
-       if (wh->height > max_uae_height)
+       }
+       if (wh->height > max_uae_height) {
+               error_log (_T("Height (%d) must be at least %d."), wh->height, max_uae_height);
                wh->height = max_uae_height;
+       }
 }
 
 void fixup_prefs_dimensions (struct uae_prefs *prefs)
@@ -192,40 +200,46 @@ void fixup_prefs_dimensions (struct uae_prefs *prefs)
                }
        }
 
-       if (prefs->gfx_filter == 0 && ((prefs->gfx_filter_autoscale && !prefs->gfx_api) || (prefs->gfx_apmode[0].gfx_vsyncmode)))
+       if (prefs->gfx_filter == 0 && ((prefs->gfx_filter_autoscale && !prefs->gfx_api) || (prefs->gfx_apmode[0].gfx_vsyncmode))) {
                prefs->gfx_filter = 1;
-       if (prefs->gfx_filter == 0 && prefs->monitoremu)
+       }
+       if (prefs->gfx_filter == 0 && prefs->monitoremu) {
+               error_log (_T("A2024 and Graffiti require at least null filter."));
                prefs->gfx_filter = 1;
+       }
 }
 
 void fixup_cpu (struct uae_prefs *p)
 {
        if (p->cpu_frequency == 1000000)
                p->cpu_frequency = 0;
+
+       if (p->cpu_model >= 68030 && p->address_space_24) {
+               error_log (_T("24-bit address space is not supported in 68030/040/060 configurations."));
+               p->address_space_24 = 0;
+       }
+       if (p->cpu_model < 68020 && p->fpu_model && (p->cpu_compatible || p->cpu_cycle_exact)) {
+               error_log (_T("FPU is not supported in 68000/010 configurations."));
+               p->fpu_model = 0;
+       }
+
        switch (p->cpu_model)
        {
        case 68000:
                p->address_space_24 = 1;
-               if (p->cpu_compatible || p->cpu_cycle_exact)
-                       p->fpu_model = 0;
                break;
        case 68010:
                p->address_space_24 = 1;
-               if (p->cpu_compatible || p->cpu_cycle_exact)
-                       p->fpu_model = 0;
                break;
        case 68020:
                break;
        case 68030:
-               p->address_space_24 = 0;
                break;
        case 68040:
-               p->address_space_24 = 0;
                if (p->fpu_model)
                        p->fpu_model = 68040;
                break;
        case 68060:
-               p->address_space_24 = 0;
                if (p->fpu_model)
                        p->fpu_model = 68060;
                break;
@@ -234,23 +248,38 @@ void fixup_cpu (struct uae_prefs *p)
        if (p->cpu_model >= 68040 && p->cachesize && p->cpu_compatible)
                p->cpu_compatible = false;
 
-       if (p->cpu_model < 68030 || p->cachesize)
+       if (p->cpu_model >= 68040 && p->cpu_cycle_exact) {
+               p->cpu_cycle_exact = 0;
+               error_log (_T("68040/060 cycle-exact is not supported."));
+       }
+
+       if ((p->cpu_model < 68030 || p->cachesize) && p->mmu_model) {
+               error_log (_T("MMU emulation requires 68030/040/060 and it is not JIT compatible."));
                p->mmu_model = 0;
+       }
 
-       if (p->cachesize && p->cpu_cycle_exact)
+       if (p->cachesize && p->cpu_cycle_exact) {
+               error_log (_T("JIT and cycle-exact can't be enabled simultaneously."));
                p->cachesize = 0;
+       }
+       if (p->cachesize && (p->fpu_no_unimplemented || p->int_no_unimplemented)) {
+               error_log (_T("JIT is not compatible with unimplemented CPU/FPU instruction emulation."));
+               p->fpu_no_unimplemented = p->int_no_unimplemented = false;
+       }
 
        if (p->cpu_cycle_exact && p->m68k_speed < 0)
                p->m68k_speed = 0;
 
-       if (p->immediate_blits && p->blitter_cycle_exact)
+       if (p->immediate_blits && p->blitter_cycle_exact) {
+               error_log (_T("Cycle-exact and immediate blitter can't be enabled simultaneously.\n"));
                p->immediate_blits = false;
-       if (p->immediate_blits && p->waiting_blits)
+       }
+       if (p->immediate_blits && p->waiting_blits) {
+               error_log (_T("Immediate blitter and waiting blits can't be enabled simultaneously.\n"));
                p->waiting_blits = 0;
+       }
 }
 
-
-
 void fixup_prefs (struct uae_prefs *p)
 {
        int err = 0;
@@ -262,20 +291,20 @@ void fixup_prefs (struct uae_prefs *p)
                || p->chipmem_size < 0x20000
                || p->chipmem_size > 0x800000)
        {
-               write_log (_T("Unsupported chipmem size %x!\n"), p->chipmem_size);
+               error_log (_T("Unsupported chipmem size %x."), p->chipmem_size);
                p->chipmem_size = 0x200000;
                err = 1;
        }
        if ((p->fastmem_size & (p->fastmem_size - 1)) != 0
                || (p->fastmem_size != 0 && (p->fastmem_size < 0x100000 || p->fastmem_size > 0x800000)))
        {
-               write_log (_T("Unsupported fastmem size %x!\n"), p->fastmem_size);
+               error_log (_T("Unsupported fastmem size %x."), p->fastmem_size);
                err = 1;
        }
        if ((p->rtgmem_size & (p->rtgmem_size - 1)) != 0
                || (p->rtgmem_size != 0 && (p->rtgmem_size < 0x100000 || (p->rtgmem_size > max_z3fastmem && p->rtgmem_type == GFXBOARD_UAE_Z3))))
        {
-               write_log (_T("Unsupported graphics card memory size %x (%x)!\n"), p->rtgmem_size, max_z3fastmem);
+               error_log (_T("Unsupported graphics card memory size %x (%x)."), p->rtgmem_size, max_z3fastmem);
                if (p->rtgmem_size > max_z3fastmem)
                        p->rtgmem_size = max_z3fastmem;
                else
@@ -286,7 +315,7 @@ void fixup_prefs (struct uae_prefs *p)
        if ((p->z3fastmem_size & (p->z3fastmem_size - 1)) != 0
                || (p->z3fastmem_size != 0 && (p->z3fastmem_size < 0x100000 || p->z3fastmem_size > max_z3fastmem)))
        {
-               write_log (_T("Unsupported Zorro III fastmem size %x (%x)!\n"), p->z3fastmem_size, max_z3fastmem);
+               error_log (_T("Unsupported Zorro III fastmem size %x (%x)."), p->z3fastmem_size, max_z3fastmem);
                if (p->z3fastmem_size > max_z3fastmem)
                        p->z3fastmem_size = max_z3fastmem;
                else
@@ -296,7 +325,7 @@ void fixup_prefs (struct uae_prefs *p)
        if ((p->z3fastmem2_size & (p->z3fastmem2_size - 1)) != 0
                || (p->z3fastmem2_size != 0 && (p->z3fastmem2_size < 0x100000 || p->z3fastmem2_size > max_z3fastmem)))
        {
-               write_log (_T("Unsupported Zorro III fastmem size %x (%x)!\n"), p->z3fastmem2_size, max_z3fastmem);
+               error_log (_T("Unsupported Zorro III fastmem size %x (%x)."), p->z3fastmem2_size, max_z3fastmem);
                if (p->z3fastmem2_size > max_z3fastmem)
                        p->z3fastmem2_size = max_z3fastmem;
                else
@@ -309,7 +338,7 @@ void fixup_prefs (struct uae_prefs *p)
        if ((p->z3chipmem_size & (p->z3chipmem_size - 1)) != 0
                || (p->z3chipmem_size != 0 && (p->z3chipmem_size < 0x100000 || p->z3chipmem_size > max_z3fastmem)))
        {
-               write_log (_T("Unsupported Zorro III fake chipmem size %x (%x)!\n"), p->z3chipmem_size, max_z3fastmem);
+               error_log (_T("Unsupported Zorro III fake chipmem size %x (%x)."), p->z3chipmem_size, max_z3fastmem);
                if (p->z3chipmem_size > max_z3fastmem)
                        p->z3chipmem_size = max_z3fastmem;
                else
@@ -319,29 +348,29 @@ void fixup_prefs (struct uae_prefs *p)
 
        if (p->address_space_24 && (p->z3fastmem_size != 0 || p->z3fastmem2_size != 0 || p->z3chipmem_size != 0)) {
                p->z3fastmem_size = p->z3fastmem2_size = p->z3chipmem_size = 0;
-               write_log (_T("Can't use a graphics card or 32-bit memory when using a 24 bit\naddress space.\n"));
+               error_log (_T("Can't use a Z3 graphics card or 32-bit memory when using a 24 bit address space."));
        }
        if (p->bogomem_size != 0 && p->bogomem_size != 0x80000 && p->bogomem_size != 0x100000 && p->bogomem_size != 0x180000 && p->bogomem_size != 0x1c0000) {
+               error_log (_T("Unsupported bogomem size %x"), p->bogomem_size);
                p->bogomem_size = 0;
-               write_log (_T("Unsupported bogomem size!\n"));
                err = 1;
        }
        if (p->bogomem_size > 0x180000 && (p->cs_fatgaryrev >= 0 || p->cs_ide || p->cs_ramseyrev >= 0)) {
                p->bogomem_size = 0x180000;
-               write_log (_T("Possible Gayle bogomem conflict fixed\n"));
+               error_log (_T("Possible Gayle bogomem conflict fixed."));
        }
        if (p->chipmem_size > 0x200000 && p->fastmem_size != 0) {
-               write_log (_T("You can't use fastmem and more than 2MB chip at the same time!\n"));
+               error_log (_T("You can't use fastmem and more than 2MB chip at the same time."));
                p->fastmem_size = 0;
                err = 1;
        }
        if (p->mbresmem_low_size > 0x04000000 || (p->mbresmem_low_size & 0xfffff)) {
                p->mbresmem_low_size = 0;
-               write_log (_T("Unsupported A3000 MB RAM size\n"));
+               error_log (_T("Unsupported A3000 MB RAM size"));
        }
-       if (p->mbresmem_high_size > 0x04000000 || (p->mbresmem_high_size & 0xfffff)) {
+       if (p->mbresmem_high_size > 0x08000000 || (p->mbresmem_high_size & 0xfffff)) {
                p->mbresmem_high_size = 0;
-               write_log (_T("Unsupported Motherboard RAM size\n"));
+               error_log (_T("Unsupported Motherboard RAM size."));
        }
 
        if (p->rtgmem_type >= GFXBOARD_HARDWARE) {
@@ -350,13 +379,16 @@ void fixup_prefs (struct uae_prefs *p)
                if (p->address_space_24 && gfxboard_is_z3 (p->rtgmem_type)) {
                        p->rtgmem_type = GFXBOARD_UAE_Z2;
                        p->rtgmem_size = 0;
+                       error_log (_T("Z3 RTG and 24-bit address space are not compatible."));
                }
        }
-       if (p->address_space_24 && p->rtgmem_size && p->rtgmem_type == GFXBOARD_UAE_Z3)
+       if (p->address_space_24 && p->rtgmem_size && p->rtgmem_type == GFXBOARD_UAE_Z3) {
+               error_log (_T("Z3 RTG and 24bit address space are not compatible."));
                p->rtgmem_type = GFXBOARD_UAE_Z2;
+       }
        if (p->rtgmem_type == GFXBOARD_UAE_Z2 && (p->chipmem_size > 2 * 1024 * 1024 || getz2size (p) > 8 * 1024 * 1024 || getz2size (p) < 0)) {
                p->rtgmem_size = 0;
-               write_log (_T("Too large Z2 RTG memory size\n"));
+               error_log (_T("Too large Z2 RTG memory size."));
        }
 
 #if 0
@@ -368,44 +400,42 @@ void fixup_prefs (struct uae_prefs *p)
 #endif
 
        if (p->produce_sound < 0 || p->produce_sound > 3) {
-               write_log (_T("Bad value for -S parameter: enable value must be within 0..3\n"));
+               error_log (_T("Bad value for -S parameter: enable value must be within 0..3."));
                p->produce_sound = 0;
                err = 1;
        }
        if (p->comptrustbyte < 0 || p->comptrustbyte > 3) {
-               write_log (_T("Bad value for comptrustbyte parameter: value must be within 0..2\n"));
+               error_log (_T("Bad value for comptrustbyte parameter: value must be within 0..2."));
                p->comptrustbyte = 1;
                err = 1;
        }
        if (p->comptrustword < 0 || p->comptrustword > 3) {
-               write_log (_T("Bad value for comptrustword parameter: value must be within 0..2\n"));
+               error_log (_T("Bad value for comptrustword parameter: value must be within 0..2."));
                p->comptrustword = 1;
                err = 1;
        }
        if (p->comptrustlong < 0 || p->comptrustlong > 3) {
-               write_log (_T("Bad value for comptrustlong parameter: value must be within 0..2\n"));
+               error_log (_T("Bad value for comptrustlong parameter: value must be within 0..2."));
                p->comptrustlong = 1;
                err = 1;
        }
        if (p->comptrustnaddr < 0 || p->comptrustnaddr > 3) {
-               write_log (_T("Bad value for comptrustnaddr parameter: value must be within 0..2\n"));
+               error_log (_T("Bad value for comptrustnaddr parameter: value must be within 0..2."));
                p->comptrustnaddr = 1;
                err = 1;
        }
        if (p->cachesize < 0 || p->cachesize > 16384) {
-               write_log (_T("Bad value for cachesize parameter: value must be within 0..16384\n"));
+               error_log (_T("Bad value for cachesize parameter: value must be within 0..16384."));
                p->cachesize = 0;
                err = 1;
        }
        if (p->z3fastmem_size > 0 && (p->address_space_24 || p->cpu_model < 68020)) {
-               write_log (_T("Z3 fast memory can't be used with a 68000/68010 emulation. It\n")
-                       _T("requires a 68020 emulation. Turning off Z3 fast memory.\n"));
+               error_log (_T("Z3 fast memory can't be used with a 68000/68010 emulation. Turning off Z3 fast memory."));
                p->z3fastmem_size = 0;
                err = 1;
        }
        if (p->rtgmem_size > 0 && p->rtgmem_type == GFXBOARD_UAE_Z3 && (p->cpu_model < 68020 || p->address_space_24)) {
-               write_log (_T("RTG can't be used with a 68000/68010 or 68EC020 emulation. It\n")
-                       _T("requires a 68020 emulation. Turning off RTG.\n"));
+               error_log (_T("UAEGFX RTG can't be used with a 68000/68010 or 68EC020 emulation. Turning off RTG."));
                p->rtgmem_size = 0;
                err = 1;
        }
@@ -419,22 +449,24 @@ void fixup_prefs (struct uae_prefs *p)
 #endif
 
        if (p->nr_floppies < 0 || p->nr_floppies > 4) {
-               write_log (_T("Invalid number of floppies.  Using 4.\n"));
-               p->nr_floppies = 4;
+               error_log (_T("Invalid number of floppies.  Using 2."));
+               p->nr_floppies = 2;
                p->floppyslots[0].dfxtype = 0;
                p->floppyslots[1].dfxtype = 0;
-               p->floppyslots[2].dfxtype = 0;
-               p->floppyslots[3].dfxtype = 0;
+               p->floppyslots[2].dfxtype = -1;
+               p->floppyslots[3].dfxtype = -1;
                err = 1;
        }
        if (p->floppy_speed > 0 && p->floppy_speed < 10) {
+               error_log (_T("Invalid floppy speed."));
                p->floppy_speed = 100;
        }
        if (p->input_mouse_speed < 1 || p->input_mouse_speed > 1000) {
+               error_log (_T("Invalid mouse speed."));
                p->input_mouse_speed = 100;
        }
        if (p->collision_level < 0 || p->collision_level > 3) {
-               write_log (_T("Invalid collision support level.  Using 1.\n"));
+               error_log (_T("Invalid collision support level.  Using 1."));
                p->collision_level = 1;
                err = 1;
        }
@@ -460,9 +492,10 @@ void fixup_prefs (struct uae_prefs *p)
        /* Can't fit genlock and A2024 or Graffiti at the same time,
         * also Graffiti uses genlock audio bit as an enable signal
         */
-       if (p->genlock && p->monitoremu)
+       if (p->genlock && p->monitoremu) {
+               error_log (_T("Genlock and A2024 or Graffiti can't be active simultaneously."));
                p->genlock = false;
-
+       }
 
        fixup_prefs_dimensions (p);
 
@@ -509,15 +542,25 @@ void fixup_prefs (struct uae_prefs *p)
 #endif
 #if defined (CPUEMU_12)
        if (p->cpu_cycle_exact) {
-               p->gfx_framerate = 1;
-               p->cachesize = 0;
-               p->m68k_speed = 0;
+               if (p->gfx_framerate > 1) {
+                       error_log (_T("Cycle-exact requires disabled frameskip."));
+                       p->gfx_framerate = 1;
+               }
+               if (p->cachesize) {
+                       error_log (_T("Cycle-exact and JIT can't be active simultaneously."));
+                       p->cachesize = 0;
+               }
+               if (p->m68k_speed) {
+                       error_log (_T("Adjustable CPU speed is not available in cycle-exact mode."));
+                       p->m68k_speed = 0;
+               }
        }
 #endif
        if (p->maprom && !p->address_space_24)
                p->maprom = 0x0f000000;
-       if ((p->maprom & 0xff000000) && p->address_space_24)
+       if (((p->maprom & 0xff000000) && p->address_space_24) || p->mbresmem_high_size == 0x08000000) {
                p->maprom = 0x00e00000;
+       }
        if (p->tod_hack && p->cs_ciaatod == 0)
                p->cs_ciaatod = p->ntscmode ? 2 : 1;
 
index 22c20b55da5610860d7ac5cd135d954e300f16f0..7ac5d1ddf15cb83b3632c1b3d0f4f39406e02245 100644 (file)
@@ -221,6 +221,12 @@ static uae_u32 REGPARAM2 dummy_wget (uaecptr addr)
 {
 #ifdef JIT
        special_mem |= S_READ;
+#endif
+#if 0
+       if (addr == 0xb0b000) {
+               extern uae_u16 isideint(void);
+               return isideint();
+       }
 #endif
        if (currprefs.illegal_mem)
                dummylog (0, addr, 2, 0, 0);
@@ -421,6 +427,11 @@ void REGPARAM2 chipmem_lput (uaecptr addr, uae_u32 l)
        do_put_mem_long (m, l);
 }
 
+#if 0
+static int tables[256];
+static int told, toldv;
+#endif
+
 void REGPARAM2 chipmem_wput (uaecptr addr, uae_u32 w)
 {
        uae_u16 *m;
@@ -428,6 +439,14 @@ void REGPARAM2 chipmem_wput (uaecptr addr, uae_u32 w)
        addr &= chipmem_bank.mask;
        m = (uae_u16 *)(chipmem_bank.baseaddr + addr);
        do_put_mem_word (m, w);
+#if 0
+    if (addr == 0x120) {
+               if (told)
+                       tables[toldv] += hsync_counter - told;
+               told = hsync_counter;
+               toldv = w;
+       }
+#endif
 }
 
 void REGPARAM2 chipmem_bput (uaecptr addr, uae_u32 b)
@@ -1791,12 +1810,14 @@ static void fill_ce_banks (void)
        int i;
 
        memset (ce_banktype, CE_MEMBANK_FAST32, sizeof ce_banktype);
-       // data cachable regions
+       // data cachable regions (2 = burst supported)
        memset (ce_cachable, 0, sizeof ce_cachable);
-       memset (ce_cachable + (0x00200000 >> 16), 1, currprefs.fastmem_size >> 16);
+       memset (ce_cachable + (0x00200000 >> 16), 1 | 2, currprefs.fastmem_size >> 16);
        memset (ce_cachable + (0x00c00000 >> 16), 1, currprefs.bogomem_size >> 16);
-       memset (ce_cachable + (z3fastmem_bank.start >> 16), 1, currprefs.z3fastmem_size >> 16);
-       memset (ce_cachable + (z3fastmem2_bank.start >> 16), 1, currprefs.z3fastmem2_size >> 16);
+       memset (ce_cachable + (z3fastmem_bank.start >> 16), 1 | 2, currprefs.z3fastmem_size >> 16);
+       memset (ce_cachable + (z3fastmem2_bank.start >> 16), 1 | 2, currprefs.z3fastmem2_size >> 16);
+       memset (ce_cachable + (a3000hmem_bank.start >> 16), 1 | 2, currprefs.mbresmem_high_size >> 16);
+       memset (ce_cachable + (a3000lmem_bank.start >> 16), 1 | 2, currprefs.mbresmem_low_size >> 16);
 
        if (&get_mem_bank (0) == &chipmem_bank) {
                for (i = 0; i < (0x200000 >> 16); i++) {
index 465bc3657c98a70bc41def420b3db5c7465c4335..7e46cd72e92aad528666d26f25dc4d68410d0048 100644 (file)
@@ -35,6 +35,7 @@
 #include "cia.h"
 #include "inputrecord.h"
 #include "inputdevice.h"
+#include "audio.h"
 #ifdef JIT
 #include "jit/compemu.h"
 #include <signal.h>
@@ -87,7 +88,9 @@ static uae_u16 fake_mmusr_030;
 static struct cache020 caches020[CACHELINES020];
 static struct cache030 icaches030[CACHELINES030];
 static struct cache030 dcaches030[CACHELINES030];
+#if 0
 static struct cache040 caches040[CACHESETS040];
+#endif
 
 #if COUNT_INSTRS
 static unsigned long int instrcount[65536];
@@ -1044,6 +1047,7 @@ static void set_cpu_caches (void)
                        dcaches030[(regs.caar >> 4) & (CACHELINES030 - 1)].valid[(regs.caar >> 2) & 3] = 0;
                        regs.cacr &= ~0x400;
                }
+#if 0
        } else if (currprefs.cpu_model == 68040) {
                if (!(regs.cacr & 0x8000)) {
                        for (i = 0; i < CACHESETS040; i++) {
@@ -1053,6 +1057,7 @@ static void set_cpu_caches (void)
                                caches040[i].valid[3] = 0;
                        }
                }
+#endif
        }
 }
 
@@ -1088,38 +1093,46 @@ static void build_cpufunctbl (void)
        case 68060:
                lvl = 5;
                tbl = op_smalltbl_0_ff;
-               if (currprefs.cpu_cycle_exact)
-                       tbl = op_smalltbl_22_ff;
-               if (currprefs.mmu_model)
-                       tbl = op_smalltbl_33_ff;
+               if (!currprefs.cachesize) {
+                       if (currprefs.cpu_cycle_exact)
+                               tbl = op_smalltbl_22_ff;
+                       if (currprefs.mmu_model)
+                               tbl = op_smalltbl_33_ff;
+               }
                break;
        case 68040:
                lvl = 4;
                tbl = op_smalltbl_1_ff;
-               if (currprefs.cpu_cycle_exact)
-                       tbl = op_smalltbl_23_ff;
-               if (currprefs.mmu_model)
-                       tbl = op_smalltbl_31_ff;
+               if (!currprefs.cachesize) {
+                       if (currprefs.cpu_cycle_exact)
+                               tbl = op_smalltbl_23_ff;
+                       if (currprefs.mmu_model)
+                               tbl = op_smalltbl_31_ff;
+               }
                break;
        case 68030:
                lvl = 3;
                tbl = op_smalltbl_2_ff;
-               if (currprefs.cpu_cycle_exact)
-                       tbl = op_smalltbl_24_ff;
-               if (currprefs.mmu_model)
-                       tbl = op_smalltbl_32_ff;
+               if (!currprefs.cachesize) {
+                       if (currprefs.cpu_cycle_exact)
+                               tbl = op_smalltbl_24_ff;
+                       if (currprefs.mmu_model)
+                               tbl = op_smalltbl_32_ff;
+               }
                break;
        case 68020:
                lvl = 2;
                tbl = op_smalltbl_3_ff;
+               if (!currprefs.cachesize) {
 #ifdef CPUEMU_20
-               if (currprefs.cpu_compatible)
-                       tbl = op_smalltbl_20_ff;
+                       if (currprefs.cpu_compatible)
+                               tbl = op_smalltbl_20_ff;
 #endif
 #ifdef CPUEMU_21
-               if (currprefs.cpu_cycle_exact)
-                       tbl = op_smalltbl_21_ff;
+                       if (currprefs.cpu_cycle_exact)
+                               tbl = op_smalltbl_21_ff;
 #endif
+               }
                break;
        case 68010:
                lvl = 1;
@@ -1979,6 +1992,52 @@ uae_u32 REGPARAM2 x_get_disp_ea_020 (uae_u32 base, int idx)
        return v;
 }
 
+uae_u32 REGPARAM2 x_get_disp_ea_ce030 (uae_u32 base, int idx)
+{
+       uae_u16 dp = next_iword_030ce ();
+       int reg = (dp >> 12) & 15;
+       uae_u32 v;
+
+       uae_s32 regd = regs.regs[reg];
+       if ((dp & 0x800) == 0)
+               regd = (uae_s32)(uae_s16)regd;
+       regd <<= (dp >> 9) & 3;
+       if (dp & 0x100) {
+               uae_s32 outer = 0;
+               if (dp & 0x80)
+                       base = 0;
+               if (dp & 0x40)
+                       regd = 0;
+
+               if ((dp & 0x30) == 0x20) {
+                       base += (uae_s32)(uae_s16) next_iword_030ce ();
+               }
+               if ((dp & 0x30) == 0x30) {
+                       base += next_ilong_030ce ();
+               }
+
+               if ((dp & 0x3) == 0x2) {
+                       outer = (uae_s32)(uae_s16) next_iword_030ce ();
+               }
+               if ((dp & 0x3) == 0x3) {
+                       outer = next_ilong_030ce ();
+               }
+
+               if ((dp & 0x4) == 0) {
+                       base += regd;
+               }
+               if (dp & 0x3) {
+                       base = x_get_long (base);
+               }
+               if (dp & 0x4) {
+                       base += regd;
+               }
+               v = base + outer;
+       } else {
+               v = base + (uae_s32)((uae_s8)dp) + regd;
+       }
+       return v;
+}
 
 uae_u32 REGPARAM2 x_get_disp_ea_ce020 (uae_u32 base, int idx)
 {
@@ -2063,11 +2122,6 @@ void REGPARAM2 MakeFromSR (void)
        int oldm = regs.m;
        int olds = regs.s;
 
-       if (currprefs.cpu_cycle_exact && currprefs.cpu_model >= 68020) {
-               x_do_cycles (6 * CYCLE_UNIT);
-               regs.ce020memcycles = 0;
-       }
-
        SET_XFLG ((regs.sr >> 4) & 1);
        SET_NFLG ((regs.sr >> 3) & 1);
        SET_ZFLG ((regs.sr >> 2) & 1);
@@ -4171,28 +4225,28 @@ cont:
 
 #ifdef CPUEMU_20
 // emulate simple prefetch
-static uae_u32 get_word_020_prefetchf (uae_u32 pc)
+static uae_u16 get_word_020_prefetchf (uae_u32 pc)
 {
        if (pc == regs.prefetch020addr) {
-               uae_u32 v = regs.prefetch020[0];
+               uae_u16 v = regs.prefetch020[0];
                regs.prefetch020[0] = regs.prefetch020[1];
                regs.prefetch020[1] = regs.prefetch020[2];
                regs.prefetch020[2] = x_get_word (pc + 6);
                regs.prefetch020addr += 2;
                return v;
        } else if (pc == regs.prefetch020addr + 2) {
-               uae_u32 v = regs.prefetch020[1];
+               uae_u16 v = regs.prefetch020[1];
                regs.prefetch020[0] = regs.prefetch020[2];
                regs.prefetch020[1] = x_get_word (pc + 4);
                regs.prefetch020[2] = x_get_word (pc + 6);
-               regs.prefetch020addr += 4;
+               regs.prefetch020addr = pc + 2;
                return v;
        } else if (pc == regs.prefetch020addr + 4) {
-               uae_u32 v = regs.prefetch020[2];
+               uae_u16 v = regs.prefetch020[2];
                regs.prefetch020[0] = x_get_word (pc + 2);
                regs.prefetch020[1] = x_get_word (pc + 4);
                regs.prefetch020[2] = x_get_word (pc + 6);
-               regs.prefetch020addr += 6;
+               regs.prefetch020addr = pc + 2;
                return v;
        } else {
                regs.prefetch020addr = pc + 2;
@@ -4340,10 +4394,12 @@ void cpu_halt (int id)
                gui_led (LED_CPU, 0);
                regs.intmask = 7;
                MakeSR ();
+               audio_deactivate ();
        }
        while (regs.halted) {
-               x_do_cycles (8 * CYCLE_UNIT);
-               cpu_cycles = adjust_cycles (cpu_cycles);
+               if (vpos == 0)
+                       sleep_millis_main (8);
+               x_do_cycles (100 * CYCLE_UNIT);
                if (regs.spcflags) {
                        if ((regs.spcflags & (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE)))
                                return;
@@ -4556,6 +4612,7 @@ insretry:
 #endif
 
 
+#if 0
 /* "cycle exact" 68040+ */
 
 static void m68k_run_3ce (void)
@@ -4581,6 +4638,7 @@ static void m68k_run_3ce (void)
                        return;
        }
 }
+#endif
 
 /* "cycle exact" 68020/030  */
 
@@ -4972,12 +5030,15 @@ void m68k_go (int may_quit)
                                currprefs.cpu_model == 68030 && currprefs.mmu_model ? m68k_run_mmu030 :
                                currprefs.cpu_model == 68040 && currprefs.mmu_model ? m68k_run_mmu040 :
                                currprefs.cpu_model == 68060 && currprefs.mmu_model ? m68k_run_mmu060 :
+#if 0
                                currprefs.cpu_model >= 68040 && currprefs.cpu_cycle_exact ? m68k_run_3ce :
+#endif
                                currprefs.cpu_model >= 68020 && currprefs.cpu_cycle_exact ? m68k_run_2ce :
                                currprefs.cpu_compatible ? (currprefs.cpu_model <= 68020 ? m68k_run_2p : m68k_run_2pf) : m68k_run_2;
 #if 0
                }
 #endif
+               //activate_debugger();
                run_func ();
                unset_special (SPCFLAG_BRK | SPCFLAG_MODE_CHANGE);
        }
@@ -5457,6 +5518,36 @@ void m68k_dumpstate (uaecptr *nextpc)
 {
        m68k_dumpstate (m68k_getpc (), nextpc);
 }
+void m68k_dumpcache (void)
+{
+       if (!currprefs.cpu_compatible)
+               return;
+       if (currprefs.cpu_model == 68020) {
+               for (int i = 0; i < CACHELINES020; i += 4) {
+                       for (int j = 0; j < 4; j++) {
+                               int s = i + j;
+                               uaecptr addr;
+                               struct cache020 *c = &caches020[s];
+                               addr = c->tag & ~1;
+                               addr |= s << 2;
+                               console_out_f (_T("%08X:%08X%c "), addr, c->data, c->valid ? '*' : ' ');
+                       }
+                       console_out_f (_T("\n"));
+               }
+       } else if (currprefs.cpu_model == 68030) {
+               for (int i = 0; i < CACHELINES030; i++) {
+                       struct cache030 *c = &icaches030[i];
+                       uaecptr addr;
+                       addr = c->tag & ~1;
+                       addr |= i << 4;
+                       console_out_f (_T("%08X: "), addr);
+                       for (int j = 0; j < 4; j++) {
+                               console_out_f (_T("%08X%c "), c->data[j], c->valid[j] ? '*' : ' ');
+                       }
+                       console_out_f (_T("\n"));
+               }
+       }
+}
 
 #ifdef SAVESTATE
 
@@ -6191,6 +6282,7 @@ void divbyzero_special (bool issigned, uae_s32 dst)
        }
 }
 
+#if 0
 STATIC_INLINE void fill_cache040 (uae_u32 addr)
 {
        int index, i, lws;
@@ -6226,6 +6318,7 @@ STATIC_INLINE void fill_cache040 (uae_u32 addr)
        regs.cacheholdingaddr020 = addr;
        regs.cacheholdingdata020 = data;
 }
+#endif
 
 // this one is really simple and easy
 static void fill_icache020 (uae_u32 addr, uae_u32 (*fetch)(uaecptr))
@@ -6320,6 +6413,8 @@ void usecycles_ce020 (int cycles)
        }
 }
 
+// these are also used by 68030.
+
 #define RESET_CE020_CYCLES \
        resetcycles_ce020 ()
 #define STORE_CE020_CYCLES \
@@ -6586,8 +6681,10 @@ STATIC_INLINE void fill_icache030 (uae_u32 addr)
                regs.cacheholdingdata020 = c->data[lws];
                return;
        }
+
        // cache miss
        if (currprefs.cpu_cycle_exact) {
+               // see fill_icache020
                if (regs.ce020memcycles < 0)
                        regs.ce020memcycles = 0;
                unsigned long cycs = get_cycles ();
@@ -6599,15 +6696,14 @@ STATIC_INLINE void fill_icache030 (uae_u32 addr)
        }
        if ((regs.cacr & 3) == 1) { // not frozen and enabled
                update_cache030 (c, data, tag, lws);
-#if 0
-               if ((regs.cacr & 0x11) == 0x11 && lws == 0 && !c->valid[0] && !c->valid[1] && !c->valid[2] && !c->valid[3] && ce_banktype[addr >> 16] == CE_MEMBANK_FAST) {
-                       // do burst fetch if cache enabled, not frozen, all slots invalid, no chip ram
-                       c->data[1] = mem_access_delay_long_read_ce020 (addr + 4);
-                       c->data[2] = mem_access_delay_long_read_ce020 (addr + 8);
-                       c->data[3] = mem_access_delay_long_read_ce020 (addr + 12);
-                       c->valid[1] = c->valid[2] = c->valid[3] = true;
-               }
-#endif
+       }
+       if ((regs.cacr & 0x11) == 0x11 && lws == 0 && !c->valid[1] && !c->valid[2] && !c->valid[3] && ce_banktype[addr >> 16] == CE_MEMBANK_FAST32) {
+               // do burst fetch if cache enabled, not frozen, all slots invalid, no chip ram
+               c->data[1] = get_longi (addr + 4);
+               c->data[2] = get_longi (addr + 8);
+               c->data[3] = get_longi (addr + 12);
+               do_cycles_ce020_mem (3 * (CPU020_MEM_CYCLE - 1), c->data[3]);
+               c->valid[1] = c->valid[2] = c->valid[3] = true;
        }
        regs.cacheholdingaddr020 = addr;
        regs.cacheholdingdata020 = data;
@@ -6636,28 +6732,9 @@ void write_dcache030 (uaecptr addr, uae_u32 val, int size)
                if (c1->tag != tag1 || c1->valid[lws1] == false)
                        return;
        }
-
-#if 0
-       uaecptr a = 0x1db0c;
-       if (addr - (1 << size) + 1 <= a && addr + (1 << size) >= a) {
-               write_log (_T("%08x %d %d %08x %08x %d\n"), addr, aligned, size, val, tag1, lws1);
-               if (aligned == 2)
-                       write_log (_T("*\n"));
-       }
-#endif
-
        // easy one
        if (size == 2 && aligned == 0) {
                update_cache030 (c1, val, tag1, lws1);
-#if 0
-               if ((regs.cacr & 0x1100) == 0x1100 && lws1 == 0 && !c1->valid[0] && !c1->valid[1] && !c1->valid[2] && !c1->valid[3] && ce_banktype[addr >> 16] == CE_MEMBANK_FAST) {
-                       // do burst fetch if cache enabled, not frozen, all slots invalid, no chip ram
-                       c1->data[1] = mem_access_delay_long_read_ce020 (addr + 4);
-                       c1->data[2] = mem_access_delay_long_read_ce020 (addr + 8);
-                       c1->data[3] = mem_access_delay_long_read_ce020 (addr + 12);
-                       c1->valid[1] = c1->valid[2] = c1->valid[3] = true;
-               }
-#endif
                return;
        }
        // argh!! merge partial write
@@ -6716,17 +6793,20 @@ uae_u32 read_dcache030 (uaecptr addr, int size)
                                return get_byte (addr);
                }
        }
-
        c1 = getcache030 (dcaches030, addr, &tag1, &lws1);
        addr &= ~3;
        if (!c1->valid[lws1] || c1->tag != tag1) {
                v1 = currprefs.cpu_cycle_exact ? mem_access_delay_long_read_ce020 (addr) : get_long (addr);
                update_cache030 (c1, v1, tag1, lws1);
-       } else {
+       } else if (uae_boot_rom) {
+               // this check and fix is needed for UAE filesystem handler because it runs in host side and in
+               // separate thread. No way to access via cache without locking that would cause major slowdown
+               // and unneeded complexity
+               uae_u32 tv = get_long (addr);
                v1 = c1->data[lws1];
-               if (get_long (addr) != v1) {
+               if (tv != v1) {
                        write_log (_T("data cache mismatch %d %d %08x %08x != %08x %08x %d PC=%08x\n"),
-                               size, aligned, addr, get_long (addr), v1, tag1, lws1, M68K_GETPC);
+                               size, aligned, addr, tv, v1, tag1, lws1, M68K_GETPC);
                        v1 = get_long (addr);
                }
        }
@@ -6738,15 +6818,23 @@ uae_u32 read_dcache030 (uaecptr addr, int size)
                v1 >>= (2 - aligned) * 8;
                return v1;
        } else if (size == 2 && aligned == 0) {
+               if ((regs.cacr & 0x1100) == 0x1100 && lws1 == 0 && !c1->valid[1] && !c1->valid[2] && !c1->valid[3] && ce_banktype[addr >> 16] == CE_MEMBANK_FAST32) {
+                       // do burst fetch if cache enabled, not frozen, all slots invalid, no chip ram
+                       c1->data[1] = get_long (addr + 4);
+                       c1->data[2] = get_long (addr + 8);
+                       c1->data[3] = get_long (addr + 12);
+                       do_cycles_ce020_mem (3 * (CPU020_MEM_CYCLE - 1), c1->data[3]);
+                       c1->valid[1] = c1->valid[2] = c1->valid[3] = true;
+               }
                return v1;
        }
-       // need two longs
+       // no, need another one
        addr += 4;
        c2 = getcache030 (dcaches030, addr, &tag2, &lws2);
        if (!c2->valid[lws2] || c2->tag != tag2) {
                v2 = currprefs.cpu_cycle_exact ? mem_access_delay_long_read_ce020 (addr) : get_long (addr);
                update_cache030 (c2, v2, tag2, lws2);
-       } else {
+       } else if (uae_boot_rom) {
                v2 = c2->data[lws2];
                if (get_long (addr) != v2) {
                        write_log (_T("data cache mismatch %d %d %08x %08x != %08x %08x %d PC=%08x\n"),
@@ -6783,40 +6871,6 @@ uae_u32 get_word_ce030_prefetch (int o)
        return v;
 }
 
-STATIC_INLINE void fill_icache040 (uae_u32 addr)
-{
-       uae_u32 data;
-       addr &= ~3;
-       if (currprefs.cpu_cycle_exact)
-               data = mem_access_delay_longi_read_ce020 (addr);
-       else
-               data = get_longi (addr);
-       regs.cacheholdingaddr020 = addr;
-       regs.cacheholdingdata020 = data;
-}
-
-uae_u32 get_word_ce040_prefetch (int o)
-{
-       uae_u32 pc = m68k_getpc () + o;
-       uae_u32 v;
-
-       if (pc & 2) {
-               v = regs.prefetch020[0] & 0xffff;
-               regs.prefetch020[0] = regs.prefetch020[1];
-               regs.prefetch020[1] = regs.prefetch020[2];
-               regs.prefetch020[2] = regs.prefetch020[3];
-               fill_icache040 (pc + 2 + 4);
-               regs.prefetch020[1] = regs.cacheholdingdata020;
-               fill_icache040 (pc + 2 + 4 + 4);
-               regs.prefetch020[2] = regs.cacheholdingdata020;
-               fill_icache040 (pc + 2 + 4 + 4 + 4);
-               regs.prefetch020[3] = regs.cacheholdingdata020;
-               return v;
-       }
-       v = regs.prefetch020[0] >> 16;
-       return v;
-}
-
 void flush_dcache (uaecptr addr, int size)
 {
        if (!currprefs.cpu_cycle_exact)
@@ -6831,20 +6885,6 @@ void flush_dcache (uaecptr addr, int size)
        }
 }
 
-void fill_prefetch_040 (void)
-{
-       uaecptr pc = m68k_getpc ();
-       pc &= ~3;
-       fill_icache040 (pc);
-       regs.prefetch020[0] = regs.cacheholdingdata020;
-       fill_icache040 (pc + 4);
-       regs.prefetch020[1] = regs.cacheholdingdata020;
-       fill_icache040 (pc + 4 + 4);
-       regs.prefetch020[2] = regs.cacheholdingdata020;
-       fill_icache040 (pc + 4 + 4  +4);
-       regs.prefetch020[3] = regs.cacheholdingdata020;
-}
-
 void fill_prefetch_030 (void)
 {
        uaecptr pc = m68k_getpc ();
@@ -6866,23 +6906,15 @@ void fill_prefetch_020 (void)
        regs.prefetch020[1] = regs.cacheholdingdata020;
 }
 
-void fill_prefetch_0x0 (void)
-{
-       if (currprefs.cpu_model >= 68040)
-               fill_prefetch_040 ();
-       else
-               fill_prefetch_030 ();
-}
-
 void fill_prefetch (void)
 {
+       if (currprefs.cachesize)
+               return;
        uaecptr pc = m68k_getpc ();
        if (currprefs.cpu_model == 68020) {
                fill_prefetch_020 ();
-       } else if (currprefs.cpu_model >= 68030) {
+       } else if (currprefs.cpu_model == 68030) {
                fill_prefetch_030 ();
-       } else if (currprefs.cpu_model >= 68040) {
-               fill_prefetch_040 ();
        } else if (currprefs.cpu_model <= 68010) {
                regs.ir = x_get_word (pc);
                regs.irc = x_get_word (pc + 2);
index 6874170770a8199ec5f309b67d15bc06ce926b86..1bcbbcfe54ff7649f8dc2b56bda99564836a316f 100644 (file)
@@ -1273,11 +1273,13 @@ static const struct hidquirk quirks[] =  {
        { 0 }
 };
 
+// PC analog joystick to USB adapters
 static const struct hidquirk hidnorawinput[] =  {
-       { 0x0583, 0x2030 }, //  Rockfire RM-203 1
-       { 0x0583, 0x2031 }, //  Rockfire RM-203 2
-       { 0x0583, 0x2032 }, //  Rockfire RM-203 3
-       { 0x0583, 0x2033 }, //  Rockfire RM-203 4
+       { 0x0583, 0x2030 }, // Rockfire RM-203 1
+       { 0x0583, 0x2031 }, // Rockfire RM-203 2
+       { 0x0583, 0x2032 }, // Rockfire RM-203 3
+       { 0x0583, 0x2033 }, // Rockfire RM-203 4
+       { 0x079d, 0x0201 }, // "USB  ADAPTOR"
        { 0 }
 };
 
index e303987efa419472eac01e6523d591bae7067526..bed125e7dc826d97e59890e5413da6a3ba98d6f0 100644 (file)
@@ -2214,7 +2214,7 @@ static int getd3dadapter (IDirect3D9 *d3d)
        return D3DADAPTER_DEFAULT;
 }
 
-static const TCHAR *D3D_init2 (HWND ahwnd, int w_w, int w_h, int depth, int mmult)
+static const TCHAR *D3D_init2 (HWND ahwnd, int w_w, int w_h, int depth, int *freq, int mmult)
 {
        HRESULT ret, hr;
        static TCHAR errmsg[100] = { 0 };
@@ -2337,6 +2337,7 @@ static const TCHAR *D3D_init2 (HWND ahwnd, int w_w, int w_h, int depth, int mmul
                                vsync2 = 1;
                        }
                }
+               *freq = modeex.RefreshRate;
        }
        if (vsync < 0) {
                vsync2 = 0;
@@ -2397,7 +2398,7 @@ static const TCHAR *D3D_init2 (HWND ahwnd, int w_w, int w_h, int depth, int mmul
                        write_log (_T("%s\n"), errmsg);
                        write_log (_T("%s: Retrying fullscreen with DirectDraw\n"), D3DHEAD);
                        if (ddraw_fs_hack_init ()) {
-                               const TCHAR *err2 = D3D_init (ahwnd, w_w, w_h, depth, mmult);
+                               const TCHAR *err2 = D3D_init (ahwnd, w_w, w_h, depth, freq, mmult);
                                if (err2)
                                        ddraw_fs_hack_free ();
                                return err2;
@@ -2406,7 +2407,7 @@ static const TCHAR *D3D_init2 (HWND ahwnd, int w_w, int w_h, int depth, int mmul
                if (d3d_ex && D3DEX) {
                        write_log (_T("%s\n"), errmsg);
                        D3DEX = 0;
-                       return D3D_init (ahwnd, w_w, w_h, depth, mmult);
+                       return D3D_init (ahwnd, w_w, w_h, depth, freq, mmult);
                }
                D3D_free (true);
                return errmsg;
@@ -2461,7 +2462,7 @@ static const TCHAR *D3D_init2 (HWND ahwnd, int w_w, int w_h, int depth, int mmul
                        d3d = NULL;
                }
                d3ddevex = NULL;
-               return D3D_init (ahwnd, w_w, w_h, depth, mmult);
+               return D3D_init (ahwnd, w_w, w_h, depth, freq, mmult);
        }
        if (!shaderon)
                write_log (_T("Using non-shader version\n"));
@@ -2529,7 +2530,7 @@ static const TCHAR *D3D_init2 (HWND ahwnd, int w_w, int w_h, int depth, int mmul
                hr = S_OK;
                if (forcedframelatency >= 0)
                        hr = d3ddevex->SetMaximumFrameLatency (forcedframelatency);
-               else if (v > 1 || !vsync)
+               else if (dpp.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE && (v > 1 || !vsync))
                        hr = d3ddevex->SetMaximumFrameLatency (vsync ? (hzmult < 0 ? 2 : 1) : 0);
                if (FAILED (hr))
                        write_log (_T("%s: SetMaximumFrameLatency() failed: %s\n"), D3DHEAD, D3D_ErrorString (hr));
@@ -2545,6 +2546,7 @@ struct d3d_initargs
        int h;
        int depth;
        int mmult;
+       int *freq;
 };
 static struct d3d_initargs d3dargs;
 
@@ -2558,7 +2560,7 @@ static void *D3D_init_start (void *p)
        D3D_free2 ();
        sleep_millis (1000);
        write_log (_T("Threaded D3D_init() start (init)\n"));
-       const TCHAR *t = D3D_init2 (d3dargs.hwnd, d3dargs.w, d3dargs.h, d3dargs.depth, d3dargs.mmult);
+       const TCHAR *t = D3D_init2 (d3dargs.hwnd, d3dargs.w, d3dargs.h, d3dargs.depth, d3dargs.freq, d3dargs.mmult);
        if (t) {
                gui_message (_T("Threaded D3D_init() returned error '%s'\n"), t);
        }
@@ -2579,16 +2581,17 @@ static void *D3D_init_start (void *p)
        return NULL;
 }
 
-const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int depth, int mmult)
+const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int depth, int *freq, int mmult)
 {
        if (!fakemodewaitms)
-               return D3D_init2 (ahwnd, w_w, w_h, depth, mmult);
+               return D3D_init2 (ahwnd, w_w, w_h, depth, freq, mmult);
        fakemode = true;
        d3dargs.hwnd = ahwnd;
        d3dargs.w = w_w;
        d3dargs.h = w_h;
        d3dargs.depth = depth;
        d3dargs.mmult = mmult;
+       d3dargs.freq = freq;
        uae_start_thread_fast (D3D_init_start, NULL, &fakemodetid);
        return NULL;
 }
index 906fddfeee0152efc182bdc99218a6a91cfae4f7..4646082c8bb69c108d3b893971a79d61f25d7e8d 100644 (file)
@@ -1,6 +1,6 @@
 extern void D3D_resize (int width, int height);
 extern void D3D_free (bool immediate);
-extern const TCHAR *D3D_init (HWND ahwnd, int w_w, int h_h, int depth, int mmult);
+extern const TCHAR *D3D_init (HWND ahwnd, int w_w, int h_h, int depth, int *freq, int mmult);
 extern bool D3D_alloctexture (int, int);
 extern void D3D_getpixelformat (int depth,int *rb, int *bb, int *gb, int *rs, int *bs, int *gs, int *ab, int *ar, int *a);
 extern void D3D_refresh (void);
index 1a135be7439ea820e6fe26051b05e2c8c8d579f3..3b208f5108710adc808f2ce79e1fd2d25bac07a9 100644 (file)
@@ -565,6 +565,9 @@ int hdf_open_target (struct hardfiledata *hfd, const TCHAR *pname)
                                        GENERIC_READ,
                                        FILE_SHARE_READ,
                                        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
+                               DWORD err = GetLastError ();
+                               if (h == INVALID_HANDLE_VALUE && err == ERROR_FILE_NOT_FOUND)
+                                       goto end;
                        }
                }
                if (h != INVALID_HANDLE_VALUE) {
index 741e07b89f02bed5b47f2db3bb6b7c9014d0f197..67685adc46488c927e14018681594411bc000bab 100644 (file)
@@ -854,7 +854,8 @@ void *shmat (int shmid, void *shmaddr, int shmflg)
                result = virtualallocwithlock (shmaddr, size, MEM_COMMIT, PAGE_READWRITE);
                if (result == NULL) {
                        result = (void*)-1;
-                       write_log (_T("VA %08X - %08X %x (%dk) failed %d\n"),
+                       error_log (_T("Memory %s failed to allocate: VA %08X - %08X %x (%dk). Error %d."),
+                               shmids[shmid].name,
                                (uae_u8*)shmaddr - natmem_offset, (uae_u8*)shmaddr - natmem_offset + size,
                                size, size >> 10, GetLastError ());
                } else {
index 0e7a13a5cb1f0af3eeba6dfaf7e663aed642ca34..195c5234216cc0f9b595988a8cf868c7b91a5f04 100644 (file)
 #define IDD_TAPEDRIVE                   388
 #define IDS_WHEELMOUSE                  389
 #define IDS_JOYMODE_WHEELMOUSE          389
+#define IDD_ERRORLOG                    389
 #define IDS_NUMSG_KS68030PLUS           390
 #define IDS_SELECTTAPE                  391
 #define IDS_TAPE                        392
 #define IDC_CACHETEXT                   1509
 #define IDC_SWAP                        1509
 #define IDC_MAPDRIVES_CD                1509
+#define IDC_RESTARTEMU2                 1509
+#define IDC_ERRORLOG                    1509
 #define IDC_SELECTRESTEXT               1510
 #define IDC_FLUSHPRINTER                1510
 #define IDC_MAPDRIVES_REMOVABLE         1510
 #define IDC_TAPE_SELECT_DIR             1832
 #define IDC_TAPE_SELECT_FILE            1833
 #define IDC_TAPE_RW                     1834
+#define IDC_ERRORLOGMESSAGE             1835
+#define IDC_ERRORLOGCLEAR               1836
 #define ID__FLOPPYDRIVES                40004
 #define ID_FLOPPYDRIVES_DF0             40005
 #define ID_ST_CONFIGURATION             40010
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NO_MFC                     1
 #define _APS_3D_CONTROLS                     1
-#define _APS_NEXT_RESOURCE_VALUE        389
+#define _APS_NEXT_RESOURCE_VALUE        390
 #define _APS_NEXT_COMMAND_VALUE         40050
-#define _APS_NEXT_CONTROL_VALUE         1835
+#define _APS_NEXT_CONTROL_VALUE         1837
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif
index 89dbddb75ad57baa050420ae25e85992364d999f..a3ab0f489ec30d3319929fe94517a734b9abcb39 100644 (file)
@@ -458,13 +458,23 @@ BEGIN
                     "Button",BS_AUTOCHECKBOX | WS_TABSTOP,195,270,160,11
 END
 
-IDD_CONTRIBUTORS DIALOGEX 0, 0, 411, 242
+IDD_CONTRIBUTORS DIALOGEX 0, 0, 530, 345
 STYLE DS_LOCALEDIT | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | WS_POPUP | WS_VISIBLE | WS_CAPTION
 CAPTION "UAE Authors and Contributors..."
 FONT 8, "MS Sans Serif", 0, 0, 0x0
 BEGIN
-    DEFPUSHBUTTON   "Ok",ID_OK,177,224,53,14
-    CONTROL         "",IDC_CONTRIBUTORS,"RICHEDIT",TCS_HOTTRACK | TCS_VERTICAL | TCS_RAGGEDRIGHT | TCS_OWNERDRAWFIXED | TCS_MULTISELECT | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP,4,5,404,214
+    DEFPUSHBUTTON   "Ok",ID_OK,238,324,53,14
+    CONTROL         "",IDC_CONTRIBUTORS,"RICHEDIT",TCS_HOTTRACK | TCS_VERTICAL | TCS_RAGGEDRIGHT | TCS_OWNERDRAWFIXED | TCS_MULTISELECT | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP,4,5,521,311
+END
+
+IDD_ERRORLOG DIALOGEX 0, 0, 530, 345
+STYLE DS_LOCALEDIT | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | WS_POPUP | WS_VISIBLE | WS_CAPTION
+CAPTION "Configuration error log"
+FONT 8, "MS Sans Serif", 0, 0, 0x0
+BEGIN
+    DEFPUSHBUTTON   "OK",IDOK,176,322,65,15
+    CONTROL         "",IDC_ERRORLOGMESSAGE,"RICHEDIT",TCS_HOTTRACK | TCS_VERTICAL | TCS_RAGGEDRIGHT | TCS_OWNERDRAWFIXED | TCS_MULTISELECT | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP,4,5,521,309
+    PUSHBUTTON      "Clear log",IDC_ERRORLOGCLEAR,288,322,65,15
 END
 
 IDD_ABOUT DIALOGEX 0, 0, 345, 258
@@ -870,6 +880,7 @@ BEGIN
     DEFPUSHBUTTON   "OK",IDOK,375,328,47,14
     PUSHBUTTON      "Cancel",IDCANCEL,427,328,47,14
     PUSHBUTTON      "Help",IDHELP,479,328,47,14,WS_DISABLED
+    PUSHBUTTON      "Error log",IDC_ERRORLOG,322,328,47,14,NOT WS_VISIBLE
 END
 
 IDD_PATHS DIALOGEX 0, 0, 396, 303
@@ -1336,6 +1347,10 @@ BEGIN
     BEGIN
     END
 
+    IDD_ERRORLOG, DIALOG
+    BEGIN
+    END
+
     IDD_ABOUT, DIALOG
     BEGIN
     END
index ca829e893ef8b22235ac27460fa4658eeedc997d..96be79e5d4a5055b3f4da60444083121cacec88c 100644 (file)
@@ -2989,8 +2989,10 @@ void target_fixup_options (struct uae_prefs *p)
        if (depth) {
                p->color_mode = p->color_mode == 5 ? 2 : 5;
        }
-       if (p->rtg_hardwaresprite && !p->gfx_api)
+       if (p->rtg_hardwaresprite && !p->gfx_api) {
+               error_log (_T("DirectDraw is not RTG hardware sprite compatible."));
                p->rtg_hardwaresprite = false;
+       }
        if (p->rtgmem_type >= GFXBOARD_HARDWARE) {
                p->rtg_hardwareinterrupt = false;
                p->rtg_hardwaresprite = false;
index de4a1838d5a90392cc376ca076152714e6b353b2..3995fb61eb05cc62b4bfa5ff66b42121c57d09b3 100644 (file)
 #define LANG_DLL 1
 
 #if WINUAEPUBLICBETA
-#define WINUAEBETA _T("6")
+#define WINUAEBETA _T("7")
 #else
 #define WINUAEBETA _T("")
 #endif
-#define WINUAEDATE MAKEBD(2013, 8, 3)
+#define WINUAEDATE MAKEBD(2013, 9, 1)
 #define WINUAEEXTRA _T("")
 //#define WINUAEEXTRA _T("AmiKit Preview")
 //#define WINUAEEXTRA _T("Amiga Forever Edition")
index 8834e64e16581771a48d1e50a9710c72a1f82286..6b6e02b19c26369708014f358991a4f29962d366 100644 (file)
@@ -89,6 +89,7 @@ struct winuae_currentmode {
        int initdone;
        int fullfill;
        int vsync;
+       int freq;
 };
 
 struct MultiDisplay Displays[MAX_DISPLAYS + 1];
@@ -458,8 +459,9 @@ static int set_ddraw_2 (void)
                        olderr = ddrval;
                        if (freq) {
                                write_log (_T("set_ddraw: failed, trying without forced refresh rate\n"));
+                               freq = 0;
                                DirectDraw_SetCooperativeLevel (hAmigaWnd, dxfullscreen, TRUE);
-                               ddrval = DirectDraw_SetDisplayMode (width, height, bits, 0);
+                               ddrval = DirectDraw_SetDisplayMode (width, height, bits, freq);
                                if (SUCCEEDED (ddrval))
                                        break;
                        }
@@ -467,6 +469,7 @@ static int set_ddraw_2 (void)
                                goto oops;
                        return -1;
                }
+               currentmode->freq = freq;
                updatewinrect (true);
        }
 
@@ -2414,6 +2417,7 @@ static int modeswitchneeded (struct winuae_currentmode *wc)
 void gfx_set_picasso_state (int on)
 {
        struct winuae_currentmode wc;
+       struct apmode *newmode, *oldmode;
        int mode;
 
        if (screen_is_picasso == on)
@@ -2422,10 +2426,20 @@ void gfx_set_picasso_state (int on)
        rp_rtg_switch ();
        memcpy (&wc, currentmode, sizeof (wc));
 
+       newmode = &currprefs.gfx_apmode[on ? 1 : 0];
+       oldmode = &currprefs.gfx_apmode[on ? 0 : 1];
+
        updatemodes ();
        update_gfxparams ();
        clearscreen ();
-       if (currprefs.gfx_apmode[0].gfx_fullscreen != currprefs.gfx_apmode[1].gfx_fullscreen || (currprefs.gfx_apmode[0].gfx_fullscreen == GFX_FULLSCREEN && currprefs.gfx_api)) {
+       if (newmode->gfx_fullscreen != oldmode->gfx_fullscreen ||
+               (newmode->gfx_fullscreen && (
+                       newmode->gfx_backbuffers != oldmode->gfx_backbuffers ||
+                       newmode->gfx_display != oldmode->gfx_display ||
+                       newmode->gfx_refreshrate != oldmode->gfx_refreshrate ||
+                       newmode->gfx_strobo != oldmode->gfx_strobo ||
+                       newmode->gfx_vflip != oldmode->gfx_vflip ||
+                       newmode->gfx_vsync != oldmode->gfx_vsync))) {
                mode = 1;
        } else {
                mode = modeswitchneeded (&wc);
@@ -4150,7 +4164,7 @@ static BOOL doInit (void)
        S2X_free ();
        oldtex_w = oldtex_h = -1;
        if (currentmode->flags & DM_D3D) {
-               const TCHAR *err = D3D_init (hAmigaWnd, currentmode->native_width, currentmode->native_height, currentmode->current_depth, screen_is_picasso ? 1 : currprefs.gfx_filter_filtermode + 1);
+               const TCHAR *err = D3D_init (hAmigaWnd, currentmode->native_width, currentmode->native_height, currentmode->current_depth, &currentmode->freq, screen_is_picasso ? 1 : currprefs.gfx_filter_filtermode + 1);
                if (err) {
                        D3D_free (true);
                        gui_message (err);
index f96107aa7ae9009200fb697e7db6c6bbfc344fe8..a7630764e7a9d4a2893938a8c319a15dbb36edb0 100644 (file)
@@ -1192,7 +1192,8 @@ static HWND cachedlist = NULL;
 #define MAX_P96_MEM_Z3 ((max_z3fastmem >> 20) < 512 ? 8 : ((max_z3fastmem >> 20) < 1024 ? 9 : ((max_z3fastmem >> 20) < 2048) ? 10 : 11))
 #define MAX_P96_MEM_Z2 4
 #define MIN_MB_MEM 0
-#define MAX_MB_MEM 7
+#define MAX_MBL_MEM 7
+#define MAX_MBH_MEM 8
 
 #define MIN_M68K_PRIORITY 1
 #define MAX_M68K_PRIORITY 16
@@ -2411,14 +2412,20 @@ int DiskSelection_2 (HWND hDlg, WPARAM wParam, int flag, struct uae_prefs *prefs
                                TCHAR disk_name[32];
                                disk_name[0] = 0; disk_name[31] = 0;
                                GetDlgItemText (hDlg, IDC_CREATE_NAME, disk_name, 30);
-                               disk_creatediskfile (full_path, 0, (drive_type)SendDlgItemMessage (hDlg, IDC_FLOPPYTYPE, CB_GETCURSEL, 0, 0L), disk_name, ischecked (hDlg, IDC_FLOPPY_FFS), ischecked (hDlg, IDC_FLOPPY_BOOTABLE), NULL);
+                               if (disk_creatediskfile (full_path, 0, (drive_type)SendDlgItemMessage (hDlg, IDC_FLOPPYTYPE, CB_GETCURSEL, 0, 0L), disk_name, ischecked (hDlg, IDC_FLOPPY_FFS), ischecked (hDlg, IDC_FLOPPY_BOOTABLE), NULL)) {
+                                       fullpath (full_path, sizeof full_path / sizeof (TCHAR));
+                                       DISK_history_add (full_path, -1, HISTORY_FLOPPY, 0);
+                               }
                        }
                        break;
                case IDC_CREATE_RAW:
                        TCHAR disk_name[32];
                        disk_name[0] = 0; disk_name[31] = 0;
                        GetDlgItemText (hDlg, IDC_CREATE_NAME, disk_name, 30);
-                       disk_creatediskfile (full_path, 1, (drive_type)SendDlgItemMessage (hDlg, IDC_FLOPPYTYPE, CB_GETCURSEL, 0, 0L), disk_name, ischecked (hDlg, IDC_FLOPPY_FFS), ischecked (hDlg, IDC_FLOPPY_BOOTABLE), NULL);
+                       if (disk_creatediskfile (full_path, 1, (drive_type)SendDlgItemMessage (hDlg, IDC_FLOPPYTYPE, CB_GETCURSEL, 0, 0L), disk_name, ischecked (hDlg, IDC_FLOPPY_FFS), ischecked (hDlg, IDC_FLOPPY_BOOTABLE), NULL)) {
+                               fullpath (full_path, sizeof full_path / sizeof (TCHAR));
+                               DISK_history_add (full_path, -1, HISTORY_FLOPPY, 0);
+                       }
                        break;
                case IDC_LOAD:
                        if (target_cfgfile_load (&workprefs, full_path, 0, 0) == 0) {
@@ -4728,6 +4735,38 @@ static INT_PTR CALLBACK LoadSaveDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPA
 
 #define MAX_CONTRIBUTORS_LENGTH 2048
 
+static INT_PTR CALLBACK ErrorLogProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+       CHARFORMAT CharFormat;
+       TCHAR *err;
+
+       switch (msg) {
+       case WM_COMMAND:
+               if (wParam == IDOK) {
+                       EndDialog (hDlg, 1);
+                       return TRUE;
+               } else if (wParam == IDC_ERRORLOGCLEAR) {
+                       error_log (NULL);
+                       EndDialog (hDlg, 1);
+                       return TRUE;
+               }
+               break;
+       case WM_INITDIALOG:
+               err = get_error_log ();
+               if (err == NULL)
+                       return FALSE;
+               CharFormat.cbSize = sizeof (CharFormat);
+               SetDlgItemText (hDlg, IDC_ERRORLOGMESSAGE, err);
+               SendDlgItemMessage (hDlg, IDC_ERRORLOGMESSAGE, EM_GETCHARFORMAT, 0, (LPARAM) & CharFormat);
+               CharFormat.dwMask |= CFM_SIZE | CFM_FACE;
+               CharFormat.yHeight = 8 * 20; /* height in twips, where a twip is 1/20th of a point - for a pt.size of 18 */
+               _tcscpy (CharFormat.szFaceName, os_vista ? _T("Segoe UI") : _T("Tahoma"));
+               SendDlgItemMessage (hDlg, IDC_ERRORLOGMESSAGE, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) & CharFormat);
+               return TRUE;
+       }
+       return FALSE;
+}
+
 static INT_PTR CALLBACK ContributorsProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
 {
        CHARFORMAT CharFormat;
@@ -7307,6 +7346,7 @@ static void values_to_memorydlg (HWND hDlg)
        case 0x01000000: mem_size = 5; break;
        case 0x02000000: mem_size = 6; break;
        case 0x04000000: mem_size = 7; break;
+       case 0x08000000: mem_size = 8; break;
        }
        SendDlgItemMessage (hDlg, IDC_MBMEM2, TBM_SETPOS, TRUE, mem_size);
        SetDlgItemText (hDlg, IDC_MBRAM2, memsize_names[msi_gfx[mem_size]]);
@@ -7752,8 +7792,8 @@ static INT_PTR CALLBACK MemoryDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARA
                SendDlgItemMessage (hDlg, IDC_SLOWMEM, TBM_SETRANGE, TRUE, MAKELONG (MIN_SLOW_MEM, MAX_SLOW_MEM));
                SendDlgItemMessage (hDlg, IDC_Z3FASTMEM, TBM_SETRANGE, TRUE, MAKELONG (MIN_Z3_MEM, MAX_Z3_MEM));
                SendDlgItemMessage (hDlg, IDC_Z3CHIPMEM, TBM_SETRANGE, TRUE, MAKELONG (MIN_Z3_MEM, MAX_Z3_CHIPMEM));
-               SendDlgItemMessage (hDlg, IDC_MBMEM1, TBM_SETRANGE, TRUE, MAKELONG (MIN_MB_MEM, MAX_MB_MEM));
-               SendDlgItemMessage (hDlg, IDC_MBMEM2, TBM_SETRANGE, TRUE, MAKELONG (MIN_MB_MEM, MAX_MB_MEM));
+               SendDlgItemMessage (hDlg, IDC_MBMEM1, TBM_SETRANGE, TRUE, MAKELONG (MIN_MB_MEM, MAX_MBL_MEM));
+               SendDlgItemMessage (hDlg, IDC_MBMEM2, TBM_SETRANGE, TRUE, MAKELONG (MIN_MB_MEM, MAX_MBH_MEM));
                CheckDlgButton(hDlg, IDC_FASTMEMAUTOCONFIG, workprefs.fastmem_autoconfig);
 
 
@@ -8580,8 +8620,8 @@ static void enable_for_cpudlg (HWND hDlg)
        ew (hDlg, IDC_JITENABLE, jitenable);
        ew (hDlg, IDC_COMPATIBLE, !workprefs.cpu_cycle_exact);
        ew (hDlg, IDC_COMPATIBLE_FPU, workprefs.fpu_model > 0);
-       ew (hDlg, IDC_FPU_UNIMPLEMENTED, workprefs.fpu_model);
-       ew (hDlg, IDC_CPU_UNIMPLEMENTED, workprefs.cpu_model == 68060);
+       ew (hDlg, IDC_FPU_UNIMPLEMENTED, workprefs.fpu_model && !workprefs.cachesize);
+       ew (hDlg, IDC_CPU_UNIMPLEMENTED, workprefs.cpu_model == 68060 && !workprefs.cachesize);
 #if 0
        ew (hDlg, IDC_CPU_MULTIPLIER, workprefs.cpu_cycle_exact);
 #endif
@@ -8616,8 +8656,8 @@ static void values_to_cpudlg (HWND hDlg)
        CheckDlgButton (hDlg, IDC_COMPATIBLE, workprefs.cpu_compatible);
        CheckDlgButton (hDlg, IDC_COMPATIBLE24, workprefs.address_space_24);
        CheckDlgButton (hDlg, IDC_COMPATIBLE_FPU, workprefs.fpu_strict);
-       CheckDlgButton (hDlg, IDC_FPU_UNIMPLEMENTED, !workprefs.fpu_no_unimplemented);
-       CheckDlgButton (hDlg, IDC_CPU_UNIMPLEMENTED, !workprefs.int_no_unimplemented);
+       CheckDlgButton (hDlg, IDC_FPU_UNIMPLEMENTED, !workprefs.fpu_no_unimplemented || workprefs.cachesize);
+       CheckDlgButton (hDlg, IDC_CPU_UNIMPLEMENTED, !workprefs.int_no_unimplemented || workprefs.cachesize);
        SendDlgItemMessage (hDlg, IDC_CPUIDLE, TBM_SETPOS, TRUE, workprefs.cpu_idle == 0 ? 0 : 12 - workprefs.cpu_idle / 15);
        cpu = (workprefs.cpu_model - 68000) / 10;
        if (cpu >= 5)
@@ -8815,7 +8855,12 @@ static INT_PTR CALLBACK CPUDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l
 
                idx = 4;
                if (workprefs.cpu_clock_multiplier >= 1 << 8) {
-                       idx = (workprefs.cpu_clock_multiplier >> 8) - 1;
+                       idx = 0;
+                       while (idx < 3) {
+                               if (workprefs.cpu_clock_multiplier < (1 << 8) << idx)
+                                       break;
+                               idx++;
+                       }
                } else if (workprefs.cpu_clock_multiplier == 0 && workprefs.cpu_frequency == 0 && workprefs.cpu_model <= 68010) {
                        idx = 1; // A500
                } else if (workprefs.cpu_clock_multiplier == 0 && workprefs.cpu_frequency == 0 && workprefs.cpu_model >= 68020) {
@@ -9785,8 +9830,10 @@ static void hardfilecreatehdf (HWND hDlg, TCHAR *newpath)
        if (res == 0)
                dostype[0] = 0;
        if (CreateHardFile (hDlg, setting, dostype, newpath, hdfpath)) {
-               if (!current_hfdlg.ci.rootdir[0])
+               if (!current_hfdlg.ci.rootdir[0]) {
+                       fullpath (hdfpath, sizeof hdfpath / sizeof (TCHAR));
                        _tcscpy (current_hfdlg.ci.rootdir, hdfpath);
+               }
        }
        sethardfile (hDlg);
 }
@@ -10255,7 +10302,7 @@ static void new_tapedrive (HWND hDlg, int entry)
        ci.type = UAEDEV_TAPE;
        ci.blocksize = 512;
        uci = add_filesys_config (&workprefs, entry, &ci);
-       if (uci) {
+       if (uci && uci->unitnum >= 0) {
                tape_media_change (uci->unitnum, &ci);
        }
 }
@@ -15985,6 +16032,7 @@ static INT_PTR CALLBACK DialogProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l
                        SetWindowText (GetDlgItem (guiDlg, IDOK), tmp);
                }
                ShowWindow (GetDlgItem (guiDlg, IDC_RESTARTEMU), full_property_sheet ? SW_HIDE : SW_SHOW);
+               ShowWindow (GetDlgItem (guiDlg, IDC_ERRORLOG), is_error_log () ? SW_SHOW : SW_HIDE);
                centerWindow (hDlg);
                createTreeView (hDlg);
                updatePanel (currentpage);
@@ -16021,6 +16069,12 @@ static INT_PTR CALLBACK DialogProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l
                {
                        switch (LOWORD(wParam))
                        {
+                       case IDC_ERRORLOG:
+                               {
+                                       CustomDialogBox (IDD_ERRORLOG, hDlg, ErrorLogProc);
+                                       ShowWindow (GetDlgItem (guiDlg, IDC_ERRORLOG), is_error_log () ? SW_SHOW : SW_HIDE);
+                               }
+                               break;
                        case IDC_RESETAMIGA:
                                uae_reset (1, 1);
                                SendMessage (hDlg, WM_COMMAND, IDOK, 0);
index 018b4d6b541f3e56336823f9bd6e3c014e2bbf41..6e7e8aedf43f0f14d9a29eab3ae5ced5601bbef4 100644 (file)
@@ -719,6 +719,7 @@ endofline:
                        sz = destmode == Dreg ? sz_long : sz_byte;
                }
                table68k[opc].size = sz;
+               table68k[opc].sduse = id.sduse;
                table68k[opc].sreg = srcreg;
                table68k[opc].dreg = destreg;
                table68k[opc].smode = srcmode;
@@ -731,6 +732,10 @@ endofline:
                table68k[opc].plev = id.plevel;
                table68k[opc].clev = id.cpulevel;
                table68k[opc].unimpclev = id.unimpcpulevel;
+               table68k[opc].head = id.head;
+               table68k[opc].tail = id.tail;
+               table68k[opc].clocks = id.clocks;
+               table68k[opc].fetchmode = id.fetchmode;
 
 #if 0
                for (i = 0; i < 5; i++) {
index 95b4af05d7ac83b9bd48ef56bad8e70319e465fd..e4933bfac9b028092806c5c39d30bd464e549ecd 100644 (file)
@@ -683,6 +683,8 @@ void restore_state (const TCHAR *filename)
                        end = restore_scsi_dmac (chunk);
                else if (!_tcscmp (name, _T("SCSI")))
                        end = restore_scsi_device (chunk);
+               else if (!_tcscmp (name, _T("SCSD")))
+                       end = restore_scsidev (chunk);
                else if (!_tcscmp (name, _T("GAYL")))
                        end = restore_gayle (chunk);
                else if (!_tcscmp (name, _T("IDE ")))
@@ -975,7 +977,11 @@ static int save_state_internal (struct zfile *f, const TCHAR *description, int c
                save_chunk (f, dst, len, _T("SCSI"), 0);
                xfree (dst);
        }
-
+       for (i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) {
+               dst = save_scsidev (i, &len, NULL);
+               save_chunk (f, dst, len, _T("SCSD"), 0);
+               xfree (dst);
+       }
 #ifdef ACTION_REPLAY
        dst = save_action_replay (&len, NULL);
        save_chunk (f, dst, len, _T("ACTR"), comp);
index 5930730f24cd7be30b45c5e6be45ae254d8fc0f4..6d6e725670cead293c2c5b0933df134b4023f334 100644 (file)
--- a/scsi.cpp
+++ b/scsi.cpp
@@ -17,7 +17,7 @@
 #include "zfile.h"
 
 static int outcmd[] = { 0x0a, 0x2a, 0x2f, 0xaa, 0x15, 0x55, -1 };
-static int incmd[] = { 0x01, 0x03, 0x05, 0x08, 0x12, 0x1a, 0x5a, 0x25, 0x28, 0x37, 0x42, 0x43, 0xa8, 0x51, 0x52, -1 };
+static int incmd[] = { 0x01, 0x03, 0x05, 0x08, 0x12, 0x1a, 0x5a, 0x25, 0x28, 0x37, 0x42, 0x43, 0xa8, 0x51, 0x52, 0xbd, -1 };
 static int nonecmd[] = { 0x00, 0x11, 0x16, 0x17, 0x19, 0x1b, 0x1e, 0x35, -1 };
 static int scsicmdsizes[] = { 6, 10, 10, 12, 16, 12, 10, 10 };
 
index 05ecf0a1683a0ac12d75a168b30b86d64105d072..0f094dfb39add371c75e5016ae48d95bf3c399ce 100644 (file)
@@ -27,6 +27,7 @@
 #include "scsidev.h"
 #include "uae.h"
 #include "execio.h"
+#include "savestate.h"
 
 #define CDDEV_COMMANDS
 
@@ -1150,6 +1151,8 @@ static void dev_reset (void)
                                dev->configblocksize = discsi->bytespersector;
                                if (discsi->type == INQ_ROMD)
                                        dev->iscd = 1;
+                       } else {
+                               sys_command_close (i);
                        }
                }
                i++;
@@ -1430,3 +1433,90 @@ void scsidev_reset (void)
                return;
        dev_reset ();
 }
+
+uae_u8 *save_scsidev (int num, int *len, uae_u8 *dstptr)
+{
+       uae_u8 *dstbak, *dst;
+       struct priv_devstruct *pdev;
+       struct devstruct *dev;
+
+       pdev = &pdevst[num];
+       if (!pdev->inuse)
+               return NULL;
+       if (dstptr)
+               dstbak = dst = dstptr;
+       else
+               dstbak = dst = xmalloc (uae_u8, 1000);
+       save_u32 (num);
+       save_u32 (0);
+       save_u32 (pdev->unit);
+       save_u32 (pdev->type);
+       save_u32 (pdev->mode);
+       save_u32 (pdev->flags);
+       dev = getdevstruct (pdev->unit);
+       if (dev) {
+               save_u32 (0);
+               save_u32 (dev->aunit);
+               save_u32 (dev->opencnt);
+               save_u32 (dev->changenum);
+               save_u32 (dev->changeint);
+               save_u32 (dev->changeint_mediastate);
+               save_u32 (dev->configblocksize);
+               save_u32 (dev->fadecounter);
+               save_u32 (dev->fadeframes);
+               save_u32 (dev->fadetarget);
+               for (int i = 0; i < MAX_ASYNC_REQUESTS; i++) {
+                       if (dev->d_request[i]) {
+                               save_u32 (dev->d_request[i]);
+                               save_u32 (dev->d_request_type[i]);
+                               save_u32 (dev->d_request_data[i]);
+                       }
+               }
+               save_u32 (0xffffffff);
+       } else {
+               save_u32 (0xffffffff);
+       }
+       *len = dst - dstbak;
+       return dstbak;
+}
+
+uae_u8 *restore_scsidev (uae_u8 *src)
+{
+       struct priv_devstruct *pdev;
+       struct devstruct *dev;
+       int i;
+
+       int num = restore_u32 ();
+       if (num == 0)
+               dev_reset ();
+       pdev = &pdevst[num];
+       restore_u32 ();
+       restore_u32 ();
+       pdev->type = restore_u32 ();
+       pdev->mode = restore_u32 ();
+       pdev->flags = restore_u32 ();
+       if (restore_u32 () != 0xffffffff) {
+               dev = getdevstruct (pdev->unit);
+               if (dev) {
+                       dev->aunit = restore_u32 ();
+                       dev->opencnt = restore_u32 ();
+                       dev->changenum = restore_u32 ();
+                       dev->changeint = restore_u32 ();
+                       dev->changeint_mediastate = restore_u32 ();
+                       dev->configblocksize = restore_u32 ();
+                       dev->fadecounter = restore_u32 ();
+                       dev->fadeframes = restore_u32 ();
+                       dev->fadetarget = restore_u32 ();
+                       i = 0;
+                       for (;;) {
+                               uae_u32 v = restore_u32 ();
+                               if (v == 0xffffffff)
+                                       break;
+                               dev->d_request[i] = v;
+                               dev->d_request_type[i] = restore_u32 ();
+                               dev->d_request_data[i] = restore_u32 ();
+                       }
+               }
+       }
+       return src;
+}
\ No newline at end of file
index 28f5c9a3beb31745f5b85fef43749085ad24a2a2..9aaf20b651020afb24cc06287cdfc295b41315c3 100644 (file)
@@ -67,6 +67,7 @@ static void tape_init (int unit, struct scsi_data_tape *tape, const TCHAR *tape_
        tape->wp = readonly;
        tape->beom = -1;
        tape->nomedia = false;
+       tape->unloaded = false;
 
        if (my_existsdir (tape->tape_dir)) {
                tape->realdir = true;
@@ -80,6 +81,8 @@ static void tape_init (int unit, struct scsi_data_tape *tape, const TCHAR *tape_
        _tcscat (path, FSDB_DIR_SEPARATOR_S);
        _tcscat (path, TAPE_INDEX);
        tape->index = zfile_fopen (path, _T("rb"), ZFD_NORMAL);
+       if (tape->index)
+               write_log (_T("TAPEEMU INDEX: '%s'\n"), path);
        tapeunits[unit] = tape;
 }
 
@@ -264,9 +267,9 @@ int scsi_tape_emulate (struct scsi_data_tape *tape, uae_u8 *cmdbuf, int scsi_cmd
        if (cmdbuf[0] == 3) {
                s[0] = 0x70;
                if (tape->beom < 0)
-                       s[9] |= 0x8;
+                       s[9] |= 0x8; // beginning of media
                if (tape->beom > 0)
-                       s[2] |= 0x40;
+                       s[2] |= 0x40; // end of media
                *sense_len = 0x12;
                return 0;
        }
@@ -291,6 +294,8 @@ int scsi_tape_emulate (struct scsi_data_tape *tape, uae_u8 *cmdbuf, int scsi_cmd
        case 0x00: /* TEST UNIT READY */
                if (notape (tape))
                        goto notape;
+               if (tape->unloaded)
+                       goto unloaded;
                scsi_len = 0;
                break;
 
@@ -299,6 +304,8 @@ int scsi_tape_emulate (struct scsi_data_tape *tape, uae_u8 *cmdbuf, int scsi_cmd
                        write_log (_T("TAPEEMU ERASE\n"));
                if (notape (tape))
                        goto notape;
+               if (tape->unloaded)
+                       goto unloaded;
                if (tape->wp)
                        goto writeprot;
                erase (tape);
@@ -316,9 +323,10 @@ int scsi_tape_emulate (struct scsi_data_tape *tape, uae_u8 *cmdbuf, int scsi_cmd
                        write_log (_T("TAPEEMU LOAD/UNLOAD %d:%d:%d\n"), eot, ret, load);
                if (notape (tape))
                        goto notape;
-               if (load && (ret || eot))
+               if (load && eot)
                        goto errreq;
                rewind (tape);
+               tape->unloaded = !load;
                if (eot) {
                        tape->beom = 1;
                } else {
@@ -333,6 +341,8 @@ int scsi_tape_emulate (struct scsi_data_tape *tape, uae_u8 *cmdbuf, int scsi_cmd
                        write_log (_T("TAPEEMU: REWIND. IMMED=%d\n"), cmdbuf[1] & 1);
                if (notape (tape))
                        goto notape;
+               if (tape->unloaded)
+                       goto unloaded;
                rewind (tape);
                scsi_len = 0;
                break;
@@ -343,6 +353,10 @@ int scsi_tape_emulate (struct scsi_data_tape *tape, uae_u8 *cmdbuf, int scsi_cmd
                int count = rl (cmdbuf + 1) & 0xffffff;
                if (log_tapeemu)
                        write_log (_T("TAPEEMU: SPACE code=%d count=%d\n"), code, count);
+               if (notape (tape))
+                       goto notape;
+               if (tape->unloaded)
+                       goto unloaded;
                if (code >= 2)
                        goto errreq;
                if (code == 1) {
@@ -359,6 +373,8 @@ int scsi_tape_emulate (struct scsi_data_tape *tape, uae_u8 *cmdbuf, int scsi_cmd
                        write_log (_T("TAPEEMU WRITE FILEMARK %d\n"), len);
                if (notape (tape))
                        goto notape;
+               if (tape->unloaded)
+                       goto unloaded;
                if (tape->wp)
                        goto writeprot;
                if (len > 0) {
@@ -376,6 +392,8 @@ int scsi_tape_emulate (struct scsi_data_tape *tape, uae_u8 *cmdbuf, int scsi_cmd
                        write_log (_T("TAPEEMU WRITE %d (%d, %d)\n"), len, rl (cmdbuf + 1) & 0xffffff, cmdbuf[1] & 1);
                if (notape (tape))
                        goto notape;
+               if (tape->unloaded)
+                       goto unloaded;
                if (tape->wp)
                        goto writeprot;
                if (tape->beom < 0)
@@ -393,6 +411,8 @@ int scsi_tape_emulate (struct scsi_data_tape *tape, uae_u8 *cmdbuf, int scsi_cmd
                        write_log (_T("TAPEEMU READ %d (%d, %d)\n"), len, rl (cmdbuf + 1) & 0xffffff, cmdbuf[1] & 1);
                if (notape (tape))
                        goto notape;
+               if (tape->unloaded)
+                       goto unloaded;
                if (tape->beom < 0)
                        tape->beom = 0;
                scsi_len = tape_read (tape, scsi_data, len);
@@ -597,6 +617,13 @@ endoftape:
                s[13] = 2; /* End-of-partition/medium detected */
                ls = 0x12;
                break;
+unloaded:
+               status = SCSI_STATUS_CHECK_CONDITION;
+               s[0] = 0x70;
+               s[2] = SCSI_SK_NOT_READY;
+               s[12] = SCSI_NOT_READY;
+               ls = 0x12;
+               break;
 notape:
                status = SCSI_STATUS_CHECK_CONDITION;
                s[0] = 0x70;
index ec31efac3574befb16e4069e4c366cded9b83637..60f4421ade234258825fba0b19a562b215a467db 100644 (file)
--- a/table68k
+++ b/table68k
 %   4 means jump offset
 %   8 means jump address
 % instruction
+% optional line feed and 68030 Head/Tail/Cycles/ea calculation
 %
 
 0000 0000 0011 1100:000:XNZVC:XNZVC:10: ORSR.B  #1
 0000 0000 0111 1100:002:?????:?????:10: ORSR.W  #1
 0000 0zz0 11ss sSSS:250:?????:?????:11: CHK2.z  #1,s[!Dreg,Areg,Aipi,Apdi,Immd]
-0000 0000 zzdd dDDD:000:-NZ00:-----:13: OR.z    #z,d[!Areg]
+0000 0000 zzdd dDDD:000:-NZ00:-----:13: OR.z    #z,d[Dreg]
+- 2 0 2 fiea
+0000 0000 zzdd dDDD:000:-NZ00:-----:13: OR.z    #z,d[!Areg,Dreg]
+- 0 1 3 fiea
 0000 0010 0011 1100:000:XNZVC:XNZVC:10: ANDSR.B #1
 0000 0010 0111 1100:002:?????:?????:10: ANDSR.W #1
-0000 0010 zzdd dDDD:000:-NZ00:-----:13: AND.z   #z,d[!Areg]
-0000 0100 zzdd dDDD:000:XNZVC:-----:13: SUB.z   #z,d[!Areg]
-0000 0110 zzdd dDDD:000:XNZVC:-----:13: ADD.z   #z,d[!Areg]
+0000 0010 zzdd dDDD:000:-NZ00:-----:13: AND.z   #z,d[Dreg]
+- 2 0 2 fiea
+0000 0010 zzdd dDDD:000:-NZ00:-----:13: AND.z   #z,d[!Areg,Dreg]
+- 0 1 3 fiea
+0000 0100 zzdd dDDD:000:XNZVC:-----:13: SUB.z   #z,d[Dreg]
+- 2 0 2 fiea
+0000 0100 zzdd dDDD:000:XNZVC:-----:13: SUB.z   #z,d[!Areg,Dreg]
+- 0 1 3 fiea
+0000 0110 zzdd dDDD:000:XNZVC:-----:13: ADD.z   #z,d[Dreg]
+- 2 0 2 fiea
+0000 0110 zzdd dDDD:000:XNZVC:-----:13: ADD.z   #z,d[!Areg,Dreg]
+- 0 1 3 fiea
 0000 0110 11ss sSSS:230:?????:?????:10: CALLM   s[!Dreg,Areg,Aipi,Apdi,Immd]
 0000 0110 11ss sSSS:230:?????:?????:10: RTM     s[Dreg,Areg]
-0000 1000 00ss sSSS:000:--Z--:-----:11: BTST    #1,s[!Areg]
-0000 1000 01ss sSSS:000:--Z--:-----:13: BCHG    #1,s[!Areg,Immd]
-0000 1000 10ss sSSS:000:--Z--:-----:13: BCLR    #1,s[!Areg,Immd]
-0000 1000 11ss sSSS:000:--Z--:-----:13: BSET    #1,s[!Areg,Immd]
+0000 1000 00ss sSSS:000:--Z--:-----:11: BTST    #1,s[Dreg]
+- 4 0 4
+0000 1000 00ss sSSS:000:--Z--:-----:11: BTST    #1,s[!Areg,Dreg,Immd]
+- 0 0 4 fiea
+0000 1000 01ss sSSS:000:--Z--:-----:13: BCHG    #1,s[Dreg]
+- 6 0 6
+0000 1000 01ss sSSS:000:--Z--:-----:13: BCHG    #1,s[!Areg,Dreg,Immd]
+- 0 0 6 fiea
+0000 1000 10ss sSSS:000:--Z--:-----:13: BCLR    #1,s[Dreg]
+- 6 0 6
+0000 1000 10ss sSSS:000:--Z--:-----:13: BCLR    #1,s[!Areg,Dreg,Immd]
+- 0 0 6 fiea
+0000 1000 11ss sSSS:000:--Z--:-----:13: BSET    #1,s[Dreg]
+- 6 0 6
+0000 1000 11ss sSSS:000:--Z--:-----:13: BSET    #1,s[!Areg,Dreg,Immd]
+- 0 0 6 fiea
 0000 1010 0011 1100:000:XNZVC:XNZVC:10: EORSR.B #1
 0000 1010 0111 1100:002:?????:?????:10: EORSR.W #1
-0000 1010 zzdd dDDD:000:-NZ00:-----:13: EOR.z   #z,d[!Areg]
-0000 1100 zzss sSSS:000:-NZVC:-----:11: CMP.z   #z,s[!Areg,Immd,PC8r,PC16]
+0000 1010 zzdd dDDD:000:-NZ00:-----:13: EOR.z   #z,d[Dreg]
+- 2 0 2 fiea
+0000 1010 zzdd dDDD:000:-NZ00:-----:13: EOR.z   #z,d[!Areg,Dreg]
+- 0 1 3 fiea
+0000 1100 zzss sSSS:000:-NZVC:-----:11: CMP.z   #z,s[Dreg]
+- 2 0 2 fiea
+0000 1100 zzss sSSS:000:-NZVC:-----:11: CMP.z   #z,s[!Areg,Dreg,Immd,PC8r,PC16]
+- 0 0 2 fiea
 0000 1100 zzss sSSS:200:-NZVC:-----:11: CMP.z   #z,s[PC8r,PC16]
+- 0 0 2 fiea
 
 0000 1010 11ss sSSS:200:?????:?????:13: CAS.B   #1,s[!Dreg,Areg,Immd,PC8r,PC16]
 0000 1100 11ss sSSS:200:?????:?????:13: CAS.W   #1,s[!Dreg,Areg,Immd,PC8r,PC16]
 0000 rrr1 01dd dDDD:050:-----:-----:12: MVPMR.L d[Areg-Ad16],Dr
 0000 rrr1 10dd dDDD:050:-----:-----:12: MVPRM.W Dr,d[Areg-Ad16]
 0000 rrr1 11dd dDDD:050:-----:-----:12: MVPRM.L Dr,d[Areg-Ad16]
-0000 rrr1 00ss sSSS:000:--Z--:-----:11: BTST    Dr,s[!Areg]
-0000 rrr1 01ss sSSS:000:--Z--:-----:13: BCHG    Dr,s[!Areg,Immd]
-0000 rrr1 10ss sSSS:000:--Z--:-----:13: BCLR    Dr,s[!Areg,Immd]
-0000 rrr1 11ss sSSS:000:--Z--:-----:13: BSET    Dr,s[!Areg,Immd]
+0000 rrr1 00ss sSSS:000:--Z--:-----:11: BTST    Dr,s[Dreg]
+- 4 0 4
+0000 rrr1 00ss sSSS:000:--Z--:-----:11: BTST    Dr,s[!Areg,Dreg,Immd]
+- 0 0 4 fea
+0000 rrr1 01ss sSSS:000:--Z--:-----:13: BCHG    Dr,s[Dreg]
+- 6 0 6
+0000 rrr1 01ss sSSS:000:--Z--:-----:13: BCHG    Dr,s[!Areg,Dreg,Immd]
+- 0 0 6 fiea
+0000 rrr1 10ss sSSS:000:--Z--:-----:13: BCLR    Dr,s[Dreg]
+- 6 0 6
+0000 rrr1 10ss sSSS:000:--Z--:-----:13: BCLR    Dr,s[!Areg,Dreg,Immd]
+- 0 0 6 fiea
+0000 rrr1 11ss sSSS:000:--Z--:-----:13: BSET    Dr,s[Dreg]
+- 6 0 6
+0000 rrr1 11ss sSSS:000:--Z--:-----:13: BSET    Dr,s[!Areg,Dreg,Immd]
+- 0 0 6 fiea
 
 0001 DDDd ddss sSSS:000:-NZ00:-----:12: MOVE.B  s,d[!Areg]
-0010 DDDd ddss sSSS:000:-----:-----:12: MOVEA.L s,d[Areg]
-0010 DDDd ddss sSSS:000:-NZ00:-----:12: MOVE.L  s,d[!Areg]
 0011 DDDd ddss sSSS:000:-----:-----:12: MOVEA.W s,d[Areg]
 0011 DDDd ddss sSSS:000:-NZ00:-----:12: MOVE.W  s,d[!Areg]
+0010 DDDd ddss sSSS:000:-----:-----:12: MOVEA.L s,d[Areg]
+0010 DDDd ddss sSSS:000:-NZ00:-----:12: MOVE.L  s,d[!Areg]
 
-0100 0000 zzdd dDDD:000:XxZxC:X-Z--:30: NEGX.z  d[!Areg]
-0100 0000 11dd dDDD:001:?????:?????:10: MVSR2.W d[!Areg]
-0100 0010 zzdd dDDD:000:-0100:-----:20: CLR.z   d[!Areg]
-0100 0010 11dd dDDD:100:?????:?????:10: MVSR2.B d[!Areg]
-0100 0100 zzdd dDDD:000:XNZVC:-----:30: NEG.z   d[!Areg]
-0100 0100 11ss sSSS:000:XNZVC:-----:10: MV2SR.B s[!Areg]
-0100 0110 zzdd dDDD:000:-NZ00:-----:30: NOT.z   d[!Areg]
+0100 0000 zzdd dDDD:000:XxZxC:X-Z--:30: NEGX.z  d[Dreg]
+- 2 0 2
+0100 0000 zzdd dDDD:000:XxZxC:X-Z--:30: NEGX.z  d[!Areg,Dreg]
+- 0 1 3 fea
+0100 0000 11dd dDDD:001:?????:?????:10: MVSR2.W d[Dreg]
+- 2 0 4
+0100 0000 11dd dDDD:001:?????:?????:10: MVSR2.W d[!Areg,Dreg]
+- 2 0 4 cea
+0100 0010 zzdd dDDD:000:-0100:-----:20: CLR.z   d[Dreg]
+- 2 0 2
+0100 0010 zzdd dDDD:000:-0100:-----:20: CLR.z   d[!Areg,Dreg]
+- 0 1 3 cea
+0100 0010 11dd dDDD:100:?????:?????:10: MVSR2.B d[Dreg]
+- 2 0 4
+0100 0010 11dd dDDD:100:?????:?????:10: MVSR2.B d[!Areg,Dreg]
+- 2 0 4 cea
+0100 0100 zzdd dDDD:000:XNZVC:-----:30: NEG.z   d[Dreg]
+- 2 0 2
+0100 0100 zzdd dDDD:000:XNZVC:-----:30: NEG.z   d[!Areg,Dreg]
+- 0 1 3 fea
+0100 0100 11ss sSSS:000:XNZVC:-----:10: MV2SR.B s[Dreg]
+- 4 0 4
+0100 0100 11ss sSSS:000:XNZVC:-----:10: MV2SR.B s[!Areg,Dreg]
+- 0 0 4 fea
+0100 0110 zzdd dDDD:000:-NZ00:-----:30: NOT.z   d[Dreg]
+- 2 0 2
+0100 0110 zzdd dDDD:000:-NZ00:-----:30: NOT.z   d[!Areg,Dreg]
+- 0 1 3 fea
 0100 0110 11ss sSSS:002:?????:?????:10: MV2SR.W s[!Areg]
+- 0 0 8 fea
 0100 1000 0000 1rrr:200:-----:-----:31: LINK.L  Ar,#2
+- 2 0 6
 0100 1000 00dd dDDD:000:X?Z?C:X-Z--:30: NBCD.B  d[!Areg]
 0100 1000 0100 1kkk:200:?????:?????:10: BKPT    #k
 0100 1000 01ss sSSS:000:-NZ00:-----:30: SWAP.W  s[Dreg]         
+- 4 0 4
 0100 1000 01ss sSSS:000:-----:-----:00: PEA.L   s[!Dreg,Areg,Aipi,Apdi,Immd]
-0100 1000 10dd dDDD:000:-NZ00:-----:30: EXT.W   d[Dreg]         
+- 0 2 4 cea
+0100 1000 10dd dDDD:000:-NZ00:-----:30: EXT.W   d[Dreg]
+- 4 0 4
 0100 1000 10dd dDDD:000:-----:-----:02: MVMLE.W #1,d[!Dreg,Areg,Aipi]
-0100 1000 11dd dDDD:000:-NZ00:-----:30: EXT.L   d[Dreg]         
+0100 1000 11dd dDDD:000:-NZ00:-----:30: EXT.L   d[Dreg]
+- 4 0 4
 0100 1000 11dd dDDD:000:-----:-----:02: MVMLE.L #1,d[!Dreg,Areg,Aipi]
 0100 1001 11dd dDDD:200:-NZ00:-----:30: EXT.B   d[Dreg]         
-0100 1010 zzss sSSS:000:-NZ00:-----:10: TST.z   s[!Areg,PC16,PC8r]
+- 4 0 4
+0100 1010 zzss sSSS:000:-NZ00:-----:10: TST.z   s[Dreg]
+- 0 0 2
+0100 1010 zzss sSSS:000:-NZ00:-----:10: TST.z   s[!Areg,Dreg,PC16,PC8r,Immd]
+- 0 0 2 fea
 0100 1010 zzss sSSS:200:-NZ00:-----:10: TST.z   s[Areg,PC16,PC8r]
-0100 1010 11dd dDDD:000:?????:?????:30: TAS.B   d[!Areg]
+- 0 0 2 fea
+0100 1010 11dd dDDD:000:?????:?????:30: TAS.B   d[Dreg]
+- 0 0 2
+0100 1010 11dd dDDD:000:?????:?????:30: TAS.B   d[!Areg,Dreg]
+- 0 0 2 fea
 0100 1010 1111 1100:000:?????:?????:00: ILLEGAL
 0100 1100 00ss sSSS:200:-NZVC:-----:13: MULL.L  #1,s[!Areg]
 0100 1100 01ss sSSS:200:?????:?????:13: DIVL.L  #1,s[!Areg]
 0100 1100 11ss sSSS:000:-----:-----:01: MVMEL.L #1,s[!Dreg,Areg,Apdi,Immd]
 0100 1110 0100 JJJJ:000:-----:XNZVC:10: TRAP    #J
 0100 1110 0101 0rrr:000:-----:-----:31: LINK.W  Ar,#1
+- 0 0 4
 0100 1110 0101 1rrr:000:-----:-----:30: UNLK.L  Ar
+- 0 0 5
 0100 1110 0110 0rrr:002:-----:-----:10: MVR2USP.L Ar
+- 4 0 4
 0100 1110 0110 1rrr:002:-----:-----:20: MVUSP2R.L Ar
+- 4 0 4
 0100 1110 0111 0000:002:-----:-----:00: RESET
+- 0 0 518
 0100 1110 0111 0001:000:-----:-----:00: NOP
+- 0 0 2
 0100 1110 0111 0010:002:XNZVC:-----:10: STOP    #1
+- 0 0 8
 0100 1110 0111 0011:002:XNZVC:-----:00: RTE
 0100 1110 0111 0100:000:?????:?????:10: RTD     #1
 0100 1110 0111 0101:000:-----:-----:00: RTS
 0100 1110 0111 0110:000:-----:XNZVC:00: TRAPV
 0100 1110 0111 0111:000:XNZVC:-----:00: RTR
 0100 1110 0111 1010:102:?????:?????:10: MOVEC2  #1
+- 6 0 6
 0100 1110 0111 1011:102:?????:?????:10: MOVE2C  #1
+- 6 0 6
 0100 1110 10ss sSSS:000://///://///:80: JSR.L   s[!Dreg,Areg,Aipi,Apdi,Immd]
+- 0 0 4 jea
 0100 rrr1 00ss sSSS:200:?????:?????:11: CHK.L   s[!Areg],Dr
 0100 rrr1 10ss sSSS:000:?????:?????:11: CHK.W   s[!Areg],Dr
 0100 1110 11ss sSSS:000://///://///:80: JMP.L   s[!Dreg,Areg,Aipi,Apdi,Immd]
+- 4 0 4 jea
 0100 rrr1 11ss sSSS:000:-----:-----:02: LEA.L   s[!Dreg,Areg,Aipi,Apdi,Immd],Ar
+- 2 0 2 cea
 
 0101 jjj0 01dd dDDD:000:-----:-----:13: ADDA.W  #j,d[Areg]
+- 2 0 2
 0101 jjj0 10dd dDDD:000:-----:-----:13: ADDA.L  #j,d[Areg]
-0101 jjj0 zzdd dDDD:000:XNZVC:-----:13: ADD.z   #j,d[!Areg]
+- 2 0 2
+0101 jjj0 zzdd dDDD:000:XNZVC:-----:13: ADD.z   #j,d[Dreg]
+- 2 0 2
+0101 jjj0 zzdd dDDD:000:XNZVC:-----:13: ADD.z   #j,d[!Areg,Dreg]
+- 0 1 3 fea
 0101 jjj1 01dd dDDD:000:-----:-----:13: SUBA.W  #j,d[Areg]
+- 2 0 2
 0101 jjj1 10dd dDDD:000:-----:-----:13: SUBA.L  #j,d[Areg]
-0101 jjj1 zzdd dDDD:000:XNZVC:-----:13: SUB.z   #j,d[!Areg]
+- 2 0 2
+0101 jjj1 zzdd dDDD:000:XNZVC:-----:13: SUB.z   #j,d[Dreg]
+- 2 0 2
+0101 jjj1 zzdd dDDD:000:XNZVC:-----:13: SUB.z   #j,d[!Areg,Dreg]
+- 0 1 3 fea
 0101 cccc 1100 1rrr:000:-----:-++++:31: DBcc.W  Dr,#1
-0101 cccc 11dd dDDD:000:-----:-++++:20: Scc.B   d[!Areg]
+0101 cccc 11dd dDDD:000:-----:-++++:20: Scc.B   d[Dreg]
+- 0 0 2
+0101 cccc 11dd dDDD:000:-----:-++++:20: Scc.B   d[!Areg,Dreg]
+- 0 0 2 cea
 0101 cccc 1111 1010:200:?????:?????:10: TRAPcc  #1
 0101 cccc 1111 1011:200:?????:?????:10: TRAPcc  #2
 0101 cccc 1111 1100:200:?????:?????:00: TRAPcc
 1000 rrr1 01dd dDDD:200:?????:?????:12: PACK    d[Areg-Apdi],Arp      
 1000 rrr1 10dd dDDD:200:?????:?????:12: UNPK    d[Dreg],Dr      
 1000 rrr1 10dd dDDD:200:?????:?????:12: UNPK    d[Areg-Apdi],Arp      
-1000 rrr1 11ss sSSS:000:?????:?????:13: DIVS.W  s[!Areg],Dr
+1000 rrr1 11ss sSSS:000:?????:?????:13: DIVS.W  s[Dreg],Dr
+- 2 0 56
+1000 rrr1 11ss sSSS:000:?????:?????:13: DIVS.W  s[!Areg,Dreg],Dr
+- 0 0 56 fea
 
-1001 rrr0 zzss sSSS:000:XNZVC:-----:13: SUB.z   s,Dr
+1001 rrr0 zzss sSSS:000:XNZVC:-----:13: SUB.z   s[Areg,Dreg],Dr
+- 2 0 2
+1001 rrr0 zzss sSSS:000:XNZVC:-----:13: SUB.z   s[!Areg,Dreg],Dr
+- 0 0 2 fea
 1001 rrr0 11ss sSSS:000:-----:-----:13: SUBA.W  s,Ar
+- 4 0 4
 1001 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: SUBX.z  d[Dreg],Dr      
 1001 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: SUBX.z  d[Areg-Apdi],Arp      
 1001 rrr1 zzdd dDDD:000:XNZVC:-----:13: SUB.z   Dr,d[!Areg,Dreg]
+- 0 1 3 fea
 1001 rrr1 11ss sSSS:000:-----:-----:13: SUBA.L  s,Ar
+- 2 0 2
 
-1011 rrr0 zzss sSSS:000:-NZVC:-----:11: CMP.z   s,Dr
-1011 rrr0 11ss sSSS:000:-NZVC:-----:11: CMPA.W  s,Ar
-1011 rrr1 11ss sSSS:000:-NZVC:-----:11: CMPA.L  s,Ar
+1011 rrr0 zzss sSSS:000:-NZVC:-----:11: CMP.z   s[Areg,Dreg],Dr
+- 2 0 2
+1011 rrr0 zzss sSSS:000:-NZVC:-----:11: CMP.z   s[!Areg,Dreg],Dr
+- 0 0 2 fea
+1011 rrr0 11ss sSSS:000:-NZVC:-----:11: CMPA.W  s[Areg,Dreg],Ar
+- 4 0 4
+1011 rrr0 11ss sSSS:000:-NZVC:-----:11: CMPA.W  s[!Areg,Dreg],Ar
+- 0 0 4 fea
+1011 rrr1 11ss sSSS:000:-NZVC:-----:11: CMPA.L  s[Areg,Dreg],Ar
+- 4 0 4
+1011 rrr1 11ss sSSS:000:-NZVC:-----:11: CMPA.L  s[!Areg,Dreg],Ar
+- 0 0 4 fea
 1011 rrr1 zzdd dDDD:000:-NZVC:-----:11: CMPM.z  d[Areg-Aipi],ArP
+- 0 0 8
 1011 rrr1 zzdd dDDD:000:-NZ00:-----:13: EOR.z   Dr,d[!Areg]
 
 1100 rrr0 zzss sSSS:000:-NZ00:-----:13: AND.z   s[!Areg],Dr
 1100 rrr0 11ss sSSS:000:-NZ00:-----:13: MULU.W  s[!Areg],Dr
+- 2 0 28 fea
 1100 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: ABCD.B  d[Dreg],Dr      
 1100 rrr1 00dd dDDD:000:XxZxC:X-Z--:13: ABCD.B  d[Areg-Apdi],Arp      
 1100 rrr1 zzdd dDDD:000:-NZ00:-----:13: AND.z   Dr,d[!Areg,Dreg]
 1100 rrr1 01dd dDDD:000:-----:-----:33: EXG.L   Dr,d[Dreg]      
+- 4 0 4
 1100 rrr1 01dd dDDD:000:-----:-----:33: EXG.L   Ar,d[Areg]            
+- 4 0 4
 1100 rrr1 10dd dDDD:000:-----:-----:33: EXG.L   Dr,d[Areg]      
+- 4 0 4
 1100 rrr1 11ss sSSS:000:-NZ00:-----:13: MULS.W  s[!Areg],Dr
+- 2 0 28 fea
 
-1101 rrr0 zzss sSSS:000:XNZVC:-----:13: ADD.z   s,Dr
+1101 rrr0 zzss sSSS:000:XNZVC:-----:13: ADD.z   s[Areg,Dreg],Dr
+- 2 0 2
+1101 rrr0 zzss sSSS:000:XNZVC:-----:13: ADD.z   s[!Areg,Dreg],Dr
+- 0 0 2 fea
 1101 rrr0 11ss sSSS:000:-----:-----:13: ADDA.W  s,Ar
+- 4 0 4
 1101 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: ADDX.z  d[Dreg],Dr      
 1101 rrr1 zzdd dDDD:000:XNZVC:X-Z--:13: ADDX.z  d[Areg-Apdi],Arp      
 1101 rrr1 zzdd dDDD:000:XNZVC:-----:13: ADD.z   Dr,d[!Areg,Dreg]
+- 0 1 3 fea
 1101 rrr1 11ss sSSS:000:-----:-----:13: ADDA.L  s,Ar
+- 2 0 2
 
 1110 jjjf zz00 0RRR:000:XNZVC:-----:13: ASf.z   #j,DR
+- 2 0 6
 1110 jjjf zz00 1RRR:000:XNZ0C:-----:13: LSf.z   #j,DR
+- 4 0 4
 1110 jjjf zz01 0RRR:000:XNZ0C:X----:13: ROXf.z  #j,DR
+- 10 0 12
 1110 jjjf zz01 1RRR:000:-NZ0C:-----:13: ROf.z   #j,DR
+- 4 0 6
 1110 rrrf zz10 0RRR:000:XNZVC:X----:13: ASf.z   Dr,DR
+- 4 0 6
 1110 rrrf zz10 1RRR:000:XNZ0C:X----:13: LSf.z   Dr,DR
+- 6 0 6
 1110 rrrf zz11 0RRR:000:XNZ0C:X----:13: ROXf.z  Dr,DR
+- 10 0 12
 1110 rrrf zz11 1RRR:000:-NZ0C:-----:13: ROf.z   Dr,DR
+- 6 0 8
 1110 000f 11dd dDDD:000:XNZVC:-----:13: ASfW.W  d[!Dreg,Areg]
+- 0 0 4 fea
 1110 001f 11dd dDDD:000:XNZ0C:-----:13: LSfW.W  d[!Dreg,Areg]
+- 0 0 4 fea
 1110 010f 11dd dDDD:000:XNZ0C:X----:13: ROXfW.W d[!Dreg,Areg]
+- 0 0 4 fea
 1110 011f 11dd dDDD:000:-NZ0C:-----:13: ROfW.W  d[!Dreg,Areg]
+- 0 0 6 fea
 
 1110 1000 11ss sSSS:200:?????:?????:11: BFTST   #1,s[!Areg,Apdi,Aipi,Immd]
 1110 1001 11ss sSSS:200:?????:?????:11: BFEXTU  #1,s[!Areg,Apdi,Aipi,Immd]