* 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
#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;
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;
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 ();
}
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);
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:");
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)
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;
/* firmware info */
strcpy (cdrom_result_buffer + 2, FIRMWAREVERSION);
cdrom_result_buffer[0] = cdrom_command;
+ cd_initialized = 1;
return 20;
}
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) {
#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
#endif
cdrom_command_active = 1;
cdrom_command_length = cmd_len;
+ set_status (CDINTERRUPT_TXDMADONE);
return;
}
}
{
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)
{
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);
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;
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++;
{
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 ();
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;
}
{
if (!currprefs.cs_cd32cd)
return;
+ cdrom_return_data ();
cdrom_run_command ();
if (cdrom_command_active > 0) {
cdrom_command_active--;
framecounter--;
if (framecounter <= 0) {
+ int i;
if (cdrom_led)
gui_cd_led (0, 1);
if (cdrom_seek_delay <= 0) {
} 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)
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);
}
}
}
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;
}
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 ();
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 ();
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));
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 ();
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
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;
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;
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);
int strobe; /* COPJMP1 / COPJMP2 accessed */
int last_write, last_write_hpos;
int moveaddr, movedata, movedelay;
- int movedata100, movedelay100;
};
static struct copper cop_state;
// 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)
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;
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)
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];
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;
lightpen_triggered = 1;
}
vpos = 0;
+ lol = 0;
vsync_handler ();
#if 0
if (input_recording > 0) {
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;
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
}
CLXCON (0);
setup_fmodes (0);
sprite_width = GET_SPRITEWIDTH (fmode);
+ new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20;
}
gayle_reset (hardreset);
hdiwstate = DIW_waiting_start;
set_cycles (0);
- new_beamcon0 = currprefs.ntscmode ? 0x00 : 0x20;
hack_vpos = 0;
init_hz ();
vpos_lpen = -1;
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;
}
}
+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 ();
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++;
}
abort ();
}
if (!(flags & GF_APDI)) {
- addcycles (2);
+ addcycles000 (2);
insn_n_cycles += 2;
count_cycles_ea += 2;
}
count_read_ea++;
}
if (!(flags & GF_AD8R)) {
- addcycles (2);
+ addcycles000 (2);
insn_n_cycles += 2;
count_cycles_ea += 2;
}
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;
}
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) {
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",
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) {
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;
}
} 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++;
}
}
c += 2;
}
if (c > 0)
- addcycles (c);
+ addcycles000 (c);
} else if (curi->smode == Dreg) {
int c = 0;
if (curi->dmode == Dreg) {
c += 2;
}
if (c > 0)
- addcycles (c);
+ addcycles000 (c);
}
fill_prefetch_next ();
genastore ("src", curi->dmode, "dstreg", curi->size, "dst");
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");
if (curi->size == sz_byte) {
printf ("\tsrc |= 0xFF00;\n");
}
- addcycles (4);
+ addcycles000 (4);
fill_prefetch_next ();
printf ("\tregs.sr &= src;\n");
printf ("\tMakeFromSR ();\n");
c += 2;
}
if (c > 0)
- addcycles (c);
+ addcycles000 (c);
}
fill_prefetch_next ();
start_brace ();
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 ();
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");
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:
c += 2;
}
if (c > 0)
- addcycles (c);
+ addcycles000 (c);
}
fill_prefetch_next ();
start_brace ();
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 ();
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");
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");
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");
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");
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");
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");
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");
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");
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");
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)
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 ();
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");
case i_RESET:
fill_prefetch_next ();
printf ("\tcpureset ();\n");
- addcycles (128);
+ addcycles000 (128);
if (using_prefetch)
printf ("\tregs.irc = get_iword (4);\n");
break;
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");
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;
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)
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);
}
}
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");
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 ();
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 ();
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);
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;
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;
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.. */
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");
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 ();
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;
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");
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;
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) {
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;
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:
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) {
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;
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);
int j;
if (currprefs.gfx_blackerthanblack) {
- j = i * 15 / 16 + 16;
+ j = i * 15 / 16;
} else {
j = i;
}
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);
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])
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);
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])
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);
}
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)
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);
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);
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;
}
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);
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);
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;
#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];
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;
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)
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);
/* 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 */
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;
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);
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;
}
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;
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)
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;
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 ();
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
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);
+}
del cpuemu_0.c
del cpuemu_11.c
del cpuemu_12.c
+del cpuemu_20.c
del linetoscr.c
cd jit
#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 */
#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""
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))
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)
/* 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);
}
>
</File>
<File
- RelativePath=".\configfile.ico"
+ RelativePath="..\resources\configfile.ico"
>
</File>
<File
- RelativePath="..\resources\configfile.ico"
+ RelativePath=".\configfile.ico"
>
</File>
<File
>
</File>
<File
- RelativePath=".\file.ico"
+ RelativePath="..\resources\file.ico"
>
</File>
<File
- RelativePath="..\resources\file.ico"
+ RelativePath=".\file.ico"
>
</File>
<File
>
</File>
<File
- RelativePath="..\resources\port.ico"
+ RelativePath=".\port.ico"
>
</File>
<File
- RelativePath=".\port.ico"
+ RelativePath="..\resources\port.ico"
>
</File>
<File
>
</File>
<File
- RelativePath="..\..\cpuemu_13.c"
+ RelativePath="..\..\cpuemu_20.c"
>
</File>
<File
+Beta 8:
+
+68020 CE mode updates:
+
+- unaligned word/long accesses emulated (68020 always fetches aligned
+ longs, two accesses required if for example word is fetched
+ from address 3)
+- emulate 68020 instruction cache logic as documented in 68020 manual,
+ cache hits are free, cache misses require normal, possibly slow
+ chip ram fetch
+- approximate emulation of 68020 prefetch buffer, more compatible with
+ self-modifying code
+- very approximate 68020 MUL/DIV cycle usage added
+- 68030/040/060 also supported in "020CE" mode. Not totally useless
+ because this can mean more compatible HD installed games by switching
+ between JIT and "CE" mode on the fly using uae-configuration.
+ (switching between CPU types on the fly isn't very good idea..)
+
+Note that 68020 "CE" is still too fast (CPU internal calculations are
+not counted yet) but this is 100x better than previously because
+memory fetches are emulated, too fast CPU chip memory accesses and
+too fast blitter was the most common cause for problems.
+
+- CD32 drive command communication and interrupt handling rewritten,
+ should now match real hardware (I think..) At least Brian the Lion
+ CD32 works again..
+- automatic vsync mode on the fly switching between 50Hz and 60Hz
+ screen modes if refresh rate is supported, disable vsync temporarily
+ if rate not supported (until switching back to supported rate)
+- Superstardust AGA weapon panel breaks if 1 extra BPLCON0 delay cycle
+ added. Obviously previous fix wasn't right.. Lets try something else,
+ add extra cycle if first bpl dma cycle is allocated (8 planes)
Beta 7:
extra cycles) Quickstart A1200/CD32 most compatible now enables this
new CE-mode. Some weird sound problems can be noticed, reason unknown..
-Two above changes can break lots of things as usual..
+Two above changes can break lots of things as usual.. Binary size also
+increased, 4th CPU core added (68020CE) and finally, next official
+version is now guaranteed to not be 1.6.2..
Beta 6: