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