From: Toni Wilen Date: Sun, 1 Sep 2013 11:43:08 +0000 (+0300) Subject: 2700b7 X-Git-Tag: 2700~11 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=56452e01541dc2d8f4f82a87da933a1e53b1f8e0;p=francis%2Fwinuae.git 2700b7 --- diff --git a/akiko.cpp b/akiko.cpp index 3a1ad119..300a2a2f 100644 --- 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; diff --git a/archivers/lzx/unlzx.cpp b/archivers/lzx/unlzx.cpp index 373a6ce2..2e048f70 100644 --- a/archivers/lzx/unlzx.cpp +++ b/archivers/lzx/unlzx.cpp @@ -32,6 +32,8 @@ /* - minimal UAE specific version 13-14.06.2007 by Toni Wilen */ +#define LZX_ERROR_CHECK 1 + #include #include @@ -43,28 +45,30 @@ /* ---------------------------------------------------------------------- */ -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; diff --git a/audio.cpp b/audio.cpp index 8fbdc589..6ec40ecd 100644 --- 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 (); diff --git a/blkdev.cpp b/blkdev.cpp index 2d73639b..f693e3e2 100644 --- a/blkdev.cpp +++ b/blkdev.cpp @@ -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) diff --git a/build68k.cpp b/build68k.cpp index 339a63f6..4b292db9 100644 --- a/build68k.cpp +++ b/build68k.cpp @@ -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; diff --git a/cfgfile.cpp b/cfgfile.cpp index bbcae931..47e45f5f 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -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); +} diff --git a/custom.cpp b/custom.cpp index 775a67a8..9c8d5d68 100644 --- a/custom.cpp +++ b/custom.cpp @@ -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) diff --git a/debug.cpp b/debug.cpp index 39ca7c44..4cff87dd 100644 --- 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); diff --git a/disk.cpp b/disk.cpp index 6696b044..b2880e7d 100644 --- 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; } diff --git a/filesys.cpp b/filesys.cpp index af5c11cf..e4d4ed3f 100644 --- a/filesys.cpp +++ b/filesys.cpp @@ -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) { diff --git a/gayle.cpp b/gayle.cpp index 1be9e28d..d1be1a2f 100644 --- 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); diff --git a/gencpu.cpp b/gencpu.cpp index 2d631e1a..8994d0ec 100644 --- a/gencpu.cpp +++ b/gencpu.cpp @@ -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; diff --git a/gfxboard.cpp b/gfxboard.cpp index 633a6ac8..a03bc4c9 100644 --- a/gfxboard.cpp +++ b/gfxboard.cpp @@ -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]; diff --git a/include/audio.h b/include/audio.h index f72c79ad..c5f43c38 100644 --- a/include/audio.h +++ b/include/audio.h @@ -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); diff --git a/include/cpu_prefetch.h b/include/cpu_prefetch.h index b71c61db..2284d4c0 100644 --- a/include/cpu_prefetch.h +++ b/include/cpu_prefetch.h @@ -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); diff --git a/include/newcpu.h b/include/newcpu.h index 8f647a2d..6c726d94 100644 --- a/include/newcpu.h +++ b/include/newcpu.h @@ -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 diff --git a/include/options.h b/include/options.h index 58074cc6..3614f577 100644 --- a/include/options.h +++ b/include/options.h @@ -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); diff --git a/include/readcpu.h b/include/readcpu.h index 871973df..81f6af16 100644 --- a/include/readcpu.h +++ b/include/readcpu.h @@ -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); diff --git a/include/savestate.h b/include/savestate.h index 9d8b186e..bfd43cf2 100644 --- a/include/savestate.h +++ b/include/savestate.h @@ -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); diff --git a/include/scsi.h b/include/scsi.h index 71cbc9a0..d359f09d 100644 --- a/include/scsi.h +++ b/include/scsi.h @@ -15,6 +15,7 @@ struct scsi_data_tape int beom; bool wp; bool nomedia; + bool unloaded; }; struct scsi_data diff --git a/main.cpp b/main.cpp index 3ad739e0..08f6d3a3 100644 --- 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; diff --git a/memory.cpp b/memory.cpp index 22c20b55..7ac5d1dd 100644 --- a/memory.cpp +++ b/memory.cpp @@ -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++) { diff --git a/newcpu.cpp b/newcpu.cpp index 465bc365..7e46cd72 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -35,6 +35,7 @@ #include "cia.h" #include "inputrecord.h" #include "inputdevice.h" +#include "audio.h" #ifdef JIT #include "jit/compemu.h" #include @@ -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); diff --git a/od-win32/dinput.cpp b/od-win32/dinput.cpp index 68741707..1bcbbcfe 100644 --- a/od-win32/dinput.cpp +++ b/od-win32/dinput.cpp @@ -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 } }; diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index e303987e..bed125e7 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -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; } diff --git a/od-win32/direct3d.h b/od-win32/direct3d.h index 906fddfe..4646082c 100644 --- a/od-win32/direct3d.h +++ b/od-win32/direct3d.h @@ -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); diff --git a/od-win32/hardfile_win32.cpp b/od-win32/hardfile_win32.cpp index 1a135be7..3b208f51 100644 --- a/od-win32/hardfile_win32.cpp +++ b/od-win32/hardfile_win32.cpp @@ -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) { diff --git a/od-win32/mman.cpp b/od-win32/mman.cpp index 741e07b8..67685adc 100644 --- a/od-win32/mman.cpp +++ b/od-win32/mman.cpp @@ -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 { diff --git a/od-win32/resources/resource.h b/od-win32/resources/resource.h index 0e7a13a5..195c5234 100644 --- a/od-win32/resources/resource.h +++ b/od-win32/resources/resource.h @@ -375,6 +375,7 @@ #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 @@ -658,6 +659,8 @@ #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 @@ -1145,6 +1148,8 @@ #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 @@ -1193,9 +1198,9 @@ #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 diff --git a/od-win32/resources/winuae.rc b/od-win32/resources/winuae.rc index 89dbddb7..a3ab0f48 100644 --- a/od-win32/resources/winuae.rc +++ b/od-win32/resources/winuae.rc @@ -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 diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index ca829e89..96be79e5 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -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; diff --git a/od-win32/win32.h b/od-win32/win32.h index de4a1838..3995fb61 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -19,11 +19,11 @@ #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") diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index 8834e64e..6b6e02b1 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -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, ¤tmode->freq, screen_is_picasso ? 1 : currprefs.gfx_filter_filtermode + 1); if (err) { D3D_free (true); gui_message (err); diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index f96107aa..a7630764 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -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); diff --git a/readcpu.cpp b/readcpu.cpp index 018b4d6b..6e7e8aed 100644 --- a/readcpu.cpp +++ b/readcpu.cpp @@ -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++) { diff --git a/savestate.cpp b/savestate.cpp index 95b4af05..e4933bfa 100644 --- a/savestate.cpp +++ b/savestate.cpp @@ -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); diff --git a/scsi.cpp b/scsi.cpp index 5930730f..6d6e7256 100644 --- 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 }; diff --git a/scsiemul.cpp b/scsiemul.cpp index 05ecf0a1..0f094dfb 100644 --- a/scsiemul.cpp +++ b/scsiemul.cpp @@ -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 diff --git a/scsitape.cpp b/scsitape.cpp index 28f5c9a3..9aaf20b6 100644 --- a/scsitape.cpp +++ b/scsitape.cpp @@ -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; diff --git a/table68k b/table68k index ec31efac..60f4421a 100644 --- a/table68k +++ b/table68k @@ -64,28 +64,60 @@ % 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] @@ -98,38 +130,85 @@ 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] @@ -137,33 +216,58 @@ 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 @@ -189,50 +293,92 @@ 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]