From: Toni Wilen Date: Sat, 21 Aug 2010 10:01:41 +0000 (+0300) Subject: 2300b12 X-Git-Tag: 2300~9 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=cfca4f1ab48476176e81965e09782f9608d7039c;p=francis%2Fwinuae.git 2300b12 --- diff --git a/akiko.cpp b/akiko.cpp index 294d2354..77d059c2 100644 --- a/akiko.cpp +++ b/akiko.cpp @@ -503,8 +503,10 @@ static void subfunc (uae_u8 *data, int cnt) static int statusfunc (int status) { - if (status < 0) - return 1000; + if (status == -1) + return 0; + if (status == -2) + return 150; if (cdrom_audiostatus != status) { if (status == AUDIO_STATUS_IN_PROGRESS) { cdrom_playing = 1; diff --git a/blkdev.cpp b/blkdev.cpp index c62e43d6..585a3b70 100644 --- a/blkdev.cpp +++ b/blkdev.cpp @@ -16,10 +16,14 @@ #include "scsidev.h" #include "savestate.h" #include "crc32.h" +#include "threaddep/thread.h" +#include "execio.h" #ifdef RETROPLATFORM #include "rp.h" #endif +int log_scsiemu = 0; + #define PRE_INSERT_DELAY (3 * (currprefs.ntscmode ? 60 : 50)) static int scsiemu[MAX_TOTAL_SCSI_DEVICES]; @@ -28,6 +32,8 @@ static struct device_functions *device_func[MAX_TOTAL_SCSI_DEVICES]; static int openlist[MAX_TOTAL_SCSI_DEVICES]; static int waspaused[MAX_TOTAL_SCSI_DEVICES]; static int delayed[MAX_TOTAL_SCSI_DEVICES]; +static uae_sem_t unitsem[MAX_TOTAL_SCSI_DEVICES]; +static int unitsem_cnt[MAX_TOTAL_SCSI_DEVICES]; /* convert minutes, seconds and frames -> logical sector number */ int msf2lsn (int msf) @@ -222,9 +228,58 @@ void blkdev_fix_prefs (struct uae_prefs *p) } +static bool getsem (int unitnum, bool dowait) +{ + if (unitsem[unitnum] == NULL) + uae_sem_init (&unitsem[unitnum], 0, 1); + bool gotit = false; + if (dowait) { + uae_sem_wait (&unitsem[unitnum]); + gotit = true; + } else { + gotit = uae_sem_trywait (&unitsem[unitnum]) == 0; + } + if (gotit) + unitsem_cnt[unitnum]++; + if (unitsem_cnt[unitnum] > 1) + write_log (L"CD: unitsem%d acquire mismatch! cnt=%d\n", unitnum, unitsem_cnt[unitnum]); + return gotit; +} +static bool getsem (int unitnum) +{ + return getsem (unitnum, false); +} +static void freesem (int unitnum) +{ + unitsem_cnt[unitnum]--; + if (unitsem_cnt[unitnum] < 0) + write_log (L"CD: unitsem%d release mismatch! cnt=%d\n", unitnum, unitsem_cnt[unitnum]); + uae_sem_post (&unitsem[unitnum]); +} +static void sys_command_close_internal (int unitnum) +{ + getsem (unitnum, true); + waspaused[unitnum] = 0; + if (openlist[unitnum] <= 0) + write_log (L"BUG unit %d close: opencnt=%d!\n", unitnum, openlist[unitnum]); + if (device_func[unitnum]) { + device_func[unitnum]->closedev (unitnum); + if (openlist[unitnum] > 0) + openlist[unitnum]--; + } + freesem (unitnum); + if (openlist[unitnum] == 0) { + uae_sem_destroy (&unitsem[unitnum]); + unitsem[unitnum] = NULL; + } +} + static int sys_command_open_internal (int unitnum, const TCHAR *ident, cd_standard_unit csu) { int ret = 0; + if (unitsem[unitnum] == NULL) + uae_sem_init (&unitsem[unitnum], 0, 1); + getsem (unitnum, true); if (openlist[unitnum]) write_log (L"BUG unit %d open: opencnt=%d!\n", unitnum, openlist[unitnum]); if (device_func[unitnum]) { @@ -232,6 +287,7 @@ static int sys_command_open_internal (int unitnum, const TCHAR *ident, cd_standa if (ret) openlist[unitnum]++; } + freesem (unitnum); return ret; } @@ -345,17 +401,9 @@ int sys_command_open (int unitnum) return sys_command_open_internal (unitnum, currprefs.cdslots[unitnum].name[0] ? currprefs.cdslots[unitnum].name : NULL, CD_STANDARD_UNIT_DEFAULT); } - void sys_command_close (int unitnum) { - waspaused[unitnum] = 0; - if (openlist[unitnum] <= 0) - write_log (L"BUG unit %d close: opencnt=%d!\n", unitnum, openlist[unitnum]); - if (device_func[unitnum]) { - device_func[unitnum]->closedev (unitnum); - if (openlist[unitnum] > 0) - openlist[unitnum]--; - } + sys_command_close_internal (unitnum); } void blkdev_cd_change (int unitnum, const TCHAR *name) @@ -430,6 +478,8 @@ static void check_changes (int unitnum) changed = true; if (changed) { + if (unitsem[unitnum]) + getsem (unitnum, true); cdimagefileinuse[unitnum] = changed_prefs.cdslots[unitnum].inuse; _tcscpy (newimagefiles[unitnum], changed_prefs.cdslots[unitnum].name); changed_prefs.cdslots[unitnum].name[0] = currprefs.cdslots[unitnum].name[0] = 0; @@ -451,12 +501,16 @@ static void check_changes (int unitnum) #ifdef RETROPLATFORM rp_cd_image_change (unitnum, NULL); #endif + if (unitsem[unitnum]) + freesem (unitnum); } if (imagechangetime[unitnum] == 0) return; imagechangetime[unitnum]--; if (imagechangetime[unitnum] > 0) return; + if (unitsem[unitnum]) + getsem (unitnum, true); _tcscpy (currprefs.cdslots[unitnum].name, newimagefiles[unitnum]); _tcscpy (changed_prefs.cdslots[unitnum].name, newimagefiles[unitnum]); currprefs.cdslots[unitnum].inuse = changed_prefs.cdslots[unitnum].inuse = cdimagefileinuse[unitnum]; @@ -478,6 +532,9 @@ static void check_changes (int unitnum) #ifdef RETROPLATFORM rp_cd_image_change (unitnum, currprefs.cdslots[unitnum].name); #endif + if (unitsem[unitnum]) + freesem (unitnum); + config_changed = 1; } @@ -508,8 +565,11 @@ static int failunit (int unitnum) static int audiostatus (int unitnum) { + if (!getsem (unitnum)) + return 0; uae_u8 cmd[10] = {0x42,2,0x40,1,0,0,0,(uae_u8)(DEVICE_SCSI_BUFSIZE>>8),(uae_u8)(DEVICE_SCSI_BUFSIZE&0xff),0}; uae_u8 *p = device_func[unitnum]->exec_in (unitnum, cmd, sizeof (cmd), 0); + freesem (unitnum); if (!p) return 0; return p[1]; @@ -520,13 +580,19 @@ int sys_command_cd_pause (int unitnum, int paused) { if (failunit (unitnum)) return -1; + if (!getsem (unitnum)) + return 0; + int v; if (device_func[unitnum]->pause == NULL) { int as = audiostatus (unitnum); uae_u8 cmd[10] = {0x4b,0,0,0,0,0,0,0,paused?0:1,0}; do_scsi (unitnum, cmd, sizeof cmd); - return as == AUDIO_STATUS_PAUSED; + v = as == AUDIO_STATUS_PAUSED; + } else { + v = device_func[unitnum]->pause (unitnum, paused); } - return device_func[unitnum]->pause (unitnum, paused); + freesem (unitnum); + return v; } /* stop CD audio */ @@ -534,48 +600,26 @@ void sys_command_cd_stop (int unitnum) { if (failunit (unitnum)) return; + if (!getsem (unitnum)) + return; if (device_func[unitnum]->stop == NULL) { int as = audiostatus (unitnum); uae_u8 cmd[6] = {0x4e,0,0,0,0,0}; do_scsi (unitnum, cmd, sizeof cmd); - return; - } - device_func[unitnum]->stop (unitnum); -} - -#if 0 -static int adjustplaypos (int unitnum, int startlsn) -{ - uae_u8 q[SUBQ_SIZE]; - if (!device_func[unitnum]->qcode (unitnum, q, startlsn - 1)) - return startlsn; - int otrack = frombcd (q[4 + 1]); - int lsn = startlsn; - int max = 150; - while (max-- > 0 && startlsn > 0) { - if (!device_func[unitnum]->qcode (unitnum, q, startlsn - 1)) - break; - int track = frombcd (q[4 + 1]); - int idx = frombcd (q[4 + 2]); - //write_log (L"%d %d\n", track, idx); - if (idx != 0 || otrack != track) - break; - startlsn--; + } else { + device_func[unitnum]->stop (unitnum); } - if (lsn != startlsn) - write_log (L"CD play adjust %d -> %d\n", lsn, startlsn); - startlsn -= 10; - if (startlsn < 0) - startlsn = 0; - return startlsn; + freesem (unitnum); } -#endif /* play CD audio */ int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int scan) { + int v; if (failunit (unitnum)) return 0; + if (!getsem (unitnum)) + return 0; if (device_func[unitnum]->play == NULL) { uae_u8 cmd[12] = {0,0,0,0,0,0,0,0,0,0,0,0}; int startmsf = lsn2msf (startlsn); @@ -587,145 +631,209 @@ int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int scan) cmd[6] = (uae_u8)(endmsf >> 16); cmd[7] = (uae_u8)(endmsf >> 8); cmd[8] = (uae_u8)(endmsf >> 0); - return do_scsi (unitnum, cmd, sizeof cmd) ? 0 : 1; + v = do_scsi (unitnum, cmd, sizeof cmd) ? 0 : 1; + } else { + v = device_func[unitnum]->play (unitnum, startlsn, endlsn, scan, NULL, NULL); } - //startlsn = adjustplaypos (unitnum, startlsn); - return device_func[unitnum]->play (unitnum, startlsn, endlsn, scan, NULL, NULL); + freesem (unitnum); + return v; } /* play CD audio with subchannels */ int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int scan, play_status_callback statusfunc, play_subchannel_callback subfunc) { + int v; if (failunit (unitnum)) return 0; + if (!getsem (unitnum)) + return 0; if (device_func[unitnum]->play == NULL) - return sys_command_cd_play (unitnum, startlsn, endlsn, scan); - //startlsn = adjustplaypos (unitnum, startlsn); - return device_func[unitnum]->play (unitnum, startlsn, endlsn, scan, statusfunc, subfunc); + v = sys_command_cd_play (unitnum, startlsn, endlsn, scan); + else + v = device_func[unitnum]->play (unitnum, startlsn, endlsn, scan, statusfunc, subfunc); + freesem (unitnum); + return v; } /* set CD audio volume */ uae_u32 sys_command_cd_volume (int unitnum, uae_u16 volume_left, uae_u16 volume_right) { + int v; if (failunit (unitnum)) return 0; + if (!getsem (unitnum)) + return 0; if (device_func[unitnum]->volume == NULL) - return -1; - return device_func[unitnum]->volume (unitnum, volume_left, volume_right); + v = -1; + else + v = device_func[unitnum]->volume (unitnum, volume_left, volume_right); + freesem (unitnum); + return v; } /* read qcode */ int sys_command_cd_qcode (int unitnum, uae_u8 *buf) { + int v; if (failunit (unitnum)) return 0; + if (!getsem (unitnum)) + return 0; if (device_func[unitnum]->qcode == NULL) { uae_u8 cmd[10] = {0x42,2,0x40,1,0,0,0,(uae_u8)(SUBQ_SIZE>>8),(uae_u8)(SUBQ_SIZE&0xff),0}; - return do_scsi (unitnum, cmd, sizeof cmd, buf, SUBQ_SIZE); + v = do_scsi (unitnum, cmd, sizeof cmd, buf, SUBQ_SIZE); + } else { + v = device_func[unitnum]->qcode (unitnum, buf, -1); } - return device_func[unitnum]->qcode (unitnum, buf, -1); + freesem (unitnum); + return v; }; /* read table of contents */ int sys_command_cd_toc (int unitnum, struct cd_toc_head *toc) { + int v; if (failunit (unitnum)) return 0; + if (!getsem (unitnum)) + return 0; if (device_func[unitnum]->toc == NULL) { uae_u8 buf[4 + 8 * 103]; int size = sizeof buf; uae_u8 cmd [10] = { 0x43,0,2,0,0,0,0,(uae_u8)(size>>8),(uae_u8)(size&0xff),0}; if (do_scsi (unitnum, cmd, sizeof cmd, buf, size)) { // toc parse to do - return 0; + v = 0; } - return 0; + v = 0; + } else { + v = device_func[unitnum]->toc (unitnum, toc); } - return device_func[unitnum]->toc (unitnum, toc); + freesem (unitnum); + return v; } /* read one cd sector */ int sys_command_cd_read (int unitnum, uae_u8 *data, int block, int size) { + int v; if (failunit (unitnum)) return 0; + if (!getsem (unitnum)) + return 0; if (device_func[unitnum]->read == NULL) { uae_u8 cmd[12] = { 0xbe, 0, block >> 24, block >> 16, block >> 8, block >> 0, size >> 16, size >> 8, size >> 0, 0x10, 0, 0 }; cmd[1] = 2 << 3; // 2048 if (!do_scsi (unitnum, cmd, sizeof cmd, data, size * 2048)) cmd[1] = 4 << 3; // 2048 mode2 - return do_scsi (unitnum, cmd, sizeof cmd, data, size * 2048); + v = do_scsi (unitnum, cmd, sizeof cmd, data, size * 2048); + } else { + v = device_func[unitnum]->read (unitnum, data, block, size); } - return device_func[unitnum]->read (unitnum, data, block, size); + freesem (unitnum); + return v; } int sys_command_cd_rawread (int unitnum, uae_u8 *data, int block, int size, int sectorsize) { + int v; if (failunit (unitnum)) return -1; + if (!getsem (unitnum)) + return 0; if (device_func[unitnum]->rawread == NULL) { uae_u8 cmd[12] = { 0xbe, 0, block >> 24, block >> 16, block >> 8, block >> 0, size >> 16, size >> 8, size >> 0, 0x10, 0, 0 }; - return do_scsi (unitnum, cmd, sizeof cmd, data, size * sectorsize); + v = do_scsi (unitnum, cmd, sizeof cmd, data, size * sectorsize); + } else { + v = device_func[unitnum]->rawread (unitnum, data, block, size, sectorsize, 0xffffffff); } - return device_func[unitnum]->rawread (unitnum, data, block, size, sectorsize, 0xffffffff); + freesem (unitnum); + return v; } int sys_command_cd_rawread (int unitnum, uae_u8 *data, int block, int size, int sectorsize, uae_u8 sectortype, uae_u8 scsicmd9, uae_u8 subs) { + int v; if (failunit (unitnum)) return -1; + if (!getsem (unitnum)) + return 0; if (device_func[unitnum]->rawread == NULL) { uae_u8 cmd[12] = { 0xbe, 0, block >> 24, block >> 16, block >> 8, block >> 0, size >> 16, size >> 8, size >> 0, 0x10, 0, 0 }; - return do_scsi (unitnum, cmd, sizeof cmd, data, size * sectorsize); + v = do_scsi (unitnum, cmd, sizeof cmd, data, size * sectorsize); + } else { + v = device_func[unitnum]->rawread (unitnum, data, block, size, sectorsize, (sectortype << 16) | (scsicmd9 << 8) | subs); } - return device_func[unitnum]->rawread (unitnum, data, block, size, sectorsize, (sectortype << 16) | (scsicmd9 << 8) | subs); + freesem (unitnum); + return v; } /* read block */ int sys_command_read (int unitnum, uae_u8 *data, int block, int size) { + int v; if (failunit (unitnum)) return 0; + if (!getsem (unitnum)) + return 0; if (device_func[unitnum]->read == NULL) { uae_u8 cmd[12] = { 0xa8, 0, 0, 0, 0, 0, size >> 24, size >> 16, size >> 8, size >> 0, 0, 0 }; cmd[2] = (uae_u8)(block >> 24); cmd[3] = (uae_u8)(block >> 16); cmd[4] = (uae_u8)(block >> 8); cmd[5] = (uae_u8)(block >> 0); - return do_scsi (unitnum, cmd, sizeof cmd, data, size * 2048); + v = do_scsi (unitnum, cmd, sizeof cmd, data, size * 2048); + } else { + v = device_func[unitnum]->read (unitnum, data, block, size); } - return device_func[unitnum]->read (unitnum, data, block, size); + freesem (unitnum); + return v; } /* write block */ int sys_command_write (int unitnum, uae_u8 *data, int offset, int size) { + int v; if (failunit (unitnum)) return 0; - if (device_func[unitnum]->write == NULL) + if (!getsem (unitnum)) return 0; - return device_func[unitnum]->write (unitnum, data, offset, size); + if (device_func[unitnum]->write == NULL) { + v = 0; + } else { + v = device_func[unitnum]->write (unitnum, data, offset, size); + } + freesem (unitnum); + return v; } int sys_command_ismedia (int unitnum, int quick) { + int v; if (failunit (unitnum)) return -1; if (delayed[unitnum]) return 0; + if (!getsem (unitnum)) + return 0; if (device_func[unitnum] == NULL) { uae_u8 cmd[6] = { 0, 0, 0, 0, 0, 0 }; - return do_scsi (unitnum, cmd, sizeof cmd); + v = do_scsi (unitnum, cmd, sizeof cmd); } else { - return device_func[unitnum]->ismedia (unitnum, quick); + v = device_func[unitnum]->ismedia (unitnum, quick); } + freesem (unitnum); + return v; } struct device_info *sys_command_info (int unitnum, struct device_info *di, int quick) { if (failunit (unitnum)) return NULL; + if (!getsem (unitnum)) + return 0; struct device_info *di2 = device_func[unitnum]->info (unitnum, di, quick); if (di2 && delayed[unitnum]) di2->media_inserted = 0; + freesem (unitnum); return di2; } @@ -857,10 +965,13 @@ static bool nodisk (struct device_info *di) } static uae_u64 cmd_readx (int unitnum, uae_u8 *dataptr, int offset, int len) { - if (device_func[unitnum]->read (unitnum, dataptr, offset, len)) - return len; - else + if (!getsem (unitnum)) return 0; + int v = device_func[unitnum]->read (unitnum, dataptr, offset, len); + freesem (unitnum); + if (v) + return len; + return 0; } static void wl (uae_u8 *p, int v) @@ -963,10 +1074,11 @@ static int scsi_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, scsi_len = 0; goto end; } - write_log (L"SCSIEMU %d: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X CMDLEN=%d DATA=%08X LEN=%d\n", unitnum, - cmdbuf[0], cmdbuf[1], cmdbuf[2], cmdbuf[3], cmdbuf[4], cmdbuf[5], cmdbuf[6], - cmdbuf[7], cmdbuf[8], cmdbuf[9], cmdbuf[10], cmdbuf[11], - scsi_cmd_len, scsi_data, *data_len); + if (log_scsiemu) + write_log (L"SCSIEMU %d: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X CMDLEN=%d DATA=%08X LEN=%d\n", unitnum, + cmdbuf[0], cmdbuf[1], cmdbuf[2], cmdbuf[3], cmdbuf[4], cmdbuf[5], cmdbuf[6], + cmdbuf[7], cmdbuf[8], cmdbuf[9], cmdbuf[10], cmdbuf[11], + scsi_cmd_len, scsi_data, *data_len); switch (cmdbuf[0]) { case 0x12: /* INQUIRY */ @@ -1037,7 +1149,8 @@ static int scsi_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, int dbd = cmdbuf[1] & 8; if (cmdbuf[0] == 0x5a) dbd = 1; - write_log (L"MODE SENSE PC=%d CODE=%d DBD=%d\n", pc, pcode, dbd); + if (log_scsiemu) + write_log (L"MODE SENSE PC=%d CODE=%d DBD=%d\n", pc, pcode, dbd); p = r; if (cmdbuf[0] == 0x5a) { p[0] = 8 - 1; @@ -1512,7 +1625,7 @@ end: *data_len = scsi_len; *reply_len = lr; *sense_len = ls; - if (cmdbuf[0]) + if (cmdbuf[0] && log_scsiemu) write_log (L"-> DATAOUT=%d ST=%d SENSELEN=%d\n", scsi_len, status, ls); return status; } @@ -1538,7 +1651,7 @@ static int execscsicmd_direct (int unitnum, struct amigascsi *as) as->cmdactual = as->status != 0 ? 0 : as->cmd_len; /* fake scsi_CmdActual */ if (as->status) { - io_error = 45; /* HFERR_BadStatus */ + io_error = IOERR_BadStatus; as->sense_len = senselen; as->actual = 0; /* scsi_Actual */ } else { @@ -1552,7 +1665,7 @@ static int execscsicmd_direct (int unitnum, struct amigascsi *as) as->sensedata[i] = 0; sactual = 0; if (datalen < 0) { - io_error = 20; /* io_Error, but not specified */ + io_error = IOERR_NotSpecified; as->actual = 0; /* scsi_Actual */ } else { as->len = datalen; @@ -1591,11 +1704,13 @@ int sys_command_scsi_direct (int unitnum, uaecptr acmd) bank = &get_mem_bank (ap); if (!bank || !bank->check(ap, as.len)) - return -5; + return IOERR_BADADDRESS; as.data = bank->xlateaddr (ap); ap = get_long (acmd + 12); as.cmd_len = get_word (acmd + 16); + if (as.cmd_len > sizeof as.cmd) + return IOERR_BADLENGTH; for (i = 0; i < as.cmd_len; i++) as.cmd[i] = get_byte (ap++); while (i < sizeof as.cmd) diff --git a/blkdev_cdimage.cpp b/blkdev_cdimage.cpp index 7918de3d..9012df8f 100644 --- a/blkdev_cdimage.cpp +++ b/blkdev_cdimage.cpp @@ -76,7 +76,7 @@ struct cdunit { int cdda_start, cdda_end; play_subchannel_callback cdda_subfunc; play_status_callback cdda_statusfunc; - int cdda_delay; + int cdda_delay, cdda_delay_frames; int imagechange; TCHAR newfile[MAX_DPATH]; @@ -98,11 +98,14 @@ static struct cdunit *unitisopen (int unitnum) return NULL; } + static struct cdtoc *findtoc (struct cdunit *cdu, int *sectorp) { int i; int sector; + if (*sectorp < 0) + return NULL; sector = *sectorp; for (i = 0; i <= cdu->tracks; i++) { struct cdtoc *t = &cdu->toc[i]; @@ -266,7 +269,7 @@ static void sub_to_deinterleaved (const uae_u8 *s, uae_u8 *d) } } -static int getsub (uae_u8 *dst, struct cdunit *cdu, struct cdtoc *t, int sector) +static int getsub_deinterleaved (uae_u8 *dst, struct cdunit *cdu, struct cdtoc *t, int sector) { int ret = 0; uae_sem_wait (&cdu->sub_sem); @@ -309,29 +312,20 @@ static int getsub (uae_u8 *dst, struct cdunit *cdu, struct cdtoc *t, int sector) return ret; } -static void dosub (struct cdunit *cdu, struct cdtoc *t, int sector) +static void dosub (struct cdunit *cdu, uae_u8 *subbuf) { - uae_u8 *d; - uae_u8 subbuf[SUB_CHANNEL_SIZE]; uae_u8 subbuf2[SUB_CHANNEL_SIZE]; if (!cdu->cdda_subfunc) return; - if (!t) { - memset (subbuf, 0, sizeof subbuf); - cdu->cdda_subfunc (subbuf, 1); + if (!subbuf) { + memset (subbuf2, 0, sizeof subbuf2); + cdu->cdda_subfunc (subbuf2, 1); return; } - memset (subbuf, 0, SUB_CHANNEL_SIZE); - int mode = getsub (subbuf, cdu, t, sector); - if (mode == 2) { // deinterleaved -> interleaved - sub_to_interleaved (subbuf, subbuf2); - d = subbuf2; - } else { - d = subbuf; - } - cdu->cdda_subfunc (d, 1); + sub_to_interleaved (subbuf, subbuf2); + cdu->cdda_subfunc (subbuf2, 1); } static int setstate (struct cdunit *cdu, int state) @@ -400,6 +394,8 @@ static void *cdda_play_func (void *v) MMRESULT mmr; int volume[2], volume_main; int oldplay; + int idleframes; + bool foundsub; struct cdunit *cdu = (struct cdunit*)v; for (i = 0; i < 2; i++) { @@ -441,11 +437,12 @@ static void *cdda_play_func (void *v) int sector, diff; struct _timeb tb1, tb2; + idleframes = 0; + foundsub = false; _ftime (&tb1); cdda_pos = cdu->cdda_start; oldplay = cdu->cdda_play; - cdu->cd_last_pos = cdda_pos; - sector = cdu->cdda_start; + sector = cdu->cd_last_pos = cdda_pos; t = findtoc (cdu, §or); if (!t) { write_log (L"IMAGE CDDA: illegal sector number %d\n", cdu->cdda_start); @@ -463,10 +460,44 @@ static void *cdda_play_func (void *v) while (cdimage_unpack_active == 0) Sleep (10); } + idleframes = cdu->cdda_delay_frames; + while (cdu->cdda_paused && cdu->cdda_play > 0) { + Sleep (10); + idleframes = -1; + } + + if (cdu->cdda_scan == 0) { + // find possible P-subchannel=1 and fudge starting point so that + // buggy CD32/CDTV software CD+G handling does not miss any frames + bool seenindex = false; + for (sector = cdda_pos - 200; sector < cdda_pos; sector++) { + int sec = sector; + t = findtoc (cdu, &sec); + if (t) { + uae_u8 subbuf[SUB_CHANNEL_SIZE]; + getsub_deinterleaved (subbuf, cdu, t, sector); + if (seenindex) { + for (int i = 2 * SUB_ENTRY_SIZE; i < SUB_CHANNEL_SIZE; i++) { + if (subbuf[i]) { // non-zero R-W subchannels + int diff = cdda_pos - sector + 2; + write_log (L"-> CD+G start pos fudge -> %d (%d)\n", sector, -diff); + idleframes -= diff; + cdda_pos = sector; + break; + } + } + } else if (subbuf[0] == 0xff) { // P == 1? + seenindex = true; + } + } + } + } + cdda_pos -= idleframes; + _ftime (&tb2); diff = (tb2.time * (uae_s64)1000 + tb2.millitm) - (tb1.time * (uae_s64)1000 + tb1.millitm); diff -= cdu->cdda_delay; - if (diff < 0 && cdu->cdda_play > 0) + if (idleframes >= 0 && diff < 0 && cdu->cdda_play > 0) Sleep (-diff); setstate (cdu, AUDIO_STATUS_IN_PROGRESS); } @@ -478,7 +509,7 @@ static void *cdda_play_func (void *v) } bufon[bufnum] = 0; - if (!isaudiotrack (&cdu->di.toc, cdda_pos)) { + if (idleframes <= 0 && !isaudiotrack (&cdu->di.toc, cdda_pos)) { setstate (cdu, AUDIO_STATUS_PLAY_ERROR); goto end; // data track? } @@ -493,22 +524,15 @@ static void *cdda_play_func (void *v) memset (px[bufnum], 0, num_sectors * 2352); for (cnt = 0; cnt < num_sectors; cnt++) { + uae_u8 *dst = px[bufnum] + cnt * 2352; + uae_u8 subbuf[SUB_CHANNEL_SIZE]; sector = cdda_pos; - if (cdu->cdda_scan) { - cdda_pos += cdu->cdda_scan; - if (cdda_pos < 0) - cdda_pos = 0; - } else { - cdda_pos++; - } - if (cdda_pos - num_sectors < cdu->cdda_end && cdda_pos >= cdu->cdda_end) - dofinish = 1; + memset (subbuf, 0, SUB_CHANNEL_SIZE); t = findtoc (cdu, §or); if (t) { if (t->handle && !(t->ctrl & 4)) { - uae_u8 *dst = px[bufnum] + cnt * t->size; int totalsize = t->size + t->skipsize; if ((t->enctype == AUDENC_MP3 || t->enctype == AUDENC_FLAC) && t->data) { if (t->filesize >= sector * totalsize + t->offset + t->size) @@ -520,10 +544,36 @@ static void *cdda_play_func (void *v) } } } - dosub (cdu, t, cdda_pos); + getsub_deinterleaved (subbuf, cdu, t, cdda_pos); + } + + if (idleframes > 0) { + idleframes--; + memset (dst, 0, 2352); + memset (subbuf, 0, SUB_CHANNEL_SIZE); + } + + if (cdda_pos < cdu->cdda_start && cdu->cdda_scan == 0) + memset (dst, 0, 2352); + + dosub (cdu, subbuf); + + if (cdu->cdda_scan) { + cdda_pos += cdu->cdda_scan; + if (cdda_pos < 0) + cdda_pos = 0; + } else { + cdda_pos++; } + + if (cdda_pos - num_sectors < cdu->cdda_end && cdda_pos >= cdu->cdda_end) + dofinish = 1; + } + if (idleframes <= 0) + cdu->cd_last_pos = cdda_pos; + volume_main = currprefs.sound_volume; int vol_mult[2]; for (int j = 0; j < 2; j++) { @@ -547,8 +597,6 @@ static void *cdda_play_func (void *v) break; } - cdu->cd_last_pos = cdda_pos; - if (dofinish) { setstate (cdu, AUDIO_STATUS_PLAY_COMPLETE); cdu->cdda_play = -1; @@ -597,6 +645,7 @@ static void cdda_stop (struct cdunit *cdu) } } cdu->cdda_paused = 0; + cdu->cdda_play_state = 0; } @@ -631,6 +680,7 @@ static int command_play (int unitnum, int startlsn, int endlsn, int scan, play_s cdu->cdda_statusfunc = statusfunc; cdu->cdda_scan = scan > 0 ? 10 : (scan < 0 ? 10 : 0); cdu->cdda_delay = setstate (cdu, -1); + cdu->cdda_delay_frames = setstate (cdu, -2); setstate (cdu, AUDIO_STATUS_NOT_SUPPORTED); if (!isaudiotrack (&cdu->di.toc, startlsn)) { setstate (cdu, AUDIO_STATUS_PLAY_ERROR); @@ -684,7 +734,7 @@ static int command_qcode (int unitnum, uae_u8 *buf, int sector) } if (!td) return 0; - getsub (subbuf, cdu, td, pos); + getsub_deinterleaved (subbuf, cdu, td, pos); memcpy (p, subbuf + 12, 12); // write_log (L"%6d %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x\n", // pos, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11]); @@ -713,7 +763,8 @@ static int command_rawread (int unitnum, uae_u8 *data, int sector, int size, int struct cdtoc *t = findtoc (cdu, §or); if (!t || t->handle == NULL) - return 0; + goto end; + cdda_stop (cdu); if (sectorsize > 0) { if (sectorsize == 2352 && t->size == 2048) { @@ -765,21 +816,27 @@ static int command_rawread (int unitnum, uae_u8 *data, int sector, int size, int int edcecc = (cmd9 >> 3) & 1; int errorfield = (cmd9 >> 1) & 3; uae_u8 subs = extra & 7; - if (subs != 0 && subs != 1 && subs != 2 && subs != 4) - return -1; + if (subs != 0 && subs != 1 && subs != 2 && subs != 4) { + ret = -1; + goto end; + } if (isaudiotrack (&cdu->di.toc, sector)) { - if (sectortype != 0 && sectortype != 1) - return -2; - if (t->size != 2352) - return -1; + if (sectortype != 0 && sectortype != 1) { + ret = -2; + goto end; + } + if (t->size != 2352) { + ret = -1; + goto end; + } for (int i = 0; i < size; i++) { zfile_fseek (t->handle, t->offset + sector * t->size, SEEK_SET); zfile_fread (data, t->size, 1, t->handle); uae_u8 *p = data + t->size; if (subs) { uae_u8 subdata[SUB_CHANNEL_SIZE]; - getsub (subdata, cdu, t, sector); + getsub_deinterleaved (subdata, cdu, t, sector); if (subs == 4) { // all, de-interleaved memcpy (p, subdata, SUB_CHANNEL_SIZE); p += SUB_CHANNEL_SIZE; @@ -797,6 +854,7 @@ static int command_rawread (int unitnum, uae_u8 *data, int sector, int size, int } } } +end: return ret; } @@ -810,7 +868,7 @@ static int command_read (int unitnum, uae_u8 *data, int sector, int size) struct cdtoc *t = findtoc (cdu, §or); if (!t || t->handle == NULL) - return NULL; + return 0; cdda_stop (cdu); if (t->size == 2048) { zfile_fseek (t->handle, t->offset + sector * t->size, SEEK_SET); @@ -1556,7 +1614,6 @@ static int parse_image (struct cdunit *cdu, const TCHAR *img) return 1; } - static int ismedia (int unitnum, int quick) { struct cdunit *cdu = &cdunits[unitnum]; @@ -1623,44 +1680,46 @@ static void unload_image (struct cdunit *cdu) static int open_device (int unitnum, const TCHAR *ident, int flags) { struct cdunit *cdu = &cdunits[unitnum]; + int ret = 0; - if (cdu->open) - return 0; - uae_sem_init (&cdu->sub_sem, 0, 1); - parse_image (cdu, ident); - cdu->open = true; - cdu->enabled = true; - cdu->cdda_volume[0] = 0x7fff; - cdu->cdda_volume[1] = 0x7fff; - blkdev_cd_change (unitnum, currprefs.cdslots[unitnum].name); - if (cdimage_unpack_thread == 0) { - init_comm_pipe (&unpack_pipe, 10, 1); - uae_start_thread (L"cdimage_unpack", cdda_unpack_func, NULL, NULL); - while (cdimage_unpack_thread == 0) - Sleep (10); + if (!cdu->open) { + uae_sem_init (&cdu->sub_sem, 0, 1); + parse_image (cdu, ident); + cdu->open = true; + cdu->enabled = true; + cdu->cdda_volume[0] = 0x7fff; + cdu->cdda_volume[1] = 0x7fff; + if (cdimage_unpack_thread == 0) { + init_comm_pipe (&unpack_pipe, 10, 1); + uae_start_thread (L"cdimage_unpack", cdda_unpack_func, NULL, NULL); + while (cdimage_unpack_thread == 0) + Sleep (10); + } + ret = 1; } - return 1; + blkdev_cd_change (unitnum, currprefs.cdslots[unitnum].name); + return ret; } static void close_device (int unitnum) { struct cdunit *cdu = &cdunits[unitnum]; - if (cdu->open == false) - return; - cdda_stop (cdu); - unload_image (cdu); - uae_sem_destroy (&cdu->sub_sem); - cdu->open = false; - blkdev_cd_change (unitnum, currprefs.cdslots[unitnum].name); - if (cdimage_unpack_thread) { - cdimage_unpack_thread = 0; - write_comm_pipe_u32 (&unpack_pipe, -1, 0); - write_comm_pipe_u32 (&unpack_pipe, -1, 1); - while (cdimage_unpack_thread == 0) - Sleep (10); - cdimage_unpack_thread = 0; - destroy_comm_pipe (&unpack_pipe); + if (cdu->open) { + cdda_stop (cdu); + unload_image (cdu); + uae_sem_destroy (&cdu->sub_sem); + cdu->open = false; + if (cdimage_unpack_thread) { + cdimage_unpack_thread = 0; + write_comm_pipe_u32 (&unpack_pipe, -1, 0); + write_comm_pipe_u32 (&unpack_pipe, -1, 1); + while (cdimage_unpack_thread == 0) + Sleep (10); + cdimage_unpack_thread = 0; + destroy_comm_pipe (&unpack_pipe); + } } + blkdev_cd_change (unitnum, currprefs.cdslots[unitnum].name); } static void close_bus (void) diff --git a/cdtv.cpp b/cdtv.cpp index 2daf2bf6..268ba4fd 100644 --- a/cdtv.cpp +++ b/cdtv.cpp @@ -268,8 +268,10 @@ static void subfunc (uae_u8 *data, int cnt) } static int statusfunc (int status) { - if (status < 0) + if (status == -1) return 500; + if (status == -2) + return 75; if (cd_audio_status != status) { if (status == AUDIO_STATUS_PLAY_COMPLETE || status == AUDIO_STATUS_PLAY_ERROR) { cd_audio_finished = 1; @@ -515,6 +517,8 @@ static void cdrom_command_thread (uae_u8 b) if (cdrom_command_cnt_in == 7) { cdrom_command_accepted (0, s, &cdrom_command_cnt_in); cd_finished = 1; + sleep_millis (500); + activate_stch = 1; } break; case 0x02: /* read */ diff --git a/cfgfile.cpp b/cfgfile.cpp index d0dfd982..3fcea0ab 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -1194,7 +1194,8 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) *next2++ = 0; cfgfile_intval (option, next, tmp, &unitnum, 1); } - _tcsncpy (p->cdslots[i].name, value, sizeof p->cdslots[i].name / sizeof (TCHAR)); + if (_tcslen (value) > 0) + _tcsncpy (p->cdslots[i].name, value, sizeof p->cdslots[i].name / sizeof (TCHAR)); p->cdslots[i].name[sizeof p->cdslots[i].name - 1] = 0; p->cdslots[i].inuse = true; p->cdslots[i].type = type; @@ -1650,9 +1651,9 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value) return 0; } -static void decode_rom_ident (TCHAR *romfile, int maxlen, TCHAR *ident) +static void decode_rom_ident (TCHAR *romfile, int maxlen, const TCHAR *ident, int romflags) { - TCHAR *p; + const TCHAR *p; int ver, rev, subver, subrev, round, i; TCHAR model[64], *modelp; struct romlist **rl; @@ -1670,29 +1671,29 @@ static void decode_rom_ident (TCHAR *romfile, int maxlen, TCHAR *ident) while (*p) { TCHAR c = *p++; int *pp1 = NULL, *pp2 = NULL; - if (_totupper(c) == 'V' && _istdigit(*p)) { + if (_totupper (c) == 'V' && _istdigit (*p)) { pp1 = &ver; pp2 = &rev; - } else if (_totupper(c) == 'R' && _istdigit(*p)) { + } else if (_totupper (c) == 'R' && _istdigit (*p)) { pp1 = &subver; pp2 = &subrev; - } else if (!_istdigit(c) && c != ' ') { - _tcsncpy (model, p - 1, (sizeof model) - 1); + } else if (!_istdigit (c) && c != ' ') { + _tcsncpy (model, p - 1, (sizeof model) / sizeof (TCHAR) - 1); p += _tcslen (model); modelp = model; } if (pp1) { - *pp1 = _tstol(p); + *pp1 = _tstol (p); while (*p != 0 && *p != '.' && *p != ' ') p++; if (*p == '.') { p++; if (pp2) - *pp2 = _tstol(p); + *pp2 = _tstol (p); } } if (*p == 0 || *p == ';') { - rl = getromlistbyident (ver, rev, subver, subrev, modelp, round); + rl = getromlistbyident (ver, rev, subver, subrev, modelp, romflags, round > 0); if (rl) { for (i = 0; rl[i]; i++) { if (round) { @@ -1812,7 +1813,7 @@ static void parse_addmem (struct uae_prefs *p, TCHAR *buf, int num) p->custom_memory_sizes[num] = size; } -static int cfgfile_parse_hardware (struct uae_prefs *p, TCHAR *option, TCHAR *value) +static int cfgfile_parse_hardware (struct uae_prefs *p, const TCHAR *option, TCHAR *value) { int tmpval, dummyint, i; bool tmpbool, dummybool; @@ -1964,15 +1965,15 @@ static int cfgfile_parse_hardware (struct uae_prefs *p, TCHAR *option, TCHAR *va return 1; } if (cfgfile_string (option, value, L"kickstart_rom", p->romident, sizeof p->romident / sizeof (TCHAR))) { - decode_rom_ident (p->romfile, sizeof p->romfile / sizeof (TCHAR), p->romident); + decode_rom_ident (p->romfile, sizeof p->romfile / sizeof (TCHAR), p->romident, ROMTYPE_ALL_KICK); return 1; } if (cfgfile_string (option, value, L"kickstart_ext_rom", p->romextident, sizeof p->romextident / sizeof (TCHAR))) { - decode_rom_ident (p->romextfile, sizeof p->romextfile / sizeof (TCHAR), p->romextident); + decode_rom_ident (p->romextfile, sizeof p->romextfile / sizeof (TCHAR), p->romextident, ROMTYPE_ALL_EXT); return 1; } if (cfgfile_string (option, value, L"cart", p->cartident, sizeof p->cartident / sizeof (TCHAR))) { - decode_rom_ident (p->cartfile, sizeof p->cartfile / sizeof (TCHAR), p->cartident); + decode_rom_ident (p->cartfile, sizeof p->cartfile / sizeof (TCHAR), p->cartident, ROMTYPE_ALL_CART); return 1; } diff --git a/cia.cpp b/cia.cpp index f7e205a6..03d7fcdb 100644 --- a/cia.cpp +++ b/cia.cpp @@ -625,12 +625,8 @@ static uae_u8 ReadCIAA (unsigned int addr) action_replay_ciaread (); #endif tmp = DISK_status() & 0x3c; - tmp |= handle_joystick_buttons (ciaadra); + tmp |= handle_joystick_buttons (ciaapra, ciaadra); tmp |= (ciaapra | (ciaadra ^ 3)) & 0x03; - if (ciaadra & 0x40) - tmp = (tmp & ~0x40) | (ciaapra & 0x40); - if (ciaadra & 0x80) - tmp = (tmp & ~0x80) | (ciaapra & 0x80); tmp = dongle_cia_read (0, reg, tmp); #if DONGLE_DEBUG > 0 if (notinrom()) diff --git a/disk.cpp b/disk.cpp index 2ef4e976..1c7c0343 100644 --- a/disk.cpp +++ b/disk.cpp @@ -876,7 +876,6 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR int canauto; const TCHAR *ext; - gui_disk_image_change (dnum, fname); drive_image_free (drv); DISK_validate_filename (fname, 1, &drv->wrprot, &drv->crc32, &drv->diskfile); drv->ddhd = 1; @@ -886,6 +885,8 @@ static int drive_insert (drive * drv, struct uae_prefs *p, int dnum, const TCHAR drv->useturbo = 0; drv->indexoffset = 0; + gui_disk_image_change (dnum, fname, drv->wrprot); + canauto = 0; ext = _tcsrchr (fname, '.'); if (ext) { @@ -2005,7 +2006,7 @@ static void drive_eject (drive * drv) #ifdef DRIVESOUND driveclick_insert (drv - floppy, 1); #endif - gui_disk_image_change (drv - floppy, NULL); + gui_disk_image_change (drv - floppy, NULL, drv->wrprot); drive_image_free (drv); drv->dskchange = 1; drv->ddhd = 1; @@ -2134,7 +2135,7 @@ int disk_getwriteprotect (const TCHAR *name) return diskfile_iswriteprotect (name, &needwritefile, &drvtype); } -static void diskfile_readonly (const TCHAR *name, int readonly) +static void diskfile_readonly (const TCHAR *name, bool readonly) { struct _stat64 st; int mode, oldmode; @@ -2143,7 +2144,8 @@ static void diskfile_readonly (const TCHAR *name, int readonly) return; oldmode = mode = st.st_mode; mode &= ~FILEFLAG_WRITE; - if (!readonly) mode |= FILEFLAG_WRITE; + if (!readonly) + mode |= FILEFLAG_WRITE; if (mode != oldmode) chmod (name, mode); } @@ -2170,7 +2172,7 @@ void DISK_reinsert (int num) setdskchangetime (&floppy[num], 20); } -int disk_setwriteprotect (int num, const TCHAR *name, int protect) +int disk_setwriteprotect (int num, const TCHAR *name, bool writeprotected) { int needwritefile, oldprotect; struct zfile *zf1, *zf2; @@ -2192,7 +2194,7 @@ int disk_setwriteprotect (int num, const TCHAR *name, int protect) if (needwritefile && zf2 == 0) disk_creatediskfile (name2, 1, drvtype, NULL); zfile_fclose (zf2); - if (protect && iswritefileempty (name)) { + if (writeprotected && iswritefileempty (name)) { for (i = 0; i < MAX_FLOPPY_DRIVES; i++) { if (!_tcscmp (name, floppy[i].newname)) drive_eject (&floppy[i]); @@ -2201,8 +2203,8 @@ int disk_setwriteprotect (int num, const TCHAR *name, int protect) } if (!needwritefile) - diskfile_readonly (name, protect); - diskfile_readonly (name2, protect); + diskfile_readonly (name, writeprotected); + diskfile_readonly (name2, writeprotected); DISK_reinsert (num); return 1; } @@ -3125,14 +3127,14 @@ void DSKLEN (uae_u16 v, int hpos) break; } if (dr == 4) { - write_log (L"disk %s DMA started, drvmask=%x motormask=%x\n", - dskdmaen == 3 ? L"write" : L"read", selected ^ 15, motormask); + write_log (L"disk %s DMA started, drvmask=%x motormask=%x PC=%08x\n", + dskdmaen == 3 ? L"write" : L"read", selected ^ 15, motormask, M68K_GETPC); noselected = 1; } else { if (disk_debug_logging > 0) { - write_log (L"disk %s DMA started, drvmask=%x track %d mfmpos %d dmaen=%d\n", + write_log (L"disk %s DMA started, drvmask=%x track %d mfmpos %d dmaen=%d PC=%08X\n", dskdmaen == 3 ? L"write" : L"read", selected ^ 15, - floppy[dr].cyl * 2 + side, floppy[dr].mfmpos, dma_enable); + floppy[dr].cyl * 2 + side, floppy[dr].mfmpos, dma_enable, M68K_GETPC); disk_dma_debugmsg (); } } diff --git a/include/disk.h b/include/disk.h index a6a38f9b..4ec56ac4 100644 --- a/include/disk.h +++ b/include/disk.h @@ -27,7 +27,7 @@ extern void DISK_update_adkcon (int hpos, uae_u16 v); extern void DISK_hsync (void); extern void DISK_reset (void); extern int disk_getwriteprotect (const TCHAR *name); -extern int disk_setwriteprotect (int num, const TCHAR *name, int protect); +extern int disk_setwriteprotect (int num, const TCHAR *name, bool writeprotected); extern void disk_creatediskfile (TCHAR *name, int type, drive_type adftype, TCHAR *disk_name); extern void dumpdisk (void); extern int DISK_history_add (const TCHAR *name, int idx, int type, int donotcheck); diff --git a/include/execio.h b/include/execio.h index 8e5f3854..6a0465a8 100644 --- a/include/execio.h +++ b/include/execio.h @@ -7,27 +7,27 @@ #define IOERR_UNITBUSY -6 #define IOERR_SELFTEST -7 -#define CDERR_NotSpecified 20 /* general catchall */ -#define CDERR_NoSecHdr 21 /* couldn't even find a sector */ -#define CDERR_BadSecPreamble 22 /* sector looked wrong */ -#define CDERR_BadSecID 23 /* ditto */ -#define CDERR_BadHdrSum 24 /* header had incorrect checksum */ -#define CDERR_BadSecSum 25 /* data had incorrect checksum */ -#define CDERR_TooFewSecs 26 /* couldn't find enough sectors */ -#define CDERR_BadSecHdr 27 /* another "sector looked wrong" */ -#define CDERR_WriteProt 28 /* can't write to a protected disk */ -#define CDERR_NoDisk 29 /* no disk in the drive */ -#define CDERR_SeekError 30 /* couldn't find track 0 */ -#define CDERR_NoMem 31 /* ran out of memory */ -#define CDERR_BadUnitNum 32 /* asked for a unit > NUMUNITS */ -#define CDERR_BadDriveType 33 /* not a drive cd.device understands */ -#define CDERR_DriveInUse 34 /* someone else allocated the drive */ -#define CDERR_PostReset 35 /* user hit reset; awaiting doom */ -#define CDERR_BadDataType 36 /* data on disk is wrong type */ -#define CDERR_InvalidState 37 /* invalid cmd under current conditions */ - -#define CDERR_Phase 42 /* illegal or unexpected SCSI phase */ -#define CDERR_NoBoard 50 /* open failed for non-existant board */ +#define IOERR_NotSpecified 20 /* general catchall */ +#define IOERR_NoSecHdr 21 /* couldn't even find a sector */ +#define IOERR_BadSecPreamble 22 /* sector looked wrong */ +#define IOERR_BadSecID 23 /* ditto */ +#define IOERR_BadHdrSum 24 /* header had incorrect checksum */ +#define IOERR_BadSecSum 25 /* data had incorrect checksum */ +#define IOERR_TooFewSecs 26 /* couldn't find enough sectors */ +#define IOERR_BadSecHdr 27 /* another "sector looked wrong" */ +#define IOERR_WriteProt 28 /* can't write to a protected disk */ +#define IOERR_NoDisk 29 /* no disk in the drive */ +#define IOERR_SeekError 30 /* couldn't find track 0 */ +#define IOERR_NoMem 31 /* ran out of memory */ +#define IOERR_BadUnitNum 32 /* asked for a unit > NUMUNITS */ +#define IOERR_BadDriveType 33 /* not a drive cd.device understands */ +#define IOERR_DriveInUse 34 /* someone else allocated the drive */ +#define IOERR_PostReset 35 /* user hit reset; awaiting doom */ +#define IOERR_BadDataType 36 /* data on disk is wrong type */ +#define IOERR_InvalidState 37 /* invalid cmd under current conditions */ +#define IOERR_BadStatus 45 +#define IOERR_Phase 42 /* illegal or unexpected SCSI phase */ +#define IOERR_NoBoard 50 /* open failed for non-existant board */ #define TDERR_DiskChanged 29 diff --git a/include/gui.h b/include/gui.h index ac65ba66..e28e24e1 100644 --- a/include/gui.h +++ b/include/gui.h @@ -17,7 +17,7 @@ extern void gui_changesettings (void); extern void gui_lock (void); extern void gui_unlock (void); extern void gui_flicker_led (int, int, int); -extern void gui_disk_image_change (int, const TCHAR *); +extern void gui_disk_image_change (int, const TCHAR *, bool writeprotected); extern unsigned int gui_ledstate; extern void gui_display (int shortcut); diff --git a/include/inputdevice.h b/include/inputdevice.h index af909049..9bedd0ea 100644 --- a/include/inputdevice.h +++ b/include/inputdevice.h @@ -106,7 +106,7 @@ INPUTEVENT_END extern void handle_cd32_joystick_cia (uae_u8, uae_u8); extern uae_u8 handle_parport_joystick (int port, uae_u8 pra, uae_u8 dra); -extern uae_u8 handle_joystick_buttons (uae_u8); +extern uae_u8 handle_joystick_buttons (uae_u8, uae_u8); extern int getbuttonstate (int joy, int button); extern int getjoystate (int joy); @@ -162,7 +162,7 @@ extern void inputdevice_hsync (void); extern void inputdevice_reset (void); extern void write_inputdevice_config (struct uae_prefs *p, struct zfile *f); -extern void read_inputdevice_config (struct uae_prefs *p, TCHAR *option, TCHAR *value); +extern void read_inputdevice_config (struct uae_prefs *p, const TCHAR *option, TCHAR *value); extern void reset_inputdevice_config (struct uae_prefs *pr); extern int inputdevice_joyport_config (struct uae_prefs *p, TCHAR *value, int portnum, int mode, int type); extern int inputdevice_getjoyportdevice (int port, int val); diff --git a/include/rommgr.h b/include/rommgr.h index b62c75da..cd0458c3 100644 --- a/include/rommgr.h +++ b/include/rommgr.h @@ -24,6 +24,10 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size); #define ROMTYPE_CD32 0x200000 #define ROMTYPE_SCRAMBLED 0x400000 +#define ROMTYPE_ALL_KICK (ROMTYPE_KICK | ROMTYPE_KICKCD32 | ROMTYPE_CD32) +#define ROMTYPE_ALL_EXT (ROMTYPE_EXTCD32 | ROMTYPE_EXTCDTV) +#define ROMTYPE_ALL_CART (ROMTYPE_AR | ROMTYPE_HRTMON | ROMTYPE_NORDIC | ROMTYPE_XPOWER | ROMTYPE_CD32CART) + struct romheader { TCHAR *name; int id; @@ -60,7 +64,7 @@ extern struct romdata *getromdatabyidgroup (int id, int group, int subitem); extern struct romdata *getromdatabyzfile (struct zfile *f); extern struct romlist **getarcadiaroms (void); extern struct romdata *getarcadiarombyname (const TCHAR *name); -extern struct romlist **getromlistbyident (int ver, int rev, int subver, int subrev, const TCHAR *model, int all); +extern struct romlist **getromlistbyident (int ver, int rev, int subver, int subrev, const TCHAR *model, int romflags, bool all); extern void getromname (const struct romdata*, TCHAR*); extern struct romdata *getromdatabyname (const TCHAR*); extern struct romlist *getromlistbyids (const int *ids); diff --git a/inputdevice.cpp b/inputdevice.cpp index 15074d00..19c8f8cd 100644 --- a/inputdevice.cpp +++ b/inputdevice.cpp @@ -48,6 +48,10 @@ #include "rp.h" #include "dongle.h" #include "cdtv.h" +#ifdef RETROPLATFORM +#include "rp.h" +#include "cloanto/RetroPlatformIPC.h" +#endif extern int bootrom_header, bootrom_items; @@ -774,9 +778,9 @@ void write_inputdevice_config (struct uae_prefs *p, struct zfile *f) } } -static int getnum (TCHAR **pp) +static int getnum (const TCHAR **pp) { - TCHAR *p = *pp; + const TCHAR *p = *pp; int v; if (!_tcsnicmp (p, L"false", 5)) @@ -793,11 +797,11 @@ static int getnum (TCHAR **pp) *pp = p; return v; } -static TCHAR *getstring (TCHAR **pp) +static TCHAR *getstring (const TCHAR **pp) { int i; static TCHAR str[1000]; - TCHAR *p = *pp; + const TCHAR *p = *pp; if (*p == 0) return 0; @@ -960,7 +964,7 @@ static bool readslot (TCHAR *parm, int num, int joystick, int button, struct uae return true; } -static struct inputevent *readevent (TCHAR *name, TCHAR **customp) +static struct inputevent *readevent (const TCHAR *name, TCHAR **customp) { int i = 1; while (events[i].name) { @@ -976,12 +980,13 @@ static struct inputevent *readevent (TCHAR *name, TCHAR **customp) return &events[0]; } -void read_inputdevice_config (struct uae_prefs *pr, TCHAR *option, TCHAR *value) +void read_inputdevice_config (struct uae_prefs *pr, const TCHAR *option, TCHAR *value) { struct uae_input_device *id = 0; struct inputevent *ie; int devnum, num, button, joystick, subnum, idnum, keynum; - TCHAR *p, *p2, *custom; + const TCHAR *p; + TCHAR *p2, *custom; option += 6; /* "input." */ p = getstring (&option); @@ -2104,12 +2109,13 @@ static void cap_check (void) int isbutton = getbuttonstate (joy, i == 0 ? JOYBUTTON_3 : JOYBUTTON_2); if (cd32_pad_enabled[joy]) { - if (i == 0) // 3rd button? - continue; - if (cd32padmode (p5dir, p5dat)) - continue; // only red and blue can be read if CD32 pad and only if it is in normal pad mode isbutton |= getbuttonstate (joy, JOYBUTTON_CD32_BLUE); + // CD32 pad 3rd button line (P5) is always floating + if (i == 0) + isbutton = 0; + if (cd32padmode (p5dir, p5dat)) + continue; } dong = dongle_analogjoy (joy, i); @@ -2164,6 +2170,10 @@ static void cap_check (void) if (!(potgo_value & pdir) && i == 1 && charge == 0) charge = 2; } + // CD32 pad in 2-button mode: blue button is not floating + if (cd32_pad_enabled[joy] && i == 1 && charge == 0) + charge = 2; + /* official Commodore mouse has pull-up resistors in button lines * NOTE: 3rd party mice may not have pullups! */ if (dong < 0 && (mouse_pullup && mouse_port[joy] && digital_port[joy][i]) && charge == 0) @@ -2181,7 +2191,7 @@ static void cap_check (void) } -uae_u8 handle_joystick_buttons (uae_u8 dra) +uae_u8 handle_joystick_buttons (uae_u8 pra, uae_u8 dra) { uae_u8 but = 0; int i; @@ -2192,9 +2202,9 @@ uae_u8 handle_joystick_buttons (uae_u8 dra) if (cd32_pad_enabled[i]) { uae_u16 p5dir = 0x0200 << (i * 4); uae_u16 p5dat = 0x0100 << (i * 4); - but |= 0x40 << i; + but |= mask; if (!cd32padmode (p5dir, p5dat)) { - if (getbuttonstate (i, JOYBUTTON_CD32_RED)) + if (getbuttonstate (i, JOYBUTTON_CD32_RED) || getbuttonstate (i, JOYBUTTON_1)) but &= ~mask; } } else { @@ -2205,11 +2215,11 @@ uae_u8 handle_joystick_buttons (uae_u8 dra) if (uaerand () & 1) but |= mask; } - + if (dra & mask) + but = (but & ~mask) | (pra & mask); } } - if (inputdevice_logging & 4) write_log (L"BFE001: %02X:%02X %x\n", dra, but, M68K_GETPC); return but; @@ -2836,10 +2846,17 @@ int handle_input_event (int nr, int state, int max, int autofire) if (ie->type & 4) { int old = joybutton[joy] & (1 << ie->data); - if (state) + if (state) { joybutton[joy] |= 1 << ie->data; - else +#ifdef RETROPLATFORM + rp_update_gameport (joy, RP_JOYSTICK_BUTTON1 << ie->data, 1); +#endif + } else { joybutton[joy] &= ~(1 << ie->data); +#ifdef RETROPLATFORM + rp_update_gameport (joy, RP_JOYSTICK_BUTTON1 << ie->data, 0); +#endif + } if (ie->data == 0 && old != (joybutton[joy] & (1 << ie->data)) && currprefs.cpu_cycle_exact) { // emulate contact bounce, 1st button only, others have capacitors @@ -2971,7 +2988,12 @@ int handle_input_event (int nr, int state, int max, int autofire) joydir[joy] |= DIR_UP; if (bot) joydir[joy] |= DIR_DOWN; - +#ifdef RETROPLATFORM + rp_update_gameport (joy, RP_JOYSTICK_LEFT, left); + rp_update_gameport (joy, RP_JOYSTICK_RIGHT, right); + rp_update_gameport (joy, RP_JOYSTICK_DOWN, bot); + rp_update_gameport (joy, RP_JOYSTICK_UP, top); +#endif } break; case 0: /* ->KEY */ @@ -4441,6 +4463,8 @@ void inputdevice_updateconfig (struct uae_prefs *prefs) rp_input_change (1); rp_input_change (2); rp_input_change (3); + for (i = 0; i < MAX_JPORTS; i++) + rp_update_gameport (i, -1, 0); #endif joybutton[0] = joybutton[1] = 0; @@ -5457,7 +5481,7 @@ void setjoystickstate (int joy, int axis, int state, int max) return; } for (i = 0; i < MAX_INPUT_SUB_EVENT; i++) - handle_input_event (id->eventid[ID_AXIS_OFFSET + axis][i], state, max, id->flags[ID_AXIS_OFFSET + axis][i]); + handle_input_event (id->eventid[ID_AXIS_OFFSET + axis][i], state, max, id->flags[ID_AXIS_OFFSET + axis][i] & ID_FLAG_AUTOFIRE); id2->states[axis] = state; } int getjoystickstate (int joy) diff --git a/od-win32/blkdev_win32_ioctl.cpp b/od-win32/blkdev_win32_ioctl.cpp index b9081bbe..85154bec 100644 --- a/od-win32/blkdev_win32_ioctl.cpp +++ b/od-win32/blkdev_win32_ioctl.cpp @@ -55,7 +55,7 @@ struct dev_info_ioctl { int cdda_volume[2]; int cdda_scan; int cdda_volume_main; - uae_u32 cd_last_pos; + int cd_last_pos; HWAVEOUT cdda_wavehandle; int cdda_start, cdda_end; uae_u8 subcode[SUB_CHANNEL_SIZE * CDDA_BUFFERS]; @@ -64,7 +64,7 @@ struct dev_info_ioctl { play_subchannel_callback cdda_subfunc; play_status_callback cdda_statusfunc; int cdda_play_state; - int cdda_delay; + int cdda_delay, cdda_delay_frames; struct device_info di; uae_sem_t sub_sem, sub_sem2; bool open; @@ -263,6 +263,34 @@ static int spti_inquiry (struct dev_info_ioctl *ciw, int unitnum, uae_u8 *data) return 1; } +static void sub_deinterleave (const uae_u8 *s, uae_u8 *d) +{ + for (int i = 0; i < 8 * 12; i ++) { + int dmask = 0x80; + int smask = 1 << (7 - (i / 12)); + (*d) = 0; + for (int j = 0; j < 8; j++) { + (*d) |= (s[(i % 12) * 8 + j] & smask) ? dmask : 0; + dmask >>= 1; + } + d++; + } +} + +static void sub_to_deinterleaved (const uae_u8 *s, uae_u8 *d) +{ + for (int i = 0; i < 8 * 12; i ++) { + int dmask = 0x80; + int smask = 1 << (7 - (i / 12)); + (*d) = 0; + for (int j = 0; j < 8; j++) { + (*d) |= (s[(i % 12) * 8 + j] & smask) ? dmask : 0; + dmask >>= 1; + } + d++; + } +} + static int spti_read (struct dev_info_ioctl *ciw, int unitnum, uae_u8 *data, int sector, int sectorsize) { uae_u8 cmd[12] = { 0xbe, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }; @@ -282,7 +310,6 @@ static int spti_read (struct dev_info_ioctl *ciw, int unitnum, uae_u8 *data, int cmd[9] |= 0x2 << 1; // C2 } } - ciw->cd_last_pos = sector; cmd[3] = (uae_u8)(sector >> 16); cmd[4] = (uae_u8)(sector >> 8); cmd[5] = (uae_u8)(sector >> 0); @@ -338,7 +365,6 @@ retry: data += sectorsize; ret += sectorsize; } - ciw->cd_last_pos = sector; got = true; } } @@ -363,7 +389,6 @@ retry: ret += sectorsize; } } - ciw->cd_last_pos = sector; got = true; } else { reseterrormode (ciw); @@ -391,7 +416,6 @@ retry: ret += sectorsize; } } - ciw->cd_last_pos = sector; got = true; } } @@ -473,8 +497,8 @@ static void *cdda_play (void *v) MMRESULT mmr; int volume[2], volume_main; int oldplay; + int idleframes; int readblocksize = 2352 + 96; - int current_sector = -1; for (i = 0; i < 2; i++) { memset (&whdr[i], 0, sizeof (WAVEHDR)); @@ -518,30 +542,61 @@ static void *cdda_play (void *v) bufon[bufnum] = 0; if (oldplay != ciw->cdda_play) { + idleframes = 0; struct _timeb tb1, tb2; - current_sector = -1; _ftime (&tb1); cdda_pos = ciw->cdda_start; + ciw->cd_last_pos = cdda_pos; oldplay = ciw->cdda_play; write_log (L"IOCTL%s CDDA: playing from %d to %d\n", ciw->usesptiread ? L"(SPTI)" : L"", ciw->cdda_start, ciw->cdda_end); ciw->subcodevalid = false; - while (ciw->cdda_paused && ciw->cdda_play > 0) + idleframes = ciw->cdda_delay_frames; + while (ciw->cdda_paused && ciw->cdda_play > 0) { Sleep (10); - // pre-load first sectors - if (read_block (ciw, -1, px[bufnum], cdda_pos, num_sectors, readblocksize)) - current_sector = cdda_pos; + idleframes = -1; + } + // force spin up + read_block (ciw, -1, px[bufnum], cdda_pos, num_sectors, readblocksize); + + if (ciw->cdda_scan == 0) { + // find possible P-subchannel=1 and fudge starting point so that + // buggy CD32/CDTV software CD+G handling does not miss any frames + bool seenindex = false; + for (int sector = cdda_pos - 200; sector < cdda_pos; sector++) { + uae_u8 *dst = px[bufnum]; + if (sector >= 0 && read_block (ciw, -1, dst, sector, 1, readblocksize)) { + uae_u8 subbuf[SUB_CHANNEL_SIZE]; + sub_deinterleave (dst + 2352, subbuf); + if (seenindex) { + for (int i = 2 * SUB_ENTRY_SIZE; i < SUB_CHANNEL_SIZE; i++) { + if (subbuf[i]) { // non-zero R-W subchannels + int diff = cdda_pos - sector + 2; + write_log (L"-> CD+G start pos fudge -> %d (%d)\n", sector, -diff); + idleframes -= diff; + cdda_pos = sector; + break; + } + } + } else if (subbuf[0] == 0xff) { // P == 1? + seenindex = true; + } + } + } + } + cdda_pos -= idleframes; + _ftime (&tb2); int diff = (tb2.time * (uae_s64)1000 + tb2.millitm) - (tb1.time * (uae_s64)1000 + tb1.millitm); diff -= ciw->cdda_delay; - if (diff < 0 && ciw->cdda_play > 0) + if (idleframes >= 0 && diff < 0 && ciw->cdda_play > 0) Sleep (-diff); setstate (ciw, AUDIO_STATUS_IN_PROGRESS); } if ((cdda_pos < ciw->cdda_end || ciw->cdda_end == 0xffffffff) && !ciw->cdda_paused && ciw->cdda_play) { - if (!isaudiotrack (&ciw->di.toc, cdda_pos)) { + if (idleframes <= 0 && !isaudiotrack (&ciw->di.toc, cdda_pos)) { setstate (ciw, AUDIO_STATUS_PLAY_ERROR); goto end; // data track? } @@ -549,32 +604,37 @@ static void *cdda_play (void *v) gui_flicker_led (LED_CD, ciw->di.unitnum - 1, LED_CD_AUDIO); uae_sem_wait (&ciw->sub_sem); + ciw->subcodevalid = false; memset (ciw->subcode, 0, sizeof ciw->subcode); - - bool readerr = false; - if (current_sector != cdda_pos) { - current_sector = -1; - memset (px[bufnum], 0, num_sectors * readblocksize); - readerr = read_block (ciw, -1, px[bufnum], cdda_pos, num_sectors, readblocksize) == 0; - if (!readerr) - current_sector = cdda_pos; - } - if (readerr) { - if (ciw->cdda_subfunc) - ciw->cdda_subfunc (ciw->subcode, num_sectors); - } else { - for (i = 0; i < num_sectors; i++) { - memcpy (ciw->subcode + i * SUB_CHANNEL_SIZE, px[bufnum] + readblocksize * i + 2352, SUB_CHANNEL_SIZE); + memset (px[bufnum], 0, num_sectors * readblocksize); + + if (cdda_pos >= 0) { + if (read_block (ciw, -1, px[bufnum], cdda_pos, num_sectors, readblocksize)) { + for (i = 0; i < num_sectors; i++) { + memcpy (ciw->subcode + i * SUB_CHANNEL_SIZE, px[bufnum] + readblocksize * i + 2352, SUB_CHANNEL_SIZE); + } + for (i = 1; i < num_sectors; i++) { + memmove (px[bufnum] + 2352 * i, px[bufnum] + readblocksize * i, 2352); + } + ciw->subcodevalid = true; } - if (ciw->cdda_subfunc) - ciw->cdda_subfunc (ciw->subcode, num_sectors); - for (i = 1; i < num_sectors; i++) { - memmove (px[bufnum] + 2352 * i, px[bufnum] + readblocksize * i, 2352); + } + + for (i = 0; i < num_sectors; i++) { + if (idleframes > 0) { + idleframes--; + memset (px[bufnum] + 2352 * i, 0, 2352); + memset (ciw->subcode + i * SUB_CHANNEL_SIZE, 0, SUB_CHANNEL_SIZE); + } else if (cdda_pos < ciw->cdda_start && ciw->cdda_scan == 0) { + memset (px[bufnum] + 2352 * i, 0, 2352); } - ciw->subcodevalid = true; } - reseterrormode (ciw); + if (idleframes > 0) + ciw->subcodevalid = false; + + if (ciw->cdda_subfunc) + ciw->cdda_subfunc (ciw->subcode, num_sectors); uae_sem_post (&ciw->sub_sem); @@ -612,16 +672,21 @@ static void *cdda_play (void *v) if (cdda_pos < 0) cdda_pos = 0; } else { - cdda_pos += num_sectors; - } - if (cdda_pos - num_sectors < ciw->cdda_end && cdda_pos >= ciw->cdda_end) { - setstate (ciw, AUDIO_STATUS_PLAY_COMPLETE); - ciw->cdda_play_finished = 1; - ciw->cdda_play = -1; - cdda_pos = ciw->cdda_end; + if (cdda_pos < 0 && cdda_pos + num_sectors >= 0) + cdda_pos = 0; + else + cdda_pos += num_sectors; } - ciw->cd_last_pos = cdda_pos; + if (idleframes <= 0) { + if (cdda_pos - num_sectors < ciw->cdda_end && cdda_pos >= ciw->cdda_end) { + setstate (ciw, AUDIO_STATUS_PLAY_COMPLETE); + ciw->cdda_play_finished = 1; + ciw->cdda_play = -1; + cdda_pos = ciw->cdda_end; + } + ciw->cd_last_pos = cdda_pos; + } } if (bufon[0] == 0 && bufon[1] == 0) { @@ -710,6 +775,7 @@ static int ioctl_command_play (int unitnum, int startlsn, int endlsn, int scan, ciw->cdda_statusfunc = statusfunc; ciw->cdda_scan = scan > 0 ? 10 : (scan < 0 ? 10 : 0); ciw->cdda_delay = setstate (ciw, -1); + ciw->cdda_delay_frames = setstate (ciw, -2); setstate (ciw, AUDIO_STATUS_NOT_SUPPORTED); if (!open_createfile (ciw, 0)) { @@ -731,34 +797,6 @@ static int ioctl_command_play (int unitnum, int startlsn, int endlsn, int scan, return 1; } -static void sub_deinterleave (const uae_u8 *s, uae_u8 *d) -{ - for (int i = 0; i < 8 * 12; i ++) { - int dmask = 0x80; - int smask = 1 << (7 - (i / 12)); - (*d) = 0; - for (int j = 0; j < 8; j++) { - (*d) |= (s[(i % 12) * 8 + j] & smask) ? dmask : 0; - dmask >>= 1; - } - d++; - } -} - -static void sub_to_deinterleaved (const uae_u8 *s, uae_u8 *d) -{ - for (int i = 0; i < 8 * 12; i ++) { - int dmask = 0x80; - int smask = 1 << (7 - (i / 12)); - (*d) = 0; - for (int j = 0; j < 8; j++) { - (*d) |= (s[(i % 12) * 8 + j] & smask) ? dmask : 0; - dmask >>= 1; - } - d++; - } -} - /* read qcode */ static int ioctl_command_qcode (int unitnum, uae_u8 *buf, int sector) { @@ -875,6 +913,7 @@ static int ioctl_command_rawread (int unitnum, uae_u8 *data, int sector, int siz while (size-- > 0) { if (!read_block (ciw, unitnum, data, sector, 1, sectorsize)) break; + ciw->cd_last_pos = sector; data += sectorsize; ret += sectorsize; sector++; @@ -908,6 +947,7 @@ static int ioctl_command_rawread (int unitnum, uae_u8 *data, int sector, int siz reseterrormode (ciw); return ret; } + ciw->cd_last_pos = sector; if (subs == 0) { memcpy (data, p, blocksize); diff --git a/od-win32/cloanto/RetroPlatformIPC.h b/od-win32/cloanto/RetroPlatformIPC.h old mode 100644 new mode 100755 index be6b9efd..9d54969c --- a/od-win32/cloanto/RetroPlatformIPC.h +++ b/od-win32/cloanto/RetroPlatformIPC.h @@ -2,12 +2,13 @@ Name : RetroPlatformIPC.h Project : RetroPlatform Player Client : Cloanto Italia srl - Legal : Copyright 2007, 2008 Cloanto Italia srl - All rights reserved. This + Support : http://www.retroplatform.com + Legal : Copyright 2007-2010 Cloanto Italia srl - All rights reserved. This : file is made available under the terms of the GNU General Public : License version 2 as published by the Free Software Foundation. Authors : os, mcb Created : 2007-08-27 13:55:49 - Updated : 2008-12-19 12:38:00 + Updated : 2010-08-17 19:01:00 Comment : RP Player interprocess communication include file *****************************************************************************/ @@ -16,9 +17,9 @@ #include -#define RPLATFORM_API_VER "1.1" +#define RPLATFORM_API_VER "1.2" #define RPLATFORM_API_VER_MAJOR 1 -#define RPLATFORM_API_VER_MINOR 1 +#define RPLATFORM_API_VER_MINOR 2 #define RPIPC_HostWndClass "RetroPlatformHost%s" #define RPIPC_GuestWndClass "RetroPlatformGuest%d" @@ -50,46 +51,48 @@ #define RPIPCGM_PARENT (WM_APP + 21) #define RPIPCGM_DEVICESEEK (WM_APP + 22) #define RPIPCGM_CLOSE (WM_APP + 23) - +#define RPIPCGM_DEVICEREADWRITE (WM_APP + 24) +#define RPIPCGM_HOSTVERSION (WM_APP + 25) // **************************************************************************** // Host-to-Guest Messages // **************************************************************************** -#define RPIPCHM_CLOSE (WM_APP + 200) -#define RPIPCHM_SCREENMODE (WM_APP + 202) -#define RPIPCHM_SCREENCAPTURE (WM_APP + 203) -#define RPIPCHM_PAUSE (WM_APP + 204) -#define RPIPCHM_DEVICECONTENT (WM_APP + 205) -#define RPIPCHM_RESET (WM_APP + 206) -#define RPIPCHM_TURBO (WM_APP + 207) -#define RPIPCHM_PING (WM_APP + 208) -#define RPIPCHM_VOLUME (WM_APP + 209) -#define RPIPCHM_ESCAPEKEY (WM_APP + 210) -#define RPIPCHM_EVENT (WM_APP + 211) -#define RPIPCHM_MOUSECAPTURE (WM_APP + 212) -#define RPIPCHM_SAVESTATE (WM_APP + 213) -#define RPIPCHM_LOADSTATE (WM_APP + 214) -#define RPIPCHM_FLUSH (WM_APP + 215) - +#define RPIPCHM_CLOSE (WM_APP + 200) +#define RPIPCHM_SCREENMODE (WM_APP + 202) +#define RPIPCHM_SCREENCAPTURE (WM_APP + 203) +#define RPIPCHM_PAUSE (WM_APP + 204) +#define RPIPCHM_DEVICECONTENT (WM_APP + 205) +#define RPIPCHM_RESET (WM_APP + 206) +#define RPIPCHM_TURBO (WM_APP + 207) +#define RPIPCHM_PING (WM_APP + 208) +#define RPIPCHM_VOLUME (WM_APP + 209) +#define RPIPCHM_ESCAPEKEY (WM_APP + 210) +#define RPIPCHM_EVENT (WM_APP + 211) +#define RPIPCHM_MOUSECAPTURE (WM_APP + 212) +#define RPIPCHM_SAVESTATE (WM_APP + 213) +#define RPIPCHM_LOADSTATE (WM_APP + 214) +#define RPIPCHM_FLUSH (WM_APP + 215) +#define RPIPCHM_DEVICEREADWRITE (WM_APP + 216) // **************************************************************************** // Message Data Structures and Defines // **************************************************************************** // Guest Features -#define RP_FEATURE_POWERLED 0x00000001 // a power LED is emulated -#define RP_FEATURE_SCREEN1X 0x00000002 // 1x mode is available -#define RP_FEATURE_SCREEN2X 0x00000004 // 2x mode is available -#define RP_FEATURE_SCREEN3X 0x00000008 // 3x mode is available -#define RP_FEATURE_SCREEN4X 0x00000010 // 4x mode is available -#define RP_FEATURE_FULLSCREEN 0x00000020 // full screen display is available -#define RP_FEATURE_SCREENCAPTURE 0x00000040 // screen capture functionality is available (see RPIPCHM_SCREENCAPTURE message) -#define RP_FEATURE_PAUSE 0x00000080 // pause functionality is available (see RPIPCHM_PAUSE message) -#define RP_FEATURE_TURBO 0x00000100 // turbo mode functionality is available (see RPIPCHM_TURBO message) -#define RP_FEATURE_VOLUME 0x00000200 // volume adjustment is possible (see RPIPCHM_VOLUME message) -#define RP_FEATURE_STATE 0x00000400 // loading and saving of emulation state is supported (see RPIPCHM_SAVESTATE/RPIPCHM_LOADSTATE message) -#define RP_FEATURE_SCANLINES 0x00000800 // scan lines video effect is available +#define RP_FEATURE_POWERLED 0x00000001 // a power LED is emulated +#define RP_FEATURE_SCREEN1X 0x00000002 // 1x mode is available +#define RP_FEATURE_SCREEN2X 0x00000004 // 2x mode is available +#define RP_FEATURE_SCREEN3X 0x00000008 // 3x mode is available +#define RP_FEATURE_SCREEN4X 0x00000010 // 4x mode is available +#define RP_FEATURE_FULLSCREEN 0x00000020 // full screen display is available +#define RP_FEATURE_SCREENCAPTURE 0x00000040 // screen capture functionality is available (see RPIPCHM_SCREENCAPTURE message) +#define RP_FEATURE_PAUSE 0x00000080 // pause functionality is available (see RPIPCHM_PAUSE message) +#define RP_FEATURE_TURBO 0x00000100 // turbo mode functionality is available (see RPIPCHM_TURBO message) +#define RP_FEATURE_VOLUME 0x00000200 // volume adjustment is possible (see RPIPCHM_VOLUME message) +#define RP_FEATURE_STATE 0x00000400 // loading and saving of emulation state is supported (see RPIPCHM_SAVESTATE/RPIPCHM_LOADSTATE message) +#define RP_FEATURE_SCANLINES 0x00000800 // scan lines video effect is available +#define RP_FEATURE_DEVICEREADWRITE 0x00001000 // device read/write can be set at runtime on floppy and hard disks // Screen Modes #define RP_SCREENMODE_1X 0x00000000 // 1x window or full-screen mode ("CGA mode") @@ -152,6 +155,23 @@ typedef struct RPDeviceContent #define RP_IPD_KEYBDL2 L"KeyboardLayout2" // second joystick emulation keyboard layout (e.g. Keyboard Layout B for WinUAE) #define RP_IPD_KEYBDL3 L"KeyboardLayout3" // third joystick emulation keyboard layout (e.g. Keyboard Layout C for WinUAE) +// Joystick status flags +#define RP_JOYSTICK_RIGHT 0x00000001 // right direction +#define RP_JOYSTICK_LEFT 0x00000002 // left direction +#define RP_JOYSTICK_DOWN 0x00000004 // down direction +#define RP_JOYSTICK_UP 0x00000008 // up direction +#define RP_JOYSTICK_BUTTON1 0x00000010 // button 1 - Fire 1 - CD32 Red +#define RP_JOYSTICK_BUTTON2 0x00000020 // button 2 - Fire 2 - CD32 Blue +#define RP_JOYSTICK_BUTTON3 0x00000040 // button 3 - Fire 3 - CD32 Yellow +#define RP_JOYSTICK_BUTTON4 0x00000080 // button 4 - Fire 4 - CD32 Green +#define RP_JOYSTICK_BUTTON5 0x00000100 // button 5 - CD32 Play +#define RP_JOYSTICK_BUTTON6 0x00000200 // button 6 - CD32 Reverse +#define RP_JOYSTICK_BUTTON7 0x00000400 // button 7 - CD32 Forward + +// Device Read/Write status +#define RP_DEVICE_READONLY 0 // the medium is write-protected +#define RP_DEVICE_READWRITE 1 // the medium is read/write + // Turbo Mode Functionalities #define RP_TURBO_CPU 0x00000001 // CPU #define RP_TURBO_FLOPPY 0x00000002 // floppy disk drive @@ -168,7 +188,19 @@ typedef struct RPDeviceContent // RPIPCGM_DEVICEACTIVITY #define RP_DEVICEACTIVITY_GREEN 0x0000 // green led #define RP_DEVICEACTIVITY_RED 0x0001 // red led -#define RP_DEVICEACTIVITY_READ RP_DEVICEACTIVITY_GREEN // the device activity is about a read operation -#define RP_DEVICEACTIVITY_WRITE RP_DEVICEACTIVITY_RED // the device activity is about a write operation +#define RP_DEVICEACTIVITY_READ RP_DEVICEACTIVITY_GREEN // device activity is a read operation +#define RP_DEVICEACTIVITY_WRITE RP_DEVICEACTIVITY_RED // device activity is a write operation + +// RPIPCGM_HOSTVERSION +// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 +// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +// +-----------------------+-------------------+-------------------+ +// | major | minor | build | +// +-----------------------+-------------------+-------------------+ +#define RP_HOSTVERSION_MAJOR(ver) (((ver) >> 20) & 0xFFF) +#define RP_HOSTVERSION_MINOR(ver) (((ver) >> 10) & 0x3FF) +#define RP_HOSTVERSION_BUILD(ver) ((ver) & 0x3FF) +#define RP_MAKE_HOSTVERSION(major,minor,build) ((LPARAM) (((LPARAM)((major) & 0xFFF)<<20) | ((LPARAM)((minor) & 0x3FF)<<10) | ((LPARAM)((build) & 0x3FF)))) + #endif // __CLOANTO_RETROPLATFORMIPC_H__ diff --git a/od-win32/cloanto/RetroPlatformIPC_doc_draft.txt b/od-win32/cloanto/RetroPlatformIPC_doc_draft.txt old mode 100644 new mode 100755 index 823db414..406925ae --- a/od-win32/cloanto/RetroPlatformIPC_doc_draft.txt +++ b/od-win32/cloanto/RetroPlatformIPC_doc_draft.txt @@ -2,8 +2,9 @@ Name : RetroPlatformIPC_doc.txt Project : RPSampleGuest Client : Cloanto Italia srl + Support : http://www.retroplatform.com Legal : CONFIDENTIAL TRADE SECRET PROPERTY OF CLOANTO ITALIA SRL - : Copyright © Cloanto Italia srl 2007-2008. + : Copyright © Cloanto Italia srl 2007-2009. : All rights reserved, except where licensed, : assigned or transferred by contract. Authors : os, mcb @@ -38,6 +39,7 @@ Description: RPIPCGM_POWERLED (turns on the power LED in the GUI), RPIPCGM_DEVICES (one for each device category: tells the number of emulated devices), RPIPCGM_DEVICECONTENT (one for each device with an image file or peripheral attached), + RPIPCGM_DEVICEREADWRITE (one for each device with an image file or peripheral attached - optional for non-floppy/non-hard disk which are always read-only), RPIPCGM_TURBO (tells if some of the turbo modes are activated from the start), RPIPCGM_VOLUME (reports about starting volume level), RPIPCGM_SCREENMODE (communicates the screen mode, the clipping coordinates and the guest window handle); @@ -45,7 +47,12 @@ Description: and send its handle using a RPIPCGM_SCREENMODE message, which must be the last of the initialization messages, since it displays the guest window and the host "frame window" (the part of the player user interface - with command and status icons which can be used to drag the guest window, etc.) + with command and status icons which can be used to drag the guest window, etc.); + in some circumstances the host may decide not to display the guest window + when receiving the RPIPCGM_SCREENMODE message (e.g. in Express mode + the guest may be immediately paused and an intro banner may be displayed; + when the intro banner is dismissed the guest is resumed from pause mode + and its window is displayed) Data sent: WPARAM = RP_FEATURE_* flags Response: @@ -164,7 +171,8 @@ Message: RPIPCGM_DEVICEACTIVITY Description: this message can be used to turn on or off the activity indicator - of a specified device (like a LED on the original hardware); + of a specified device (like a LED on the original hardware) + or to notify the host about the status of a joystick; the indicator can also be "blinked", i.e. the host will turn the LED on and then off again after the specified amount of time Data sent: @@ -180,7 +188,10 @@ Data sent: or to a value to turn on the activity LED for the specified amount of time (blink); the Flags value can be set - using one or more of the RP_DEVICEACTIVITY_* defines + using one or more of the RP_DEVICEACTIVITY_* defines; + in case the message references a RP_DEVICE_INPUTPORT device + connected to a joystick, the data sent via LPARAM + is a combination of RP_JOYSTICK_* values Response: none @@ -224,6 +235,18 @@ Response: (e.g. LOWORD(lr) = major version; HIWORD(lr) = minor version) +Message: + RPIPCGM_HOSTVERSION +Description: + the guest can send a RPIPCGM_HOSTVERSION + to query the host about its version +Data sent: + none +Response: + LRESULT = major, minor and build versions combined into a single 32 bit value; + the RP_HOSTVERSION_* macros can be used to get specific information + + Message: RPIPCGM_PAUSE Description: @@ -254,7 +277,32 @@ Data sent: pData = a RPDEVICECONTENT structure (see RetroPlatformIPC.h); the szContent field of the structure contains an empty string when the guest - is ejecting something from the device + is ejecting something from the device; + szContent examples for CD and other physical drives supported by the guest: + - "D:\" = mount physical drive D: (full or empty, does not matter) + - "C:\test.iso" = mount ISO image + - "" = empty image drive ("image mode without image") + - there is no specific message to indicate "empty physical drive" (what counts is that there is an association with the physical drive) +Response: + none + + +Message: + RPIPCGM_DEVICEREADWRITE +Description: + the guest sends a RPIPCGM_DEVICEREADWRITE message + to notify the host about an initial status or a change in + the read/write protection status; + this notification is optional if the event + was requested by the host (see the RPIPCHM_DEVICEREADWRITE message); + if no initial status is sent, the status is assumed to be read/write + for floppy and hard disks, and read-only for all other devices + (CDs, cartridges, tapes, etc.) +Data sent: + WPARAM = device category (RP_DEVICE_* value) and device number + combined with the MAKEWORD macro; + e.g. MAKEWORD(RP_DEVICE_FLOPPY, 0) + LPARAM = current device read/write status flags (RP_DEVICE_READONLY/RP_DEVICE_READWRITE) Response: none @@ -450,6 +498,20 @@ Response: LRESULT = 1 if the guest successfully executed the command or 0 otherwise +Message: + RPIPCHM_DEVICEREADWRITE +Description: + the host sends a RPIPCHM_DEVICEREADWRITE message + to set the read/write protection status +Data sent: + WPARAM = device category (RP_DEVICE_* value) and device number + combined with the MAKEWORD macro; + e.g. MAKEWORD(RP_DEVICE_FLOPPY, 0) + LPARAM = current device read/write status flags (RP_DEVICE_READONLY/RP_DEVICE_READWRITE) +Response: + LRESULT = 1 if the guest successfully executed the command or 0 otherwise (for example, because the image file itself is read-only, so that writing is not possible) + + Message: RPIPCHM_RESET Description: diff --git a/od-win32/dinput.cpp b/od-win32/dinput.cpp index fac2e5d8..4e705a70 100644 --- a/od-win32/dinput.cpp +++ b/od-win32/dinput.cpp @@ -114,6 +114,7 @@ static int oldleds, oldusedleds, newleds, oldusbleds; static int normalmouse, supermouse, rawmouse, winmouse, winmousenumber, winmousemode, winmousewheelbuttonstart; static int normalkb, superkb, rawkb; static bool rawinput_enabled_mouse, rawinput_enabled_keyboard; +static bool rawinput_decided; int no_rawinput = 0; int dinput_enum_all; @@ -813,18 +814,11 @@ static void getvidpid (const TCHAR *devname, int *vid, int *pid, int *mi) static void addrkblabels (struct didata *did) { - int j = 0; for (int k = 0; k < 254; k++) { TCHAR tmp[100]; tmp[0] = 0; - if (rawkeyboardlabels[j] != NULL) { - if (rawkeyboardlabels[j][0]) { - _tcscpy (tmp, rawkeyboardlabels[j]); - j++; - } - } else { - j++; - } + if (rawkeyboardlabels[k] != NULL && rawkeyboardlabels[k][0]) + _tcscpy (tmp, rawkeyboardlabels[k]); if (!tmp[0]) _stprintf (tmp, L"KEY_%02X", k + 1); did->buttonname[k] = my_strdup (tmp); @@ -889,6 +883,14 @@ static int initialize_rawinput (void) PRID_DEVICE_INFO rdi; int v, j; + if (rawinput_decided) { + // must not enable rawinput later, even if rawinput capable device was plugged in + if (type == RIM_TYPEKEYBOARD && !rawinput_enabled_keyboard) + continue; + if (type == RIM_TYPEMOUSE && !rawinput_enabled_mouse) + continue; + } + if (GetRawInputDeviceInfo (h, RIDI_DEVICENAME, NULL, &vtmp) == -1) continue; if (vtmp >= bufsize) @@ -1598,8 +1600,12 @@ static int di_do_init (void) write_log (L"RawInput enumeration..\n"); initialize_rawinput (); } - rawinput_enabled_keyboard = num_keyboard > 0; - rawinput_enabled_mouse = num_mouse > 0; + + if (!rawinput_decided) { + rawinput_enabled_keyboard = num_keyboard > 0; + rawinput_enabled_mouse = num_mouse > 0; + rawinput_decided = true; + } hr = DirectInput8Create (hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID *)&g_lpdi, NULL); if (FAILED(hr)) { diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index 63570387..f92f3507 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -2149,7 +2149,7 @@ void D3D_clear (void) static void D3D_render22 (void) { HRESULT hr; - LPDIRECT3DTEXTURE9 srctex; + LPDIRECT3DTEXTURE9 srctex = texture; UINT uPasses, uPass; if (!isd3d ()) @@ -2238,10 +2238,6 @@ static void D3D_render22 (void) #endif srctex = lpTempTexture; - } else { - - srctex = texture; - } } diff --git a/od-win32/lib/prowizard.lib b/od-win32/lib/prowizard.lib index 46893986..0ae8ca65 100644 Binary files a/od-win32/lib/prowizard.lib and b/od-win32/lib/prowizard.lib differ diff --git a/od-win32/posixemu.cpp b/od-win32/posixemu.cpp index 12601e68..f3e82bb2 100644 --- a/od-win32/posixemu.cpp +++ b/od-win32/posixemu.cpp @@ -268,7 +268,7 @@ void uae_end_thread (uae_thread_id *tid) } } -int uae_start_thread (TCHAR *name, void *(*f)(void *), void *arg, uae_thread_id *tid) +int uae_start_thread (const TCHAR *name, void *(*f)(void *), void *arg, uae_thread_id *tid) { HANDLE hThread; int result = 1; diff --git a/od-win32/rp.cpp b/od-win32/rp.cpp index 872c4221..5a88b923 100644 --- a/od-win32/rp.cpp +++ b/od-win32/rp.cpp @@ -31,6 +31,7 @@ static int initialized; static RPGUESTINFO guestinfo; +static int maxjports; TCHAR *rp_param = NULL; int rp_rpescapekey = 0x01; @@ -38,6 +39,7 @@ int rp_rpescapeholdtime = 600; int rp_screenmode = 0; int rp_inputmode = 0; int log_rp = 1; +static int rp_revision, rp_version, rp_build; static int max_horiz_dbl = RES_HIRES; static int max_vert_dbl = 1; @@ -49,6 +51,7 @@ static int mousecapture, mousemagic; static int rp_filter, rp_filter_default; static int recursive_device, recursive; static int currentpausemode; +static int gameportmask[MAX_JPORTS]; static int cando (void) { @@ -79,10 +82,8 @@ static const TCHAR *getmsg (int msg) case RPIPCGM_REGISTER: return L"RPIPCGM_REGISTER"; case RPIPCGM_FEATURES: return L"RPIPCGM_FEATURES"; case RPIPCGM_CLOSED: return L"RPIPCGM_CLOSED"; - case RPIPCGM_CLOSE: return L"RPIPCGM_CLOSE"; case RPIPCGM_ACTIVATED: return L"RPIPCGM_ACTIVATED"; case RPIPCGM_DEACTIVATED: return L"RPIPCGM_DEACTIVATED"; - case RPIPCGM_PARENT: return L"RPIPCGM_PARENT"; case RPIPCGM_SCREENMODE: return L"RPIPCGM_SCREENMODE"; case RPIPCGM_POWERLED: return L"RPIPCGM_POWERLED"; case RPIPCGM_DEVICES: return L"RPIPCGM_DEVICES"; @@ -90,27 +91,33 @@ static const TCHAR *getmsg (int msg) case RPIPCGM_MOUSECAPTURE: return L"RPIPCGM_MOUSECAPTURE"; case RPIPCGM_HOSTAPIVERSION: return L"RPIPCGM_HOSTAPIVERSION"; case RPIPCGM_PAUSE: return L"RPIPCGM_PAUSE"; + case RPIPCGM_DEVICECONTENT: return L"RPIPCGM_DEVICECONTENT"; case RPIPCGM_TURBO: return L"RPIPCGM_TURBO"; + case RPIPCGM_PING: return L"RPIPCGM_PING"; case RPIPCGM_VOLUME: return L"RPIPCGM_VOLUME"; - case RPIPCGM_DEVICECONTENT: return L"RPIPCGM_DEVICECONTENT"; - case RPIPCGM_DEVICESEEK: return L"RPIPCGM_DEVICESEEK"; case RPIPCGM_ESCAPED: return L"RPIPCGM_ESCAPED"; + case RPIPCGM_PARENT: return L"RPIPCGM_PARENT"; + case RPIPCGM_DEVICESEEK: return L"RPIPCGM_DEVICESEEK"; + case RPIPCGM_CLOSE: return L"RPIPCGM_CLOSE"; + case RPIPCGM_DEVICEREADWRITE: return L"RPIPCGM_DEVICEREADWRITE"; + case RPIPCGM_HOSTVERSION: return L"RPIPCGM_HOSTVERSION"; case RPIPCHM_CLOSE: return L"RPIPCHM_CLOSE"; case RPIPCHM_SCREENMODE: return L"RPIPCHM_SCREENMODE"; case RPIPCHM_SCREENCAPTURE: return L"RPIPCHM_SCREENCAPTURE"; case RPIPCHM_PAUSE: return L"RPIPCHM_PAUSE"; + case RPIPCHM_DEVICECONTENT: return L"RPIPCHM_DEVICECONTENT"; case RPIPCHM_RESET: return L"RPIPCHM_RESET"; case RPIPCHM_TURBO: return L"RPIPCHM_TURBO"; + case RPIPCHM_PING: return L"RPIPCHM_PING"; case RPIPCHM_VOLUME: return L"RPIPCHM_VOLUME"; - case RPIPCHM_EVENT: return L"RPIPCHM_EVENT"; case RPIPCHM_ESCAPEKEY: return L"RPIPCHM_ESCAPEKEY"; + case RPIPCHM_EVENT: return L"RPIPCHM_EVENT"; case RPIPCHM_MOUSECAPTURE: return L"RPIPCHM_MOUSECAPTURE"; - case RPIPCHM_DEVICECONTENT: return L"RPIPCHM_DEVICECONTENT"; - case RPIPCHM_PING: return L"RPIPCHM_PING"; case RPIPCHM_SAVESTATE: return L"RPIPCHM_SAVESTATE"; case RPIPCHM_LOADSTATE: return L"RPIPCHM_LOADSTATE"; case RPIPCHM_FLUSH: return L"RPIPCHM_FLUSH"; + case RPIPCHM_DEVICEREADWRITE: return L"RPIPCHM_DEVICEREADWRITE"; default: return L"UNKNOWN"; } @@ -169,7 +176,7 @@ static int port_insert (int num, const TCHAR *name) { TCHAR tmp1[1000]; - if (num < 0 || num >= MAX_JPORTS) + if (num < 0 || num >= maxjports) return FALSE; if (_tcslen (name) == 0) { inputdevice_joyport_config (&changed_prefs, L"none", num, 0, 0); @@ -685,6 +692,18 @@ static LRESULT CALLBACK RPHostMsgFunction2 (UINT uMessage, WPARAM wParam, LPARAM } return ret; } + case RPIPCHM_DEVICEREADWRITE: + { + DWORD ret = FALSE; + int device = LOBYTE(wParam); + if (device == RP_DEVICE_FLOPPY) { + int num = HIBYTE(wParam); + if (lParam == RP_DEVICE_READONLY || lParam == RP_DEVICE_READWRITE) { + ret = disk_setwriteprotect (num, currprefs.floppyslots[num].df, lParam == RP_DEVICE_READONLY); + } + } + return ret ? (LPARAM)1 : 0; + } } return FALSE; } @@ -699,6 +718,17 @@ static LRESULT CALLBACK RPHostMsgFunction (UINT uMessage, WPARAM wParam, LPARAM return lr; } +static int rp_hostversion (int *ver, int *rev, int *build) +{ + LRESULT lr = 0; + if (!RPSendMessagex (RPIPCGM_HOSTVERSION, 0, 0, NULL, 0, &guestinfo, &lr)) + return 0; + *ver = RP_HOSTVERSION_MAJOR(lr); + *rev = RP_HOSTVERSION_MINOR(lr); + *build = RP_HOSTVERSION_BUILD(lr); + return 1; +} + HRESULT rp_init (void) { HRESULT hr; @@ -706,7 +736,9 @@ HRESULT rp_init (void) hr = RPInitializeGuest (&guestinfo, hInst, rp_param, RPHostMsgFunction, 0); if (SUCCEEDED (hr)) { initialized = TRUE; - write_log (L"rp_init('%s') succeeded\n", rp_param); + rp_version = rp_revision = rp_build = -1; + rp_hostversion (&rp_version, &rp_revision, &rp_build); + write_log (L"rp_init('%s') succeeded. Version: %d.%d.%d\n", rp_param, rp_version, rp_revision, rp_build); } else { write_log (L"rp_init('%s') failed, error code %08x\n", rp_param, hr); } @@ -727,6 +759,7 @@ void rp_free (void) RPUninitializeGuest (&guestinfo); } + int rp_close (void) { if (!cando ()) @@ -750,7 +783,7 @@ static void sendfeatures (void) feat = RP_FEATURE_POWERLED | RP_FEATURE_SCREEN1X | RP_FEATURE_FULLSCREEN; feat |= RP_FEATURE_PAUSE | RP_FEATURE_TURBO | RP_FEATURE_VOLUME | RP_FEATURE_SCREENCAPTURE; - feat |= RP_FEATURE_STATE | RP_FEATURE_SCANLINES; + feat |= RP_FEATURE_STATE | RP_FEATURE_SCANLINES | RP_FEATURE_DEVICEREADWRITE; if (!WIN32GFX_IsPicassoScreen ()) feat |= RP_FEATURE_SCREEN2X | RP_FEATURE_SCREEN4X; RPSendMessagex (RPIPCGM_FEATURES, feat, 0, NULL, 0, &guestinfo, NULL); @@ -788,6 +821,7 @@ void rp_fixup_options (struct uae_prefs *p) max_horiz_dbl = currprefs.gfx_max_horizontal; max_vert_dbl = currprefs.gfx_max_vertical; + maxjports = (rp_version * 256 + rp_revision) >= 2 * 256 + 3 ? MAX_JPORTS : 2; changed_prefs.win32_borderless = currprefs.win32_borderless = 1; rp_filter_default = rp_filter = currprefs.gfx_filter; @@ -810,11 +844,12 @@ void rp_fixup_options (struct uae_prefs *p) } RPSendMessagex (RPIPCGM_DEVICES, RP_DEVICE_FLOPPY, floppy_mask, NULL, 0, &guestinfo, NULL); - RPSendMessagex (RPIPCGM_DEVICES, RP_DEVICE_INPUTPORT, (1 << MAX_JPORTS) - 1, NULL, 0, &guestinfo, NULL); + RPSendMessagex (RPIPCGM_DEVICES, RP_DEVICE_INPUTPORT, (1 << maxjports) - 1, NULL, 0, &guestinfo, NULL); rp_input_change (0); rp_input_change (1); rp_input_change (2); rp_input_change (3); + gameportmask[0] = gameportmask[1] = gameportmask[2] = gameportmask[3] = 0; hd_mask = 0; cd_mask = 0; @@ -845,7 +880,6 @@ void rp_fixup_options (struct uae_prefs *p) } } - rp_update_volume (&currprefs); rp_turbo (currprefs.turbo_emulation); for (i = 0; i <= 4; i++) @@ -853,6 +887,15 @@ void rp_fixup_options (struct uae_prefs *p) config_changed = 1; } +static void rp_device_writeprotect (int dev, int num, bool writeprotected) +{ + if (!cando ()) + return; + if (rp_version * 256 + rp_revision < 2 * 256 + 3) + return; + RPSendMessagex (RPIPCGM_DEVICEREADWRITE, MAKEWORD(dev, num), writeprotected ? RP_DEVICE_READONLY : RP_DEVICE_READWRITE, NULL, 0, &guestinfo, NULL); +} + static void rp_device_change (int dev, int num, const TCHAR *name) { struct RPDeviceContent *dc; @@ -883,6 +926,9 @@ void rp_input_change (int num) TCHAR name[MAX_DPATH]; TCHAR *name2 = NULL, *name3 = NULL; + if (num >= maxjports) + return; + name[0] = 0; if (JSEM_ISXARCADE1 (num, &currprefs)) { j = 2; @@ -914,9 +960,10 @@ void rp_input_change (int num) } rp_device_change (RP_DEVICE_INPUTPORT, num, name); } -void rp_disk_image_change (int num, const TCHAR *name) +void rp_disk_image_change (int num, const TCHAR *name, bool writeprotected) { rp_device_change (RP_DEVICE_FLOPPY, num, name); + rp_device_writeprotect (RP_DEVICE_FLOPPY, num, writeprotected); } void rp_harddrive_image_change (int num, const TCHAR *name) { @@ -988,6 +1035,24 @@ void rp_update_leds (int led, int onoff, int write) } } +void rp_update_gameport (int port, int mask, int onoff) +{ + if (!cando ()) + return; + if (port < 0 || port >= maxjports) + return; + if (rp_version * 256 + rp_revision < 2 * 256 + 3) + return; + int old = gameportmask[port]; + if (onoff) + gameportmask[port] |= mask; + else + gameportmask[port] &= ~mask; + if (old != gameportmask[port]) + RPPostMessagex (RPIPCGM_DEVICEACTIVITY, MAKEWORD (RP_DEVICE_INPUTPORT, port), + gameportmask[port], &guestinfo); +} + void rp_hd_activity (int num, int onoff, int write) { if (!cando ()) diff --git a/od-win32/rp.h b/od-win32/rp.h index 42564193..bce81613 100644 --- a/od-win32/rp.h +++ b/od-win32/rp.h @@ -3,15 +3,7 @@ extern HRESULT rp_init (void); extern void rp_free (void); extern int rp_close (void); extern void rp_fixup_options (struct uae_prefs*); -extern void rp_update_volume (struct uae_prefs*); extern void rp_pause (int paused); -extern void rp_update_leds (int, int, int); -extern void rp_floppy_track (int floppy, int track); -extern void rp_floppydrive_change (int num, int removed); -extern void rp_hd_activity (int, int, int); -extern void rp_hd_change (int, int); -extern void rp_cd_activity (int, int); -extern void rp_cd_change (int, int); extern void rp_activate (int, LPARAM); extern void rp_mouse_capture (int); extern void rp_mouse_magic (int); @@ -32,6 +24,16 @@ extern int rp_inputmode; extern int log_rp; extern void rp_input_change (int num); -extern void rp_disk_image_change (int num, const TCHAR *name); +extern void rp_disk_image_change (int num, const TCHAR *name, bool writeprotected); extern void rp_harddrive_image_change (int num, const TCHAR *name); extern void rp_cd_image_change (int num, const TCHAR *name); + +extern void rp_update_gameport (int port, int mask, int onoff); +extern void rp_update_volume (struct uae_prefs*); +extern void rp_update_leds (int, int, int); +extern void rp_floppy_track (int floppy, int track); +extern void rp_floppydrive_change (int num, int removed); +extern void rp_hd_activity (int, int, int); +extern void rp_hd_change (int, int); +extern void rp_cd_activity (int, int); +extern void rp_cd_change (int, int); diff --git a/od-win32/threaddep/thread.h b/od-win32/threaddep/thread.h index 6d786b31..11428971 100644 --- a/od-win32/threaddep/thread.h +++ b/od-win32/threaddep/thread.h @@ -7,7 +7,7 @@ extern int uae_sem_trywait (uae_sem_t*); extern void uae_sem_post (uae_sem_t*); extern void uae_sem_wait (uae_sem_t*t); extern void uae_sem_init (uae_sem_t*, int manual_reset, int initial_state); -extern int uae_start_thread (TCHAR *name, void *(*f)(void *), void *arg, uae_thread_id *thread); +extern int uae_start_thread (const TCHAR *name, void *(*f)(void *), void *arg, uae_thread_id *thread); extern int uae_start_thread_fast (void *(*f)(void *), void *arg, uae_thread_id *thread); extern void uae_end_thread (uae_thread_id *thread); extern void uae_set_thread_priority (uae_thread_id *, int); diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index 212d285e..6b572367 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -1477,7 +1477,7 @@ static LRESULT CALLBACK MainWindowProc (HWND hWnd, UINT message, WPARAM wParam, } else { oc = SetTextColor (lpDIS->hDC, GetSysColor ((tflags & 2) ? COLOR_BTNTEXT : COLOR_GRAYTEXT)); } - flags = DT_VCENTER | DT_SINGLELINE ; + flags = DT_VCENTER | DT_SINGLELINE; if (tflags & 1) { flags |= DT_CENTER; lpDIS->rcItem.left++; @@ -1668,39 +1668,39 @@ static int WIN32_RegisterClasses (void) g_dwBackgroundColor = RGB (255, 0, 255); ReleaseDC (NULL, hDC); - wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_DBLCLKS | CS_OWNDC; + wc.style = CS_DBLCLKS | CS_OWNDC; wc.lpfnWndProc = AmigaWindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = DLGWINDOWEXTRA; wc.hInstance = hInst; wc.hIcon = LoadIcon (GetModuleHandle (NULL), MAKEINTRESOURCE (IDI_APPICON)); - wc.hCursor = NULL; //LoadCursor (NULL, IDC_ARROW); + wc.hCursor = LoadCursor (NULL, IDC_ARROW); wc.lpszMenuName = 0; wc.lpszClassName = L"AmigaPowah"; wc.hbrBackground = CreateSolidBrush (g_dwBackgroundColor); if (!RegisterClass (&wc)) return 0; - wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW | CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; + wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = MainWindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = DLGWINDOWEXTRA; wc.hInstance = hInst; wc.hIcon = LoadIcon (GetModuleHandle (NULL), MAKEINTRESOURCE (IDI_APPICON)); - wc.hCursor = NULL; //LoadCursor (NULL, IDC_ARROW); + wc.hCursor = LoadCursor (NULL, IDC_ARROW); wc.hbrBackground = CreateSolidBrush (black); wc.lpszMenuName = 0; wc.lpszClassName = L"PCsuxRox"; if (!RegisterClass (&wc)) return 0; - wc.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW; + wc.style = 0; wc.lpfnWndProc = HiddenWindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = DLGWINDOWEXTRA; wc.hInstance = hInst; wc.hIcon = LoadIcon (GetModuleHandle (NULL), MAKEINTRESOURCE (IDI_APPICON)); - wc.hCursor = NULL; //LoadCursor (NULL, IDC_ARROW); + wc.hCursor = NULL; wc.hbrBackground = CreateSolidBrush (g_dwBackgroundColor); wc.lpszMenuName = 0; wc.lpszClassName = L"Useless"; @@ -2101,6 +2101,9 @@ void fullpath (TCHAR *path, int size) { if (path[0] == 0 || (path[0] == '\\' && path[1] == '\\') || path[0] == ':') return; + /* : is supposed to mean same as :\ */ + if (_istalpha (path[0]) && path[1] == ':' && path[2] == 0) + _tcscat (path, L"\\"); if (relativepaths) { TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH]; tmp1[0] = 0; @@ -4267,6 +4270,11 @@ static int parseargs (const TCHAR *argx, const TCHAR *np, const TCHAR *np2) log_scsi = 1; return 1; } + if (!_tcscmp (arg, L"scsiemulog")) { + extern int log_scsiemu; + log_scsiemu = 1; + return 1; + } if (!_tcscmp (arg, L"netlog")) { log_net = 1; return 1; diff --git a/od-win32/win32.h b/od-win32/win32.h index 80613cfb..28e7a8f4 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -18,8 +18,8 @@ #define WINUAEPUBLICBETA 1 #define LANG_DLL 1 -#define WINUAEBETA L"10" -#define WINUAEDATE MAKEBD(2010, 8, 11) +#define WINUAEBETA L"12" +#define WINUAEDATE MAKEBD(2010, 8, 21) #define WINUAEEXTRA L"" #define WINUAEREV L"" diff --git a/od-win32/win32_scaler.cpp b/od-win32/win32_scaler.cpp index f38347e9..0828033e 100644 --- a/od-win32/win32_scaler.cpp +++ b/od-win32/win32_scaler.cpp @@ -796,6 +796,8 @@ int S2X_getmult (void) { if (!usedfilter) return 1; + if (screen_is_picasso) + return 1; return usedfilter->intmul; } diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index d7a5c249..a72e1731 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -2524,7 +2524,7 @@ static BOOL doInit (void) #ifdef D3D if (currentmode->flags & DM_D3D) { const TCHAR *err = D3D_init (hAmigaWnd, currentmode->native_width, currentmode->native_height, - currentmode->amiga_width, currentmode->amiga_height, currentmode->current_depth, currprefs.gfx_filter_filtermode + 1); + currentmode->amiga_width, currentmode->amiga_height, currentmode->current_depth, screen_is_picasso ? 1 : currprefs.gfx_filter_filtermode + 1); if (err) { D3D_free (); gui_message (err); diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index 25cde563..3efe556d 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -9709,10 +9709,10 @@ static void addallfloppies (HWND hDlg) addfloppyhistory (hDlg); } -static void floppysetwriteprotect (HWND hDlg, int n, int protect) +static void floppysetwriteprotect (HWND hDlg, int n, bool writeprotected) { if (!iscd (n)) { - disk_setwriteprotect (n, workprefs.floppyslots[n].df, protect); + disk_setwriteprotect (n, workprefs.floppyslots[n].df, writeprotected); addfloppytype (hDlg, n); } } @@ -14208,10 +14208,10 @@ void check_prefs_changed_gui (void) { } -void gui_disk_image_change (int unitnum, const TCHAR *name) +void gui_disk_image_change (int unitnum, const TCHAR *name, bool writeprotected) { #ifdef RETROPLATFORM - rp_disk_image_change (unitnum, name); + rp_disk_image_change (unitnum, name, writeprotected); #endif } diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 0d7c2a09..6ed957fc 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,36 @@ +Beta 12: + +- : without '\' in harddrive paths was detected as a relative path, + automatically add missing '\', it was commonly used in old config files +- CD32 pad in 2-button mode usually returned non-existing 3rd button pressed +- CD32 pad in 2-button mode didn't have pullup resistor emulation (was lost when + joystick pullups were removed in 2.2) +- autocorrect CD32/CDTV CDA starting position if R-W subchannel data is detected, workaround + for a bug (happens on real CD32 and CDTV too) that can cause missed subchannel frames at + play startup causing corrupt or missing CD+G graphics +- CD thread safety critical sections moved to common part from image mounter +- CD image mounter in play state while replacing image: state was still reported as playing +- do not enable rawinput if rawinput capable device is inserted after winuae has been started +- 2x or larger filters changed RTG hardware mouse cursor size.. (D3D + hardware RTG cursor only) +- scsi emulation always-on logging disabled, added -scsiemulog command line parameter + +Beta 11: + +- internal CD audio handling update, status change (starting, started, end, error) callback + added, CD32 and CDTV emulation does not poll for state changes anymore, better accuracy + in audio start and end timing. CD handling rewrite should be complete now. +- CD image mounter is now thread safe, no more weird and random behavior if mounted image was + in use and image was ejected or replaced +- fixed rare crash in display emulation (introduced when right border blanking update was added) +- improved CD32 CD sound/animation timing +- CD32 CD timing now works correctly in NTSC mode (previously used hardcoded PAL values) +- "non-path" kickstart rom configuration file selection now only allows normal KS roms in + kickstart_rom variable and extended roms in kickstart_rom_ext variable +- fixed D3D non-shader mode crash introduced in b9 +- bogus autofire mode was enabled if same joystick was custom configured in input panel and in gameports panel + (missing masking of flags variable, time to wear brown paper bag again..) + Beta 10: - archive dragndrop worked too well, it unpacked everything, including adf filesystem etc.. diff --git a/prowizard/rippers/ProPacker10.c b/prowizard/rippers/ProPacker10.c index 7de0711b..22386296 100644 --- a/prowizard/rippers/ProPacker10.c +++ b/prowizard/rippers/ProPacker10.c @@ -32,7 +32,7 @@ short testPP10 ( void ) PW_l = (((in_data[PW_Start_Address+PW_j*8+4]*256)+in_data[PW_Start_Address+5+PW_j*8])*2); /* loop size */ PW_m = (((in_data[PW_Start_Address+PW_j*8+6]*256)+in_data[PW_Start_Address+7+PW_j*8])*2); - if ( (PW_m == 0) || (PW_m == PW_l) ) + if ( PW_m == 0 ) { /*printf ( "#1,98 (start:%ld) (PW_k:%ld) (PW_l:%ld) (PW_m:%ld)\n" , PW_Start_Address,PW_k,PW_l,PW_m );*/ return BAD; @@ -78,6 +78,7 @@ short testPP10 ( void ) return BAD; } } + if ( PW_WholeSampleSize <= 2 ) { /*printf ( "#2,4 (start:%ld)\n" , PW_Start_Address );*/ @@ -107,9 +108,9 @@ short testPP10 ( void ) if ( PW_Start_Address + 762 + (PW_k*4) > PW_in_size ) { +/*printf ( "#4 (start:%ld)\n" , PW_Start_Address );*/ return BAD; } - /* track data test */ PW_l=0; for ( PW_j=0 ; PW_j Max ) - Max = Tracks_Numbers[j][i]; - } + ReadPat[i] = (in_data[Where+i]*256*256*256) + + (in_data[Where+i+128]*256*256) + + (in_data[Where+i+256]*256) + + in_data[Where+i+384]; + ReadTrkPat[i][0] = in_data[Where+i]; + ReadTrkPat[i][1] = in_data[Where+i+128]; + ReadTrkPat[i][2] = in_data[Where+i+256]; + ReadTrkPat[i][3] = in_data[Where+i+384]; + if (ReadTrkPat[i][0] > Highest_Track) + Highest_Track = ReadTrkPat[i][0]; + if (ReadTrkPat[i][1] > Highest_Track) + Highest_Track = ReadTrkPat[i][1]; + if (ReadTrkPat[i][2] > Highest_Track) + Highest_Track = ReadTrkPat[i][2]; + if (ReadTrkPat[i][3] > Highest_Track) + Highest_Track = ReadTrkPat[i][3]; + /*printf ("%x-%x-%x-%x\n",ReadTrkPat[i][0],ReadTrkPat[i][1],ReadTrkPat[i][2],ReadTrkPat[i][3]);*/ + } + /*printf ( "Number of tracks : %d\n" , Highest_Track+1 );*/ + + /* sorting ?*/ + k = 0; /* next min */ + l = 0; + + /* put the first pattern number */ + /* could be stored several times */ + for (j=0; jk)) + m = ReadPat[i]; + /* if k == m then an already existing ref was found */ + if (k==m) + continue; + /* m is the next minimum */ + k = m; + for (i=0; i Highest_Track) Highest_Track = ReadTrkPat[i][3]; - /*printf ("%x-%x-%x-%x\n",ReadTrkPat[i][0],ReadTrkPat[i][1],ReadTrkPat[i][2],ReadTrkPat[i][3]);*/ + /*fprintf (info,"%x-%x-%x-%x (%ld)\n",ReadTrkPat[i][0],ReadTrkPat[i][1],ReadTrkPat[i][2],ReadTrkPat[i][3],ReadPat[i]);*/ } - /*printf ( "Number of tracks : %d\n" , Highest_Track+1 );*/ + /*fprintf ( info,"Number of tracks : %d\n\n" , Highest_Track+1 );*/ /* sorting ?*/ k = 0; /* next min */ @@ -234,7 +238,10 @@ void Depack_PP21 ( void ) Header[952+i] = (unsigned char)l; l++; } - + if ( l != Header[950] ) + l -= 1; + /*fprintf (info,"number of pattern stored : %ld\n\n",l);*/ + //fflush (info); /* write ptk's ID */ Header[1080] = 'M'; @@ -251,10 +258,11 @@ void Depack_PP21 ( void ) /* l is the number of stored patterns */ /* rebuild pattern data now */ whereTableRef = ((Highest_Track + 1)*128) + 4 + Where; - printf ( "\nwhereTableRef : %ld\n",whereTableRef); - for (i=0;i Max ) - Max = Tracks_Numbers[j][i]; - } + ReadPat[i] = (in_data[Where+i]*256*256*256) + + (in_data[Where+i+128]*256*256) + + (in_data[Where+i+256]*256) + + in_data[Where+i+384]; + ReadTrkPat[i][0] = in_data[Where+i]; + ReadTrkPat[i][1] = in_data[Where+i+128]; + ReadTrkPat[i][2] = in_data[Where+i+256]; + ReadTrkPat[i][3] = in_data[Where+i+384]; + if (ReadTrkPat[i][0] > Highest_Track) + Highest_Track = ReadTrkPat[i][0]; + if (ReadTrkPat[i][1] > Highest_Track) + Highest_Track = ReadTrkPat[i][1]; + if (ReadTrkPat[i][2] > Highest_Track) + Highest_Track = ReadTrkPat[i][2]; + if (ReadTrkPat[i][3] > Highest_Track) + Highest_Track = ReadTrkPat[i][3]; + /*printf ("%x-%x-%x-%x\n",ReadTrkPat[i][0],ReadTrkPat[i][1],ReadTrkPat[i][2],ReadTrkPat[i][3]);*/ } + /*printf ( "Number of tracks : %d\n" , Highest_Track+1 );*/ - /* write pattern table without any optimizing ! */ - for ( c1=0x00 ; c1k)) + m = ReadPat[i]; + /* if k == m then an already existing ref was found */ + if (k==m) + continue; + /* m is the next minimum */ + k = m; + for (i=0; iname)) ok = 2; - if (rd->ver == ver && (rev < 0 || rd->rev == rev)) { + if ((ver < 0 || rd->ver == ver) && (rev < 0 || rd->rev == rev)) { if (subver >= 0) { if (rd->subver == subver && (subrev < 0 || rd->subrev == subrev) && rd->subver > 0) ok = 1; @@ -419,7 +419,7 @@ struct romlist **getromlistbyident (int ver, int rev, int subver, int subrev, co if (model && ok < 2) { TCHAR *p = rd->model; ok = 0; - while (*p) { + while (p && *p) { if (!_tcscmp(rd->model, model)) { ok = 1; break; @@ -427,7 +427,7 @@ struct romlist **getromlistbyident (int ver, int rev, int subver, int subrev, co p = p + _tcslen(p) + 1; } } - if (!model && rd->type != ROMTYPE_KICK) + if (romflags && (rd->type & romflags) == 0) ok = 0; if (ok) { if (all) { diff --git a/scsiemul.cpp b/scsiemul.cpp index 07661857..082d0df9 100644 --- a/scsiemul.cpp +++ b/scsiemul.cpp @@ -707,7 +707,7 @@ static int dev_do_io (struct devstruct *dev, uaecptr request) } } } else { - io_error = CDERR_NotSpecified; + io_error = IOERR_NotSpecified; } } break; @@ -846,7 +846,7 @@ static int dev_do_io (struct devstruct *dev, uaecptr request) put_long (io_data + 8, diskpos); io_actual = 12; } else { - io_error = CDERR_InvalidState; + io_error = IOERR_InvalidState; } } else { io_error = IOERR_BADADDRESS;