From: Toni Wilen Date: Sat, 9 Mar 2013 13:03:26 +0000 (+0200) Subject: 2600b10 X-Git-Tag: 2600~11 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=18ec7b19afe18a71fac5afd21f76c955dc47b372;p=francis%2Fwinuae.git 2600b10 --- diff --git a/audio.cpp b/audio.cpp index 619ddb72..2ee141e3 100644 --- a/audio.cpp +++ b/audio.cpp @@ -1787,7 +1787,7 @@ void audio_hsync (void) { if (!isaudio ()) return; - if (audio_work_to_do > 0 && currprefs.sound_auto) { + if (audio_work_to_do > 0 && currprefs.sound_auto && !avioutput_enabled) { audio_work_to_do--; if (audio_work_to_do == 0) audio_deactivate (); diff --git a/blkdev.cpp b/blkdev.cpp index a1e49194..2a12ad9b 100644 --- a/blkdev.cpp +++ b/blkdev.cpp @@ -28,6 +28,27 @@ int log_scsiemu = 0; #define PRE_INSERT_DELAY (3 * (currprefs.ntscmode ? 60 : 50)) +struct blkdevstate +{ + int scsiemu; + struct device_functions *device_func; + int isopen; + int waspaused; + int delayed; + uae_sem_t sema; + int sema_cnt; + int play_end_pos; + uae_u8 play_qcode[SUBQ_SIZE]; + TCHAR newimagefile[256]; + int imagechangetime; + bool cdimagefileinuse; + int wasopen; + bool mediawaschanged; +}; + +struct blkdevstate state[MAX_TOTAL_SCSI_DEVICES]; + +#if 0 static int scsiemu[MAX_TOTAL_SCSI_DEVICES]; static struct device_functions *device_func[MAX_TOTAL_SCSI_DEVICES]; @@ -44,6 +65,8 @@ static TCHAR newimagefiles[MAX_TOTAL_SCSI_DEVICES][256]; static int imagechangetime[MAX_TOTAL_SCSI_DEVICES]; static bool cdimagefileinuse[MAX_TOTAL_SCSI_DEVICES]; static int wasopen[MAX_TOTAL_SCSI_DEVICES]; +#endif + static bool dev_init; /* convert minutes, seconds and frames -> logical sector number */ @@ -133,32 +156,34 @@ static int driver_installed[6]; static void install_driver (int flags) { for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) { - scsiemu[i] = false; - device_func[i] = NULL; + struct blkdevstate *st = &state[i]; + st->scsiemu = false; + st->device_func = NULL; } if (flags > 0) { - device_func[0] = devicetable[flags]; - scsiemu[0] = true; + state[0].device_func = devicetable[flags]; + state[0].scsiemu = true; } else { for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) { - scsiemu[i] = false; - device_func[i] = NULL; + struct blkdevstate *st = &state[i]; + st->scsiemu = false; + st->device_func = NULL; switch (cdscsidevicetype[i]) { case SCSI_UNIT_IMAGE: - device_func[i] = devicetable[SCSI_UNIT_IMAGE]; - scsiemu[i] = true; + st->device_func = devicetable[SCSI_UNIT_IMAGE]; + st->scsiemu = true; break; case SCSI_UNIT_IOCTL: - device_func[i] = devicetable[SCSI_UNIT_IOCTL]; - scsiemu[i] = true; + st->device_func = devicetable[SCSI_UNIT_IOCTL]; + st->scsiemu = true; break; case SCSI_UNIT_SPTI: if (currprefs.win32_uaescsimode == UAESCSI_CDEMU) { - device_func[i] = devicetable[SCSI_UNIT_IOCTL]; - scsiemu[i] = true; + st->device_func = devicetable[SCSI_UNIT_IOCTL]; + st->scsiemu = true; } else { - device_func[i] = devicetable[SCSI_UNIT_SPTI]; + st->device_func = devicetable[SCSI_UNIT_SPTI]; } break; } @@ -168,10 +193,11 @@ static void install_driver (int flags) for (int j = 1; devicetable[j]; j++) { if (!driver_installed[j]) { for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) { - if (device_func[i] == devicetable[j]) { - int ok = device_func[i]->openbus (0); + struct blkdevstate *st = &state[i]; + if (st->device_func == devicetable[j]) { + int ok = st->device_func->openbus (0); driver_installed[j] = 1; - write_log (_T("%s driver installed, ok=%d\n"), device_func[i]->name, ok); + write_log (_T("%s driver installed, ok=%d\n"), st->device_func->name, ok); break; } } @@ -225,19 +251,20 @@ 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); + struct blkdevstate *st = &state[unitnum]; + if (st->sema == NULL) + uae_sem_init (&st->sema, 0, 1); bool gotit = false; if (dowait) { - uae_sem_wait (&unitsem[unitnum]); + uae_sem_wait (&st->sema); gotit = true; } else { - gotit = uae_sem_trywait (&unitsem[unitnum]) == 0; + gotit = uae_sem_trywait (&st->sema) == 0; } if (gotit) - unitsem_cnt[unitnum]++; - if (unitsem_cnt[unitnum] > 1) - write_log (_T("CD: unitsem%d acquire mismatch! cnt=%d\n"), unitnum, unitsem_cnt[unitnum]); + st->sema_cnt++; + if (st->sema_cnt > 1) + write_log (_T("CD: unitsem%d acquire mismatch! cnt=%d\n"), unitnum, st->sema_cnt); return gotit; } static bool getsem (int unitnum) @@ -246,41 +273,44 @@ static bool getsem (int unitnum) } static void freesem (int unitnum) { - unitsem_cnt[unitnum]--; - if (unitsem_cnt[unitnum] < 0) - write_log (_T("CD: unitsem%d release mismatch! cnt=%d\n"), unitnum, unitsem_cnt[unitnum]); - uae_sem_post (&unitsem[unitnum]); + struct blkdevstate *st = &state[unitnum]; + st->sema_cnt--; + if (st->sema_cnt < 0) + write_log (_T("CD: unitsem%d release mismatch! cnt=%d\n"), unitnum, st->sema_cnt); + uae_sem_post (&st->sema); } static void sys_command_close_internal (int unitnum) { + struct blkdevstate *st = &state[unitnum]; getsem (unitnum, true); - waspaused[unitnum] = 0; - if (openlist[unitnum] <= 0) - write_log (_T("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]--; + st->waspaused = 0; + if (st->isopen <= 0) + write_log (_T("BUG unit %d close: opencnt=%d!\n"), unitnum, st->isopen); + if (st->device_func) { + state[unitnum].device_func->closedev (unitnum); + if (st->isopen > 0) + st->isopen--; } freesem (unitnum); - if (openlist[unitnum] == 0) { - uae_sem_destroy (&unitsem[unitnum]); - unitsem[unitnum] = NULL; + if (st->isopen == 0) { + uae_sem_destroy (&st->sema); + st->sema = NULL; } } static int sys_command_open_internal (int unitnum, const TCHAR *ident, cd_standard_unit csu) { + struct blkdevstate *st = &state[unitnum]; int ret = 0; - if (unitsem[unitnum] == NULL) - uae_sem_init (&unitsem[unitnum], 0, 1); + if (st->sema == NULL) + uae_sem_init (&st->sema, 0, 1); getsem (unitnum, true); - if (openlist[unitnum]) - write_log (_T("BUG unit %d open: opencnt=%d!\n"), unitnum, openlist[unitnum]); - if (device_func[unitnum]) { - ret = device_func[unitnum]->opendev (unitnum, ident, csu != CD_STANDARD_UNIT_DEFAULT); + if (st->isopen) + write_log (_T("BUG unit %d open: opencnt=%d!\n"), unitnum, st->isopen); + if (st->device_func) { + ret = state[unitnum].device_func->opendev (unitnum, ident, csu != CD_STANDARD_UNIT_DEFAULT); if (ret) - openlist[unitnum]++; + st->isopen++; } freesem (unitnum); return ret; @@ -376,12 +406,13 @@ int get_standard_cd_unit (cd_standard_unit csu) int unitnum = get_standard_cd_unit2 (&currprefs, csu); if (unitnum < 0) return -1; + struct blkdevstate *st = &state[unitnum]; #ifdef RETROPLATFORM rp_cd_device_enable (unitnum, true); #endif - delayed[unitnum] = 0; + st->delayed = 0; if (currprefs.cdslots[unitnum].delayed) { - delayed[unitnum] = PRE_INSERT_DELAY; + st->delayed = PRE_INSERT_DELAY; } return unitnum; } @@ -393,22 +424,24 @@ void close_standard_cd_unit (int unitnum) int sys_command_isopen (int unitnum) { - return openlist[unitnum]; + struct blkdevstate *st = &state[unitnum]; + return st->isopen; } int sys_command_open (int unitnum) { + struct blkdevstate *st = &state[unitnum]; blkdev_fix_prefs (&currprefs); if (!dev_init) { device_func_init (0); dev_init = true; } - if (openlist[unitnum]) { - openlist[unitnum]++; + if (st->isopen) { + st->isopen++; return -1; } - waspaused[unitnum] = 0; + st->waspaused = 0; int v = sys_command_open_internal (unitnum, currprefs.cdslots[unitnum].name[0] ? currprefs.cdslots[unitnum].name : NULL, CD_STANDARD_UNIT_DEFAULT); if (!v) return 0; @@ -420,8 +453,9 @@ int sys_command_open (int unitnum) void sys_command_close (int unitnum) { - if (openlist[unitnum] > 1) { - openlist[unitnum]--; + struct blkdevstate *st = &state[unitnum]; + if (st->isopen > 1) { + st->isopen--; return; } #ifdef RETROPLATFORM @@ -442,11 +476,12 @@ void blkdev_cd_change (int unitnum, const TCHAR *name) void device_func_reset (void) { for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) { - wasopen[i] = 0; - waspaused[i] = false; - imagechangetime[i] = 0; - cdimagefileinuse[i] = false; - newimagefiles[i][0] = 0; + struct blkdevstate *st = &state[i]; + st->wasopen = 0; + st->waspaused = false; + st->imagechangetime = 0; + st->cdimagefileinuse = false; + st->newimagefile[0] = 0; } } @@ -459,8 +494,9 @@ int device_func_init (int flags) bool blkdev_get_info (struct uae_prefs *p, int unitnum, struct device_info *di) { - bool open = true, opened = true, ok = false; - if (!openlist[unitnum]) { + bool open = true, opened = false, ok = false; + struct blkdevstate *st = &state[unitnum]; + if (!st->isopen) { blkdev_fix_prefs (p); install_driver (0); opened = true; @@ -477,24 +513,26 @@ bool blkdev_get_info (struct uae_prefs *p, int unitnum, struct device_info *di) void blkdev_entergui (void) { for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) { - waspaused[i] = 0; + struct blkdevstate *st = &state[i]; + st->waspaused = 0; struct device_info di; if (sys_command_info (i, &di, 1)) { if (sys_command_cd_pause (i, 1) == 0) - waspaused[i] = 1; + st->waspaused = 1; } } } void blkdev_exitgui (void) { for (int i = 0; i < MAX_TOTAL_SCSI_DEVICES; i++) { - if (waspaused[i]) { + struct blkdevstate *st = &state[i]; + if (st->waspaused) { struct device_info di; if (sys_command_info (i, &di, 1)) { sys_command_cd_pause (i, 0); } } - waspaused[i] = 0; + st->waspaused = 0; } } @@ -507,15 +545,16 @@ void check_prefs_changed_cd (void) static void check_changes (int unitnum) { + struct blkdevstate *st = &state[unitnum]; bool changed = false; bool gotsem = false; - if (device_func[unitnum] == NULL) + if (st->device_func == NULL) return; - if (delayed[unitnum]) { - delayed[unitnum]--; - if (delayed[unitnum] == 0) + if (st->delayed) { + st->delayed--; + if (st->delayed == 0) write_log (_T("CD: startup delayed insert '%s'\n"), currprefs.cdslots[unitnum].name[0] ? currprefs.cdslots[unitnum].name : _T("")); return; } @@ -527,32 +566,32 @@ static void check_changes (int unitnum) if (changed) { bool wasimage = currprefs.cdslots[unitnum].name[0] != 0; - if (unitsem[unitnum]) + if (st->sema) gotsem = getsem (unitnum, true); - cdimagefileinuse[unitnum] = changed_prefs.cdslots[unitnum].inuse; - _tcscpy (newimagefiles[unitnum], changed_prefs.cdslots[unitnum].name); + st->cdimagefileinuse = changed_prefs.cdslots[unitnum].inuse; + _tcscpy (st->newimagefile, changed_prefs.cdslots[unitnum].name); changed_prefs.cdslots[unitnum].name[0] = currprefs.cdslots[unitnum].name[0] = 0; currprefs.cdslots[unitnum].inuse = changed_prefs.cdslots[unitnum].inuse; int pollmode = 0; - imagechangetime[unitnum] = 3 * 50; + st->imagechangetime = 3 * 50; struct device_info di; - device_func[unitnum]->info (unitnum, &di, 0, -1); - if (wasopen[unitnum] >= 0) - wasopen[unitnum] = di.open ? 1 : 0; - if (wasopen[unitnum]) { - device_func[unitnum]->closedev (unitnum); - wasopen[unitnum] = -1; + st->device_func->info (unitnum, &di, 0, -1); + if (st->wasopen >= 0) + st->wasopen = di.open ? 1 : 0; + if (st->wasopen) { + st->device_func->closedev (unitnum); + st->wasopen = -1; if (currprefs.scsi) { scsi_do_disk_change (unitnum, 0, &pollmode); if (pollmode) - imagechangetime[unitnum] = 8 * 50; + st->imagechangetime = 8 * 50; if (filesys_do_disk_change (unitnum, 0)) { - imagechangetime[unitnum] = newimagefiles[unitnum][0] ? 3 * 50 : 0; + st->imagechangetime = st->newimagefile[0] ? 3 * 50 : 0; pollmode = 0; } } } - write_log (_T("CD: eject (%s) open=%d\n"), pollmode ? _T("slow") : _T("fast"), wasopen[unitnum] ? 1 : 0); + write_log (_T("CD: eject (%s) open=%d\n"), pollmode ? _T("slow") : _T("fast"), st->wasopen ? 1 : 0); #ifdef RETROPLATFORM rp_cd_image_change (unitnum, NULL); #endif @@ -561,31 +600,31 @@ static void check_changes (int unitnum) gotsem = false; } } - if (imagechangetime[unitnum] == 0) + if (st->imagechangetime == 0) return; - imagechangetime[unitnum]--; - if (imagechangetime[unitnum] > 0) + st->imagechangetime--; + if (st->imagechangetime > 0) return; - if (unitsem[unitnum]) + if (st->sema) gotsem = 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]; - newimagefiles[unitnum][0] = 0; - write_log (_T("CD: delayed insert '%s' (open=%d,unit=%d)\n"), currprefs.cdslots[unitnum].name[0] ? currprefs.cdslots[unitnum].name : _T(""), wasopen[unitnum] ? 1 : 0, unitnum); + _tcscpy (currprefs.cdslots[unitnum].name, st->newimagefile); + _tcscpy (changed_prefs.cdslots[unitnum].name, st->newimagefile); + currprefs.cdslots[unitnum].inuse = changed_prefs.cdslots[unitnum].inuse = st->cdimagefileinuse; + st->newimagefile[0] = 0; + write_log (_T("CD: delayed insert '%s' (open=%d,unit=%d)\n"), currprefs.cdslots[unitnum].name[0] ? currprefs.cdslots[unitnum].name : _T(""), st->wasopen ? 1 : 0, unitnum); device_func_init (0); - if (wasopen[unitnum]) { - if (!device_func[unitnum]->opendev (unitnum, currprefs.cdslots[unitnum].name, 0)) { + if (st->wasopen) { + if (!st->device_func->opendev (unitnum, currprefs.cdslots[unitnum].name, 0)) { write_log (_T("-> device open failed\n")); - wasopen[unitnum] = 0; + st->wasopen = 0; } else { - wasopen[unitnum] = 1; + st->wasopen = 1; write_log (_T("-> device reopened\n")); } } - if (currprefs.scsi && wasopen[unitnum]) { + if (currprefs.scsi && st->wasopen) { struct device_info di; - device_func[unitnum]->info (unitnum, &di, 0, -1); + st->device_func->info (unitnum, &di, 0, -1); int pollmode; if (gotsem) { freesem (unitnum); @@ -594,6 +633,7 @@ static void check_changes (int unitnum) scsi_do_disk_change (unitnum, 1, &pollmode); filesys_do_disk_change (unitnum, 1); } + st->mediawaschanged = true; #ifdef RETROPLATFORM rp_cd_image_change (unitnum, currprefs.cdslots[unitnum].name); #endif @@ -614,12 +654,12 @@ void blkdev_vsync (void) static int do_scsi (int unitnum, uae_u8 *cmd, int cmdlen) { - uae_u8 *p = device_func[unitnum]->exec_out (unitnum, cmd, cmdlen); + uae_u8 *p = state[unitnum].device_func->exec_out (unitnum, cmd, cmdlen); return p != NULL; } static int do_scsi (int unitnum, uae_u8 *cmd, int cmdlen, uae_u8 *out, int outsize) { - uae_u8 *p = device_func[unitnum]->exec_in (unitnum, cmd, cmdlen, &outsize); + uae_u8 *p = state[unitnum].device_func->exec_in (unitnum, cmd, cmdlen, &outsize); if (p) memcpy (out, p, outsize); return p != NULL; @@ -629,7 +669,7 @@ static int failunit (int unitnum) { if (unitnum < 0 || unitnum >= MAX_TOTAL_SCSI_DEVICES) return 1; - if (device_func[unitnum] == NULL) + if (state[unitnum].device_func == NULL) return 1; return 0; } @@ -639,7 +679,7 @@ 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); + uae_u8 *p = state[unitnum].device_func->exec_in (unitnum, cmd, sizeof (cmd), 0); freesem (unitnum); if (!p) return 0; @@ -654,13 +694,13 @@ int sys_command_cd_pause (int unitnum, int paused) if (!getsem (unitnum)) return 0; int v; - if (device_func[unitnum]->pause == NULL) { + if (state[unitnum].device_func->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); v = as == AUDIO_STATUS_PAUSED; } else { - v = device_func[unitnum]->pause (unitnum, paused); + v = state[unitnum].device_func->pause (unitnum, paused); } freesem (unitnum); return v; @@ -673,12 +713,12 @@ void sys_command_cd_stop (int unitnum) return; if (!getsem (unitnum)) return; - if (device_func[unitnum]->stop == NULL) { + if (state[unitnum].device_func->stop == NULL) { int as = audiostatus (unitnum); uae_u8 cmd[6] = {0x4e,0,0,0,0,0}; do_scsi (unitnum, cmd, sizeof cmd); } else { - device_func[unitnum]->stop (unitnum); + state[unitnum].device_func->stop (unitnum); } freesem (unitnum); } @@ -691,8 +731,8 @@ int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int scan) return 0; if (!getsem (unitnum)) return 0; - play_end_pos[unitnum] = endlsn; - if (device_func[unitnum]->play == NULL) { + state[unitnum].play_end_pos = endlsn; + if (state[unitnum].device_func->play == NULL) { uae_u8 cmd[12] = {0,0,0,0,0,0,0,0,0,0,0,0}; int startmsf = lsn2msf (startlsn); int endmsf = lsn2msf (endlsn); @@ -705,7 +745,7 @@ int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int scan) cmd[8] = (uae_u8)(endmsf >> 0); v = do_scsi (unitnum, cmd, sizeof cmd) ? 0 : 1; } else { - v = device_func[unitnum]->play (unitnum, startlsn, endlsn, scan, NULL, NULL); + v = state[unitnum].device_func->play (unitnum, startlsn, endlsn, scan, NULL, NULL); } freesem (unitnum); return v; @@ -719,10 +759,10 @@ int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int scan, play_s return 0; if (!getsem (unitnum)) return 0; - if (device_func[unitnum]->play == NULL) + if (state[unitnum].device_func->play == NULL) v = sys_command_cd_play (unitnum, startlsn, endlsn, scan); else - v = device_func[unitnum]->play (unitnum, startlsn, endlsn, scan, statusfunc, subfunc); + v = state[unitnum].device_func->play (unitnum, startlsn, endlsn, scan, statusfunc, subfunc); freesem (unitnum); return v; } @@ -735,10 +775,10 @@ uae_u32 sys_command_cd_volume (int unitnum, uae_u16 volume_left, uae_u16 volume_ return 0; if (!getsem (unitnum)) return 0; - if (device_func[unitnum]->volume == NULL) + if (state[unitnum].device_func->volume == NULL) v = -1; else - v = device_func[unitnum]->volume (unitnum, volume_left, volume_right); + v = state[unitnum].device_func->volume (unitnum, volume_left, volume_right); freesem (unitnum); return v; } @@ -751,11 +791,11 @@ int sys_command_cd_qcode (int unitnum, uae_u8 *buf) return 0; if (!getsem (unitnum)) return 0; - if (device_func[unitnum]->qcode == NULL) { + if (state[unitnum].device_func->qcode == NULL) { uae_u8 cmd[10] = {0x42,2,0x40,1,0,0,0,(uae_u8)(SUBQ_SIZE>>8),(uae_u8)(SUBQ_SIZE&0xff),0}; v = do_scsi (unitnum, cmd, sizeof cmd, buf, SUBQ_SIZE); } else { - v = device_func[unitnum]->qcode (unitnum, buf, -1); + v = state[unitnum].device_func->qcode (unitnum, buf, -1); } freesem (unitnum); return v; @@ -769,7 +809,7 @@ int sys_command_cd_toc (int unitnum, struct cd_toc_head *toc) return 0; if (!getsem (unitnum)) return 0; - if (device_func[unitnum]->toc == NULL) { + if (state[unitnum].device_func->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}; @@ -779,7 +819,7 @@ int sys_command_cd_toc (int unitnum, struct cd_toc_head *toc) } v = 0; } else { - v = device_func[unitnum]->toc (unitnum, toc); + v = state[unitnum].device_func->toc (unitnum, toc); } freesem (unitnum); return v; @@ -793,7 +833,7 @@ int sys_command_cd_read (int unitnum, uae_u8 *data, int block, int size) return 0; if (!getsem (unitnum)) return 0; - if (device_func[unitnum]->read == NULL) { + if (state[unitnum].device_func->read == NULL) { uae_u8 cmd1[12] = { 0x28, 0, block >> 24, block >> 16, block >> 8, block >> 0, 0, size >> 8, size >> 0, 0, 0, 0 }; v = do_scsi (unitnum, cmd1, sizeof cmd1, data, size * 2048); #if 0 @@ -803,7 +843,7 @@ int sys_command_cd_read (int unitnum, uae_u8 *data, int block, int size) } #endif } else { - v = device_func[unitnum]->read (unitnum, data, block, size); + v = state[unitnum].device_func->read (unitnum, data, block, size); } freesem (unitnum); return v; @@ -815,11 +855,11 @@ int sys_command_cd_rawread (int unitnum, uae_u8 *data, int block, int size, int return -1; if (!getsem (unitnum)) return 0; - if (device_func[unitnum]->rawread == NULL) { + if (state[unitnum].device_func->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 }; v = do_scsi (unitnum, cmd, sizeof cmd, data, size * sectorsize); } else { - v = device_func[unitnum]->rawread (unitnum, data, block, size, sectorsize, 0xffffffff); + v = state[unitnum].device_func->rawread (unitnum, data, block, size, sectorsize, 0xffffffff); } freesem (unitnum); return v; @@ -831,11 +871,11 @@ int sys_command_cd_rawread (int unitnum, uae_u8 *data, int block, int size, int return -1; if (!getsem (unitnum)) return 0; - if (device_func[unitnum]->rawread == NULL) { + if (state[unitnum].device_func->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 }; 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); + v = state[unitnum].device_func->rawread (unitnum, data, block, size, sectorsize, (sectortype << 16) | (scsicmd9 << 8) | subs); } freesem (unitnum); return v; @@ -849,7 +889,7 @@ int sys_command_read (int unitnum, uae_u8 *data, int block, int size) return 0; if (!getsem (unitnum)) return 0; - if (device_func[unitnum]->read == NULL) { + if (state[unitnum].device_func->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); @@ -857,7 +897,7 @@ int sys_command_read (int unitnum, uae_u8 *data, int block, int size) cmd[5] = (uae_u8)(block >> 0); v = do_scsi (unitnum, cmd, sizeof cmd, data, size * 2048); } else { - v = device_func[unitnum]->read (unitnum, data, block, size); + v = state[unitnum].device_func->read (unitnum, data, block, size); } freesem (unitnum); return v; @@ -871,10 +911,10 @@ int sys_command_write (int unitnum, uae_u8 *data, int offset, int size) return 0; if (!getsem (unitnum)) return 0; - if (device_func[unitnum]->write == NULL) { + if (state[unitnum].device_func->write == NULL) { v = 0; } else { - v = device_func[unitnum]->write (unitnum, data, offset, size); + v = state[unitnum].device_func->write (unitnum, data, offset, size); } freesem (unitnum); return v; @@ -883,17 +923,18 @@ int sys_command_write (int unitnum, uae_u8 *data, int offset, int size) int sys_command_ismedia (int unitnum, int quick) { int v; + struct blkdevstate *st = &state[unitnum]; if (failunit (unitnum)) return -1; - if (delayed[unitnum]) + if (st->delayed) return 0; if (!getsem (unitnum)) return 0; - if (device_func[unitnum]->ismedia == NULL) { + if (state[unitnum].device_func->ismedia == NULL) { uae_u8 cmd[6] = { 0, 0, 0, 0, 0, 0 }; v = do_scsi (unitnum, cmd, sizeof cmd); } else { - v = device_func[unitnum]->ismedia (unitnum, quick); + v = state[unitnum].device_func->ismedia (unitnum, quick); } freesem (unitnum); return v; @@ -901,14 +942,15 @@ int sys_command_ismedia (int unitnum, int quick) struct device_info *sys_command_info_session (int unitnum, struct device_info *di, int quick, int session) { + struct blkdevstate *st = &state[unitnum]; if (failunit (unitnum)) return NULL; if (!getsem (unitnum)) return 0; - if (device_func[unitnum]->info == NULL) + if (st->device_func->info == NULL) return 0; - struct device_info *di2 = device_func[unitnum]->info (unitnum, di, quick, -1); - if (di2 && delayed[unitnum]) + struct device_info *di2 = st->device_func->info (unitnum, di, quick, -1); + if (di2 && st->delayed) di2->media_inserted = 0; freesem (unitnum); return di2; @@ -1044,15 +1086,15 @@ static bool nodisk (struct device_info *di) { return di->media_inserted == 0; } -static uae_u64 cmd_readx (int unitnum, uae_u8 *dataptr, int offset, int len) +static int cmd_readx (int unitnum, uae_u8 *dataptr, int offset, int len) { if (!getsem (unitnum)) return 0; - int v = device_func[unitnum]->read (unitnum, dataptr, offset, len); + int v = state[unitnum].device_func->read (unitnum, dataptr, offset, len); freesem (unitnum); - if (v) + if (v >= 0) return len; - return 0; + return v; } static void wl (uae_u8 *p, int v) @@ -1123,8 +1165,8 @@ static int scsiemudrv (int unitnum, uae_u8 *cmd) if (!getsem (unitnum)) return 0; int v = 0; - if (device_func[unitnum]->scsiemu) - v = device_func[unitnum]->scsiemu (unitnum, cmd); + if (state[unitnum].device_func->scsiemu) + v = state[unitnum].device_func->scsiemu (unitnum, cmd); freesem (unitnum); return v; } @@ -1146,37 +1188,77 @@ static int scsi_read_cd (int unitnum, uae_u8 *cmd, uae_u8 *data, struct device_i return sys_command_cd_rawread (unitnum, data, start, len, 0, (cmd[1] >> 2) & 7, cmd[9], subs); } +static int scsi_read_cd_data (int unitnum, uae_u8 *scsi_data, uae_u32 offset, uae_u32 len, struct device_info *di, int *scsi_len) +{ + if (len == 0) { + *scsi_len = 0; + return 0; + } else { + if (len * di->bytespersector > SCSI_DATA_BUFFER_SIZE) + return -3; + if (offset >= di->sectorspertrack) + return -1; + int v = cmd_readx (unitnum, scsi_data, offset, len) * di->bytespersector; + if (v > 0) { + *scsi_len = v; + return 0; + } + return -2; + } +} + int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, uae_u8 *scsi_data, int *data_len, uae_u8 *r, int *reply_len, uae_u8 *s, int *sense_len, bool atapi) { - uae_u64 len, offset; + struct blkdevstate *st = &state[unitnum]; + uae_u32 len, offset; int lr = 0, ls = 0; int scsi_len = -1; + int v; int status = 0; struct device_info di; uae_u8 cmd = cmdbuf[0]; - int dlen = *data_len; - + int dlen; + + if (cmd == 0x03) { /* REQUEST SENSE */ + st->mediawaschanged = false; + return 0; + } + + dlen = *data_len; *reply_len = *sense_len = 0; memset (r, 0, 256); memset (s, 0, 256); sys_command_info (unitnum, &di, 1); - if (cmdbuf[0] == 0) { /* TEST UNIT READY */ - if (nodisk (&di)) - goto nodisk; - scsi_len = 0; - goto end; - } - if (log_scsiemu) + if (log_scsiemu) { write_log (_T("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, dlen); + } + + // media changed and not inquiry + if (st->mediawaschanged && cmd != 0x12) { + if (log_scsiemu) { + write_log (_T("SCSIEMU %d: MEDIUM MAY HAVE CHANGED STATE\n")); + } + lr = -1; + status = 2; /* CHECK CONDITION */ + s[0] = 0x70; + s[2] = 6; /* UNIT ATTENTION */ + s[12] = 0x28; /* MEDIUM MAY HAVE CHANGED */ + ls = 0x12; + goto end; + } + switch (cmdbuf[0]) { - case 0x03: /* REQUEST SENSE */ + case 0x00: /* TEST UNIT READY */ + if (nodisk (&di)) + goto nodisk; + scsi_len = 0; break; case 0x1e: /* PREVENT/ALLOW MEDIUM REMOVAL */ scsi_len = 0; @@ -1198,7 +1280,7 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, r[3] |= 3 << 5; // atapi transport version r[4] = 32; /* additional length */ r[7] = 0; - scsi_len = lr = len < 36 ? (uae_u32)len : 36; + scsi_len = lr = len < 36 ? len : 36; r[2] = 2; r[3] = 2; char *s = ua (di.vendorid); @@ -1283,13 +1365,10 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, } bdsize = 0; if (!dbd) { - if (nodisk (&di)) - goto nodisk; - uae_u32 blocks = di.sectorspertrack * di.cylinders * di.trackspercylinder; - bdsize = 8; - wl(p + 0, blocks); + wl(p + 0, 0); wl(p + 4, di.bytespersector); - p += 8; + bdsize = 8; + p += bdsize; } if (pcode == 0x3f) { pcode = 1; // page = 0 must be last @@ -1303,36 +1382,11 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, p[2] = 0x20; p[3] = 0; psize = 4; -#if 0 - } else if (pcode == 3) { - if (nodisk (&di)) - goto nodisk; - p[0] = 3; - p[1] = 24; - p[3] = 1; - p[10] = di.trackspercylinder >> 8; - p[11] = di.trackspercylinder; - p[12] = di.bytespersector >> 8; - p[13] = di.bytespersector; - p[15] = 1; // interleave - p[20] = 0x80; - psize = p[1]; - } else if (pcode == 4) { - if (nodisk (&di)) - goto nodisk; - p[0] = 4; - wl(p + 1, di.cylinders); - p[1] = 24; - p[5] = 1; - wl(p + 13, di.cylinders); - ww(p + 20, 0); - psize = p[1]; -#endif } else if (pcode == 14) { // CD audio control uae_u32 vol = sys_command_cd_volume (unitnum, 0xffff, 0xffff); p[0] = 0x0e; p[1] = 0x0e; - p[2] = 1; + p[2] = 4|1; p[3] = 4; p[6] = 0; p[7] = 75; @@ -1340,7 +1394,7 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, p[9] = pc == 0 ? (vol >> 7) & 0xff : 0xff; p[10] = 2; p[11] = pc == 0 ? (vol >> (16 + 7)) & 0xff : 0xff; - psize = p[1]; + psize = p[1] + 2; } else if (pcode == 0x2a) { // cd/dvd capabilities p[0] = 0x2a; p[1] = 0x18; @@ -1359,7 +1413,7 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, p[18] = p[19] = 0; p[20] = p[21] = 0; p[22] = p[23] = 0; - psize = p[1]; + psize = p[1] + 2; } else { if (!pcodeloop) goto err; @@ -1396,7 +1450,7 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, case 0x1d: /* SEND DIAGNOSTICS */ scsi_len = 0; break; - case 0x25: /* READ_CAPACITY */ + case 0x25: /* READ CAPACITY */ { int pmi = cmdbuf[8] & 1; uae_u32 lba = (cmdbuf[2] << 24) | (cmdbuf[3] << 16) | (cmdbuf[4] << 8) | cmdbuf[5]; @@ -1433,9 +1487,13 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, len = cmdbuf[4]; if (!len) len = 256; - if (len * di.bytespersector > SCSI_DATA_BUFFER_SIZE) + v = scsi_read_cd_data (unitnum, scsi_data, offset, len, &di, &scsi_len); + if (v == -1) + goto outofbounds; + if (v == -2) + goto readerr; + if (v == -3) goto toolarge; - scsi_len = (uae_u32)cmd_readx (unitnum, scsi_data, offset, len) * di.bytespersector;; } else { goto notdatatrack; } @@ -1452,9 +1510,13 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, struct cd_toc *t = gettoc (&di.toc, offset); if ((t->control & 0x0c) == 0x04) { len = rl (cmdbuf + 7 - 2) & 0xffff; - if (len * di.bytespersector > SCSI_DATA_BUFFER_SIZE) + v = scsi_read_cd_data (unitnum, scsi_data, offset, len, &di, &scsi_len); + if (v == -1) + goto outofbounds; + if (v == -2) + goto readerr; + if (v == -3) goto toolarge; - scsi_len = cmd_readx (unitnum, scsi_data, offset, len) * di.bytespersector; } else { goto notdatatrack; } @@ -1471,9 +1533,13 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, struct cd_toc *t = gettoc (&di.toc, offset); if ((t->control & 0x0c) == 0x04) { len = rl (cmdbuf + 6); - if (len * di.bytespersector > SCSI_DATA_BUFFER_SIZE) + v = scsi_read_cd_data (unitnum, scsi_data, offset, len, &di, &scsi_len); + if (v == -1) + goto outofbounds; + if (v == -2) + goto readerr; + if (v == -3) goto toolarge; - scsi_len = (uae_u32)cmd_readx (unitnum, scsi_data, offset, len) * di.bytespersector;; } else { goto notdatatrack; } @@ -1812,11 +1878,18 @@ int scsi_cd_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, scsi_len = 0; } break; + case 0x35: /* SYNCRONIZE CACHE (10) */ + scsi_len = 0; + break; + + default: +err: + write_log (_T("CDEMU: unsupported scsi command 0x%02X\n"), cmdbuf[0]); readprot: status = 2; /* CHECK CONDITION */ s[0] = 0x70; - s[2] = 7; /* DATA PROTECT */ - s[12] = 0x27; /* WRITE PROTECTED */ + s[2] = 5; + s[12] = 0x20; /* INVALID COMMAND */ ls = 0x12; break; nodisk: @@ -1840,6 +1913,13 @@ notdatatrack: s[12] = 0x64; /* ILLEGAL MODE FOR THIS TRACK */ ls = 0x12; break; +outofbounds: + status = 2; /* CHECK CONDITION */ + s[0] = 0x70; + s[2] = 5; /* ILLEGAL REQUEST */ + s[12] = 0x21; /* LOGICAL BLOCK OUT OF RANGE */ + ls = 0x12; + break; toolarge: write_log (_T("CDEMU: too large scsi data tranfer %d > %d\n"), len, dlen); status = 2; /* CHECK CONDITION */ @@ -1848,10 +1928,6 @@ toolarge: s[12] = 0x11; /* UNRECOVERED READ ERROR */ ls = 0x12; break; - - default: -err: - write_log (_T("CDEMU: unsupported scsi command 0x%02X\n"), cmdbuf[0]); errreq: lr = -1; status = 2; /* CHECK CONDITION */ @@ -1868,6 +1944,9 @@ end: if (ls) { //s[0] |= 0x80; s[7] = ls - 7; // additional sense length + if (log_scsiemu) { + write_log (_T("-> SENSE STATUS: KEY=%d ASC=%02X ASCQ=%02X\n"), s[2], s[12], s[13]); + } } if (cmdbuf[0] && log_scsiemu) write_log (_T("-> DATAOUT=%d ST=%d SENSELEN=%d\n"), scsi_len, status, ls); @@ -1890,6 +1969,9 @@ static int execscsicmd_direct (int unitnum, struct amigascsi *as) if (as->sense_len > 32) as->sense_len = 32; + /* never report media change state if uaescsi.device */ + state[unitnum].mediawaschanged = false; + as->status = scsi_cd_emulate (unitnum, cmd, as->cmd_len, scsi_datap, &datalen, replydata, &replylen, as->sensedata, &senselen, false); as->cmdactual = as->status != 0 ? 0 : as->cmd_len; /* fake scsi_CmdActual */ @@ -1921,14 +2003,15 @@ static int execscsicmd_direct (int unitnum, struct amigascsi *as) int sys_command_scsi_direct_native (int unitnum, struct amigascsi *as) { - if (scsiemu[unitnum]) { + struct blkdevstate *st = &state[unitnum]; + if (st->scsiemu) { return execscsicmd_direct (unitnum, as); } else { - if (!device_func[unitnum]->exec_direct) + if (!st->device_func->exec_direct) return -1; } - int ret = device_func[unitnum]->exec_direct (unitnum, as); - if (!ret && device_func[unitnum]->isatapi(unitnum)) + int ret = st->device_func->exec_direct (unitnum, as); + if (!ret && st->device_func->isatapi(unitnum)) scsi_atapi_fixup_inquiry (as); return ret; } @@ -1978,9 +2061,10 @@ int sys_command_scsi_direct (int unitnum, uaecptr acmd) uae_u8 *save_cd (int num, int *len) { + struct blkdevstate *st = &state[num]; uae_u8 *dstbak, *dst; - memset(play_qcode[num], 0, SUBQ_SIZE); + memset(st->play_qcode, 0, SUBQ_SIZE); if (!currprefs.cdslots[num].inuse || num >= MAX_TOTAL_SCSI_DEVICES) return NULL; if (!currprefs.cs_cd32cd && !currprefs.cs_cdtvcd && !currprefs.scsi) @@ -1991,16 +2075,17 @@ uae_u8 *save_cd (int num, int *len) save_u32 (currprefs.cdslots[num].type); save_u32 (0); save_u32 (0); - sys_command_cd_qcode (num, play_qcode[num]); + sys_command_cd_qcode (num, st->play_qcode); for (int i = 0; i < SUBQ_SIZE; i++) - save_u8 (play_qcode[num][i]); - save_u32 (play_end_pos[num]); + save_u8 (st->play_qcode[i]); + save_u32 (st->play_end_pos); *len = dst - dstbak; return dstbak; } uae_u8 *restore_cd (int num, uae_u8 *src) { + struct blkdevstate *st = &state[num]; uae_u32 flags; TCHAR *s; @@ -2020,8 +2105,8 @@ uae_u8 *restore_cd (int num, uae_u8 *src) if (flags & 8) { restore_u32 (); for (int i = 0; i < SUBQ_SIZE; i++) - play_qcode[num][i] = restore_u8 (); - play_end_pos[num] = restore_u32 (); + st->play_qcode[i] = restore_u8 (); + st->play_end_pos = restore_u32 (); } return src; } diff --git a/blkdev_cdimage.cpp b/blkdev_cdimage.cpp index f1bdfcf0..d427500c 100644 --- a/blkdev_cdimage.cpp +++ b/blkdev_cdimage.cpp @@ -605,7 +605,8 @@ static int command_pause (int unitnum, int paused) if (!cdu) return -1; int old = cdu->cdda_paused; - cdu->cdda_paused = paused; + if ((paused && cdu->cdda_play) || !paused) + cdu->cdda_paused = paused; return old; } @@ -1654,7 +1655,7 @@ static int parse_image (struct cdunit *cdu, const TCHAR *img) else write_log (_T(" ")); write_log (_T("%7d %02d:%02d:%02d"), - t->address, (msf >> 16) & 0xff, (msf >> 8) & 0xff, (msf >> 0) & 0xff); + t->address, (msf >> 16) & 0x7fff, (msf >> 8) & 0xff, (msf >> 0) & 0xff); if (i < cdu->tracks) { write_log (_T(" %s %x %10lld %10lld %s%s"), (t->ctrl & 4) ? _T("DATA ") : (t->subcode ? _T("CDA+SUB") : _T("CDA ")), @@ -1670,7 +1671,7 @@ static int parse_image (struct cdunit *cdu, const TCHAR *img) } cdu->blocksize = 2048; - cdu->cdsize = cdu->toc[cdu->tracks].address * cdu->blocksize; + cdu->cdsize = (uae_u64)cdu->toc[cdu->tracks].address * cdu->blocksize; zfile_fclose (zcue); diff --git a/cia.cpp b/cia.cpp index 0a0bc5f7..74bc12b0 100644 --- a/cia.cpp +++ b/cia.cpp @@ -454,6 +454,15 @@ static int checkalarm (unsigned long tod, unsigned long alarm, int inc) STATIC_INLINE void ciab_checkalarm (int inc) { + // hack: do not trigger alarm interrupt if KS code and both + // tod and alarm == 0. This incorrectly triggers on non-cycle exact + // modes. Real hardware value written to ciabtod by KS is always + // at least 1 or larger due to bus cycle delays when reading + // old value. + if ((munge24 (m68k_getpc ()) & 0xFFF80000) == 0xF80000) { + if (ciabtod == 0 && ciabalarm == 0) + return; + } if (checkalarm (ciabtod, ciabalarm, inc)) { ciabicr |= 4; RethinkICRB (); @@ -1532,8 +1541,8 @@ static uae_u32 REGPARAM2 cia_bget (uaecptr addr) case 3: if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible) v = (addr & 1) ? regs.irc : regs.irc >> 8; - if (warned > 0) { - write_log (_T("cia_bget: unknown CIA address %x PC=%x\n"), addr, M68K_GETPC); + if (warned > 0 || currprefs.illegal_mem) { + write_log (_T("cia_bget: unknown CIA address %08X=%02X PC=%08X\n"), addr, v & 0xff, M68K_GETPC); warned--; } break; @@ -1571,8 +1580,8 @@ static uae_u32 REGPARAM2 cia_wget (uaecptr addr) case 3: if (currprefs.cpu_model == 68000 && currprefs.cpu_compatible) v = regs.irc; - if (warned > 0) { - write_log (_T("cia_wget: unknown CIA address %x PC=%x\n"), addr, M68K_GETPC); + if (warned > 0 || currprefs.illegal_mem) { + write_log (_T("cia_wget: unknown CIA address %08X=%04X PC=%08X\n"), addr, v & 0xffff, M68K_GETPC); warned--; } break; @@ -1619,8 +1628,8 @@ static void REGPARAM2 cia_bput (uaecptr addr, uae_u32 value) WriteCIAB (r, value); if ((addr & 0x1000) == 0) WriteCIAA (r, value); - if (((addr & 0x3000) == 0x3000) && warned > 0) { - write_log (_T("cia_bput: unknown CIA address %x %x\n"), addr, value); + if (((addr & 0x3000) == 0x3000) && (warned > 0 || currprefs.illegal_mem)) { + write_log (_T("cia_bput: unknown CIA address %08X=%082X PC=%08X\n"), addr, value & 0xff, M68K_GETPC); warned--; } } @@ -1644,8 +1653,8 @@ static void REGPARAM2 cia_wput (uaecptr addr, uae_u32 value) WriteCIAB (r, value >> 8); if ((addr & 0x1000) == 0) WriteCIAA (r, value & 0xff); - if (((addr & 0x3000) == 0x3000) && warned > 0) { - write_log (_T("cia_wput: unknown CIA address %x %x\n"), addr, value); + if (((addr & 0x3000) == 0x3000) && (warned > 0 || currprefs.illegal_mem)) { + write_log (_T("cia_wput: unknown CIA address %08X=%04X %08X\n"), addr, value & 0xffff, M68K_GETPC); warned--; } } diff --git a/custom.cpp b/custom.cpp index 220d2b33..0881558d 100644 --- a/custom.cpp +++ b/custom.cpp @@ -2479,11 +2479,19 @@ static void calcsprite (void) int min, max; min = tospritexddf (thisline_decision.plfleft); max = tospritexddf (thisline_decision.plfright); - if (min > sprite_minx && min < max) /* min < max = full line ddf */ - sprite_minx = min; + if (min > sprite_minx && min < max) { /* min < max = full line ddf */ + if (currprefs.chipset_mask & CSMASK_ECS_DENISE) { + sprite_minx = min; + } else { + if (thisline_decision.plfleft >= 0x28 || bpldmawasactive) + sprite_minx = min; + } + } /* sprites are visible from first BPL1DAT write to end of line - * (undocumented feature) - */ + * ECS Denise/AGA: not limits + * OCS Denise: BPL1DAT write only enables sprite if hpos >= 0x28 or so. + * (undocumented feature) + */ } } @@ -3012,7 +3020,7 @@ void compute_framesync (void) gfxvidinfo.drawbuffer.extrawidth = 0; gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.inwidth; - gfxvidinfo.drawbuffer.inheight = (maxvpos - minfirstline) << vres2; + gfxvidinfo.drawbuffer.inheight = (maxvpos - minfirstline + 1) << vres2; gfxvidinfo.drawbuffer.inheight2 = gfxvidinfo.drawbuffer.inheight; } else { @@ -3020,7 +3028,7 @@ void compute_framesync (void) gfxvidinfo.drawbuffer.inwidth = AMIGA_WIDTH_MAX << currprefs.gfx_resolution; gfxvidinfo.drawbuffer.extrawidth = currprefs.gfx_extrawidth ? currprefs.gfx_extrawidth : -1; gfxvidinfo.drawbuffer.inwidth2 = gfxvidinfo.drawbuffer.inwidth; - gfxvidinfo.drawbuffer.inheight = (maxvpos_nom - minfirstline + 1) << currprefs.gfx_vresolution; + gfxvidinfo.drawbuffer.inheight = ((maxvpos_nom + 1) - minfirstline + 1) << currprefs.gfx_vresolution; gfxvidinfo.drawbuffer.inheight2 = gfxvidinfo.drawbuffer.inheight; } @@ -3422,7 +3430,7 @@ static uae_u16 VPOSR (void) vp |= lol ? 0x80 : 0; hsyncdelay (); #if 0 - if (M68K_GETPC < 0x00f00000 || M68K_GETPC >= 0x10000000) + if (1 || (M68K_GETPC < 0x00f00000 || M68K_GETPC >= 0x10000000)) write_log (_T("VPOSR %04x at %08x\n"), vp, M68K_GETPC); #endif return vp; @@ -5487,7 +5495,7 @@ static bool framewait (void) t += (int)start - (int)vsync_time; if (!frame_shown) - show_screen (); + show_screen (1); int legacy_avg = mavg (&ma_legacy, t, MAVG_VSYNC_SIZE); if (t > legacy_avg) @@ -5758,7 +5766,7 @@ static bool framewait (void) vsyncmintime = curr_time; vsyncmaxtime = vsyncwaittime = curr_time + vstb; if (frame_rendered) { - show_screen (); + show_screen (0); t += read_processor_time () - curr_time; } t += frameskipt_avg; @@ -5840,7 +5848,7 @@ static void vsync_handler_pre (void) if (vsync_handle_check ()) { redraw_frame (); render_screen (true); - show_screen (); + show_screen (0); } config_check_vsync (); } diff --git a/disk.cpp b/disk.cpp index 37f9680b..681ff676 100644 --- a/disk.cpp +++ b/disk.cpp @@ -303,7 +303,8 @@ static void createrootblock (uae_u8 *sector, const TCHAR *disk_name) { char *dn = ua (disk_name); char *dn2 = dn; - dn2[30] = 0; + if (strlen (dn2) >= 30) + dn2[30] = 0; if (dn2[0] == 0) dn2 = "empty"; memset (sector, 0, FS_FLOPPY_BLOCKSIZE); diff --git a/filesys.cpp b/filesys.cpp index 2680a8df..c1816945 100644 --- a/filesys.cpp +++ b/filesys.cpp @@ -914,6 +914,8 @@ struct hardfiledata *get_hardfile_data (int nr) #define ACTION_ADD_NOTIFY 4097 #define ACTION_REMOVE_NOTIFY 4098 +#define ACTION_READ_LINK 1024 + #define ACTION_CHANGE_FILE_POSITION64 8001 #define ACTION_GET_FILE_POSITION64 8002 #define ACTION_CHANGE_FILE_SIZE64 8003 @@ -921,7 +923,6 @@ struct hardfiledata *get_hardfile_data (int nr) /* not supported */ #define ACTION_MAKE_LINK 1021 -#define ACTION_READ_LINK 1024 #define DISK_TYPE_DOS 0x444f5300 /* DOS\0 */ #define DISK_TYPE_DOS_FFS 0x444f5301 /* DOS\1 */ @@ -2106,6 +2107,10 @@ static a_inode *lookup_aino (Unit *unit, uae_u32 uniq) aino_test (a); return a; } +static a_inode *aino_from_lock (Unit *unit, uaecptr lock) +{ + return lookup_aino (unit, get_long (lock + 4)); +} TCHAR *build_nname (const TCHAR *d, const TCHAR *n) { @@ -2963,7 +2968,7 @@ static void get_long (lock) << 2, get_long (lock + 8), get_long (lock + 12), get_long (lock + 16), get_long (lock + 4))); - a = lookup_aino (unit, get_long (lock + 4)); + a = aino_from_lock (unit, lock); if (a == 0) { TRACE((_T("not found!"))); } else { @@ -2978,7 +2983,7 @@ static a_inode *find_aino (Unit *unit, uaecptr lock, const TCHAR *name, int *err a_inode *a; if (lock) { - a_inode *olda = lookup_aino (unit, get_long (lock + 4)); + a_inode *olda = aino_from_lock (unit, lock); if (olda == 0) { /* That's the best we can hope to do. */ a = get_aino (unit, &unit->rootnode, name, err); @@ -3226,7 +3231,6 @@ static void action_read_link_add_parent (Unit *u, a_inode *a, TCHAR *path) } } -#if 0 #define LINK_HARD 0 #define LINK_SOFT 1 @@ -3234,35 +3238,62 @@ static void action_make_link (Unit *unit, dpacket packet) { uaecptr lock = GET_PCK_ARG1 (packet) << 2; uaecptr name = GET_PCK_ARG2 (packet) << 2; - uaecptr linkname = GET_PCK_ARG3 (packet); + uaecptr target = GET_PCK_ARG3 (packet); int type = GET_PCK_ARG4 (packet); a_inode *a1, *a2; int err; + TCHAR tmp[256], tmp2[MAX_DPATH], tmp3[MAX_DPATH]; + + _tcscpy (tmp, bstr (unit, name)); + a1 = aino_from_lock (unit, lock); if (type == LINK_HARD) { + + // we don't support hard links + uaecptr tlock = target << 2; + a2 = aino_from_lock (unit, tlock); + write_log (_T("ACTION_MAKE_LINK(HARD,'%s','%s','%s')\n"), + a1 ? a1->aname : _T("?"), tmp, + a2 ? a2->aname : _T("?")); + PUT_PCK_RES1 (packet, DOS_FALSE); PUT_PCK_RES2 (packet, ERROR_NOT_IMPLEMENTED); - return; - } - a1 = find_aino (unit, lock, bstr (unit, name), &err); - if (err != 0) { - PUT_PCK_RES1 (packet, DOS_FALSE); - PUT_PCK_RES2 (packet, err); - return; - } - a2 = find_aino (unit, lock, cstr (unit, linkname), &err); - if (err != 0) { - PUT_PCK_RES1 (packet, DOS_FALSE); - PUT_PCK_RES2 (packet, err); - return; - } - if (!my_createsoftlink (a1->nname, a2->nname)) { + + } else { + + a_inode *a3; + TCHAR *link = cstr (unit, target); + write_log (_T("ACTION_MAKE_LINK(SOFT,'%s','%s','%s')\n"), + a1 ? a1->aname : _T("?"), tmp, link); + if (!a1) { + PUT_PCK_RES1 (packet, DOS_FALSE); + PUT_PCK_RES2 (packet, ERROR_OBJECT_NOT_AROUND); + return; + } + // try to find softlink target + for (Unit *u = units; u; u = u->next) { + if (u->volflags & (MYVOLUMEINFO_ARCHIVE | MYVOLUMEINFO_CDFS)) + continue; + a3 = find_aino (u, NULL, link, &err); + if (err || !a3) + continue; + _tcscpy (tmp2, a1->nname); + _tcscat (tmp2, FSDB_DIR_SEPARATOR_S); + _tcscat (tmp2, tmp); + tmp3[0] = 0; + action_read_link_add_parent (u, a3, tmp3); + if (!my_createshortcut (tmp2, a3->nname, tmp3)) { + PUT_PCK_RES1 (packet, DOS_FALSE); + PUT_PCK_RES2 (packet, dos_errno ()); + } + return; + } + // real Amiga softlinks would accept invalid paths too, + // we won't. PUT_PCK_RES1 (packet, DOS_FALSE); PUT_PCK_RES2 (packet, ERROR_OBJECT_NOT_AROUND); - return; } } -#endif static void action_read_link (Unit *unit, dpacket packet) { @@ -3270,9 +3301,9 @@ static void action_read_link (Unit *unit, dpacket packet) uaecptr name = GET_PCK_ARG2 (packet); uaecptr newname = GET_PCK_ARG3 (packet); int size = GET_PCK_ARG4 (packet); - a_inode *a; - Unit *u = NULL; - int err, i; + a_inode *a, *matched_aino; + Unit *u = NULL, *u2 = NULL, *matched_unit; + int err, i, matched_len; TCHAR tmp[MAX_DPATH]; TCHAR *namep, *extrapath; @@ -3291,46 +3322,55 @@ static void action_read_link (Unit *unit, dpacket packet) } } } + if (!a->softlink) + err = ERROR_OBJECT_WRONG_TYPE; if (err != 0) { PUT_PCK_RES1 (packet, DOS_FALSE); PUT_PCK_RES2 (packet, err); return; } _tcscpy (tmp, a->nname); + write_log (_T("Resolving softlink '%s'\n"), tmp); if (!my_resolvesoftlink (tmp, sizeof tmp / sizeof (TCHAR))) { PUT_PCK_RES1 (packet, DOS_FALSE); // not sure what to return PUT_PCK_RES2 (packet, ERROR_OBJECT_NOT_AROUND); return; } - // TODO: - // now we have full absolute path, need to check if it can - // mapped to any Amiga side filesystem - // not that trivial.. - a = NULL; + write_log (_T("-> '%s'\n"), tmp); + matched_aino = NULL; + matched_unit = NULL; err = 0; + matched_len = 0; for (u = units; u; u = u->next) { if (!(u->volflags & (MYVOLUMEINFO_ARCHIVE | MYVOLUMEINFO_CDFS))) { TCHAR path[MAX_DPATH]; - if (my_issamevolume (u->rootnode.nname, tmp, path)) { + i = my_issamevolume (u->rootnode.nname, tmp, path); + if (i > matched_len) { a = find_aino (u, 0, path, &err); - if (a && !err) - break; + if (a && !err) { + write_log (_T("Match found from '%s' (%d)\n"), u->rootnode.aname, i); + matched_aino = a; + matched_unit = u; + matched_len = i; + } } } } - if (!a || err) { + if (!matched_aino) { + write_log (_T("Path not found in any mounted drive\n")); PUT_PCK_RES1 (packet, DOS_FALSE); PUT_PCK_RES2 (packet, ERROR_OBJECT_NOT_AROUND); return; } tmp[0] = 0; - action_read_link_add_parent (u, a, tmp); + action_read_link_add_parent (matched_unit, matched_aino, tmp); if (extrapath) { _tcscat (tmp, _T("/")); _tcscat (tmp, extrapath); } xfree (extrapath); + write_log (_T("got target '%s'\n"), tmp); char *s = ua_fs (tmp, -1); for (i = 0; s[i]; i++) { if (i >= size - 1) @@ -3348,7 +3388,7 @@ static void action_free_lock (Unit *unit, dpacket packet) TRACE((_T("ACTION_FREE_LOCK(0x%lx)\n"), lock)); DUMPLOCK(unit, lock); - a = lookup_aino (unit, get_long (lock + 4)); + a = aino_from_lock (unit, lock); if (a == 0) { PUT_PCK_RES1 (packet, DOS_FALSE); PUT_PCK_RES2 (packet, ERROR_OBJECT_NOT_AROUND); @@ -3597,7 +3637,7 @@ int get_native_path (uae_u32 lock, TCHAR *out) int i = 0; for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) { if (mountinfo.ui[i].self) { - a_inode *a = lookup_aino (mountinfo.ui[i].self, get_long ((lock << 2) + 4)); + a_inode *a = aino_from_lock (mountinfo.ui[i].self, lock << 2); if (a) { _tcscpy (out, a->nname); return 0; @@ -3945,7 +3985,7 @@ static int action_examine_all_do (Unit *unit, uaecptr lock, ExAllKey *eak, uaecp TCHAR fn[MAX_DPATH]; if (lock != 0) - base = lookup_aino (unit, get_long (lock + 4)); + base = aino_from_lock (unit, lock); if (base == 0) base = &unit->rootnode; for (;;) { @@ -4077,7 +4117,7 @@ static int action_examine_all (Unit *unit, dpacket packet) if (!eak) goto fail; if (lock != 0) - base = lookup_aino (unit, get_long (lock + 4)); + base = aino_from_lock (unit, lock); if (base == 0) base = &unit->rootnode; #if EXALL_DEBUG > 0 @@ -4185,7 +4225,7 @@ static void action_examine_object (Unit *unit, dpacket packet) DUMPLOCK(unit, lock); if (lock != 0) - aino = lookup_aino (unit, get_long (lock + 4)); + aino = aino_from_lock (unit, lock); if (aino == 0) aino = &unit->rootnode; @@ -4280,7 +4320,7 @@ static void action_examine_next (Unit *unit, dpacket packet) DUMPLOCK(unit, lock); if (lock != 0) - aino = lookup_aino (unit, get_long (lock + 4)); + aino = aino_from_lock (unit, lock); if (aino == 0) aino = &unit->rootnode; for(;;) { @@ -4476,7 +4516,7 @@ static void return; } - aino = lookup_aino (unit, get_long (lock + 4)); + aino = aino_from_lock (unit, lock); if (aino == 0) aino = &unit->rootnode; if (aino->softlink) { @@ -4828,6 +4868,11 @@ static void PUT_PCK_RES2 (packet, err); return; } + if (a->softlink) { + PUT_PCK_RES1 (packet, DOS_FALSE); + PUT_PCK_RES2 (packet, ERROR_IS_SOFT_LINK); + return; + } a->amigaos_mode = mask; if (!fsdb_cando (unit)) @@ -4886,6 +4931,12 @@ maybe_free_and_out: xfree (commented); return; } + if (a->softlink) { + PUT_PCK_RES1 (packet, DOS_FALSE); + PUT_PCK_RES2 (packet, ERROR_IS_SOFT_LINK); + goto maybe_free_and_out; + } + PUT_PCK_RES1 (packet, DOS_TRUE); PUT_PCK_RES2 (packet, 0); if (a->comment == 0 && commented == 0) @@ -5291,14 +5342,25 @@ static void return; } - amiga_to_timeval (&tv, get_long (date), get_long (date + 4), get_long (date + 8)); a = find_aino (unit, lock, bstr (unit, name), &err); + if (err != 0) { + PUT_PCK_RES1 (packet, DOS_FALSE); + PUT_PCK_RES2 (packet, err); + return; + } + if (a->softlink) { + PUT_PCK_RES1 (packet, DOS_FALSE); + PUT_PCK_RES2 (packet, ERROR_IS_SOFT_LINK); + return; + } + amiga_to_timeval (&tv, get_long (date), get_long (date + 4), get_long (date + 8)); write_log (_T("%llu.%u (%d,%d,%d) %s\n"), tv.tv_sec, tv.tv_usec, get_long (date), get_long (date + 4), get_long (date + 8), a->nname); - if (err == 0 && !my_utime (a->nname, &tv)) + if (!my_utime (a->nname, &tv)) err = dos_errno (); if (err != 0) { PUT_PCK_RES1 (packet, DOS_FALSE); PUT_PCK_RES2 (packet, err); + return; } else { notify_check (unit, a); PUT_PCK_RES1 (packet, DOS_TRUE); @@ -5858,9 +5920,8 @@ static int handle_packet (Unit *unit, dpacket pck, uae_u32 msg) case ACTION_LOCK_RECORD: return action_lock_record (unit, pck, msg); break; case ACTION_FREE_RECORD: action_free_record (unit, pck); break; case ACTION_READ_LINK: action_read_link (unit, pck); break; -#if 0 case ACTION_MAKE_LINK: action_make_link (unit, pck); break; -#endif + /* OS4+ packet types */ case ACTION_CHANGE_FILE_POSITION64: action_change_file_position64 (unit, pck); break; case ACTION_GET_FILE_POSITION64: action_get_file_position64 (unit, pck); break; @@ -5869,7 +5930,6 @@ static int handle_packet (Unit *unit, dpacket pck, uae_u32 msg) /* unsupported packets */ case ACTION_FORMAT: - case ACTION_MAKE_LINK: write_log (_T("FILESYS: UNSUPPORTED PACKET %x\n"), type); return 0; default: diff --git a/hardfile.cpp b/hardfile.cpp index 67624712..60b68dc3 100644 --- a/hardfile.cpp +++ b/hardfile.cpp @@ -1153,8 +1153,9 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua if (!len) len = 256; len *= hfd->ci.blocksize; - if (checkbounds(hfd, offset, len)) - scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len); + if (!checkbounds(hfd, offset, len)) + goto outofbounds; + scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len); break; case 0x0a: /* WRITE (6) */ if (nodisk (hfd)) @@ -1167,8 +1168,9 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua if (!len) len = 256; len *= hfd->ci.blocksize; - if (checkbounds(hfd, offset, len)) - scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len); + if (!checkbounds(hfd, offset, len)) + goto outofbounds; + scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len); break; case 0x12: /* INQUIRY */ { @@ -1346,8 +1348,9 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua offset *= hfd->ci.blocksize; len = rl (cmdbuf + 7 - 2) & 0xffff; len *= hfd->ci.blocksize; - if (checkbounds (hfd, offset, len)) - scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len); + if (!checkbounds (hfd, offset, len)) + goto outofbounds; + scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len); break; case 0x2a: /* WRITE (10) */ if (nodisk (hfd)) @@ -1358,8 +1361,9 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua offset *= hfd->ci.blocksize; len = rl (cmdbuf + 7 - 2) & 0xffff; len *= hfd->ci.blocksize; - if (checkbounds (hfd, offset, len)) - scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len); + if (!checkbounds (hfd, offset, len)) + goto outofbounds; + scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len); break; #if 0 case 0x2f: /* VERIFY */ @@ -1399,8 +1403,9 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua offset *= hfd->ci.blocksize; len = rl (cmdbuf + 6); len *= hfd->ci.blocksize; - if (checkbounds(hfd, offset, len)) - scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len); + if (!checkbounds(hfd, offset, len)) + goto outofbounds; + scsi_len = (uae_u32)cmd_readx (hfd, scsi_data, offset, len); break; case 0xaa: /* WRITE (12) */ if (nodisk (hfd)) @@ -1411,8 +1416,9 @@ int scsi_hd_emulate (struct hardfiledata *hfd, struct hd_hardfiledata *hdhfd, ua offset *= hfd->ci.blocksize; len = rl (cmdbuf + 6); len *= hfd->ci.blocksize; - if (checkbounds(hfd, offset, len)) - scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len); + if (!checkbounds(hfd, offset, len)) + goto outofbounds; + scsi_len = (uae_u32)cmd_writex (hfd, scsi_data, offset, len); break; case 0x37: /* READ DEFECT DATA */ if (nodisk (hfd)) @@ -1452,6 +1458,14 @@ errreq: s[12] = 0x24; /* ILLEGAL FIELD IN CDB */ ls = 0x12; break; +outofbounds: + lr = -1; + status = 2; /* CHECK CONDITION */ + s[0] = 0x70; + s[2] = 5; /* ILLEGAL REQUEST */ + s[12] = 0x21; /* LOGICAL BLOCK OUT OF RANGE */ + ls = 0x12; + break; miscompare: lr = -1; status = 2; /* CHECK CONDITION */ diff --git a/include/custom.h b/include/custom.h index e6bb817c..27b5f876 100644 --- a/include/custom.h +++ b/include/custom.h @@ -103,10 +103,13 @@ extern uae_u16 INTREQR (void); #define MAXHPOS_PAL 227 #define MAXHPOS_NTSC 227 +// short field maxvpos #define MAXVPOS_PAL 312 #define MAXVPOS_NTSC 262 +// following endlines = first visible line #define VBLANK_ENDLINE_PAL 26 #define VBLANK_ENDLINE_NTSC 21 +// line when sprite DMA fetches first control words #define VBLANK_SPRITE_PAL 25 #define VBLANK_SPRITE_NTSC 20 #define VBLANK_HZ_PAL 50 diff --git a/include/drawing.h b/include/drawing.h index 94575316..86147878 100644 --- a/include/drawing.h +++ b/include/drawing.h @@ -18,7 +18,7 @@ #endif #define AMIGA_WIDTH_MAX (752 / 2) -#define AMIGA_HEIGHT_MAX (574 / 2) +#define AMIGA_HEIGHT_MAX (576 / 2) //#define NEWHSYNC diff --git a/include/fsdb.h b/include/fsdb.h index 0e75ea09..4ada269c 100644 --- a/include/fsdb.h +++ b/include/fsdb.h @@ -82,7 +82,7 @@ typedef struct a_inode_struct { int shlock; long db_offset; unsigned int dir:1; - unsigned int softlink:1; + unsigned int softlink:2; unsigned int elock:1; /* Nonzero if this came from an entry in our database. */ unsigned int has_dbentry:1; @@ -161,8 +161,11 @@ extern bool my_chmod (const TCHAR *name, uae_u32 mode); extern bool my_resolveshortcut(TCHAR *linkfile, int size); extern bool my_resolvessymboliclink(TCHAR *linkfile, int size); extern bool my_resolvesoftlink(TCHAR *linkfile, int size); -extern bool my_issamevolume(const TCHAR *path1, const TCHAR *path2, TCHAR *path); +extern void my_canonicalize_path(const TCHAR *path, TCHAR *out, int size); +extern int my_issamevolume(const TCHAR *path1, const TCHAR *path2, TCHAR *path); extern bool my_createsoftlink(const TCHAR *path, const TCHAR *target); +extern bool my_createshortcut(const TCHAR *source, const TCHAR *target, const TCHAR *description); + extern char *custom_fsdb_search_dir (const char *dirname, TCHAR *rel); extern a_inode *custom_fsdb_lookup_aino_aname (a_inode *base, const TCHAR *aname); diff --git a/include/inputdevice.h b/include/inputdevice.h index 9ff2dd87..8f34daa7 100644 --- a/include/inputdevice.h +++ b/include/inputdevice.h @@ -211,7 +211,7 @@ extern void inputdevice_testrecord (int type, int num, int wtype, int wnum, int extern int inputdevice_get_compatibility_input (struct uae_prefs*, int, int*, int**, int**); extern struct inputevent *inputdevice_get_eventinfo (int evt); extern bool inputdevice_get_eventname (const struct inputevent *ie, TCHAR *out); -extern void inputdevice_compa_prepare_custom (struct uae_prefs *prefs, int index, int mode); +extern void inputdevice_compa_prepare_custom (struct uae_prefs *prefs, int index, int mode, bool removeold); extern void inputdevice_compa_clear (struct uae_prefs *prefs, int index); extern int intputdevice_compa_get_eventtype (int evt, int **axistable); extern void inputdevice_sparecopy (struct uae_input_device *uid, int num, int sub); diff --git a/include/options.h b/include/options.h index 87980e59..dfd7035c 100644 --- a/include/options.h +++ b/include/options.h @@ -217,6 +217,8 @@ struct apmode // -1 = wait for flip, before frame ends // 1 = wait for flip, after new frame has started int gfx_vflip; + // doubleframemode strobo + bool gfx_strobo; int gfx_vsyncmode; int gfx_backbuffers; bool gfx_interlaced; diff --git a/include/xwin.h b/include/xwin.h index 6364a928..a5ff47ee 100644 --- a/include/xwin.h +++ b/include/xwin.h @@ -45,7 +45,7 @@ extern void flush_block (struct vidbuffer*, int, int); extern void flush_screen (struct vidbuffer*, int, int); extern void flush_clear_screen (struct vidbuffer*); extern bool render_screen (bool); -extern void show_screen (void); +extern void show_screen (int); extern bool show_screen_maybe (bool); extern int lockscr (struct vidbuffer*, bool); diff --git a/inputdevice.cpp b/inputdevice.cpp index a073cbd2..c0a2b2ba 100644 --- a/inputdevice.cpp +++ b/inputdevice.cpp @@ -3368,7 +3368,6 @@ void inputdevice_reset (void) if (inputdevice_is_tablet ()) mousehack_enable (); bouncy = 0; - potgo_value = 0; } static int getoldport (struct uae_input_device *id) @@ -4491,7 +4490,7 @@ static void remove_custom_config (struct uae_prefs *prefs, bool nocustom, int in } // prepare port for custom mapping, remove all current Amiga side device mappings -void inputdevice_compa_prepare_custom (struct uae_prefs *prefs, int index, int newmode) +void inputdevice_compa_prepare_custom (struct uae_prefs *prefs, int index, int newmode, bool removeold) { int mode = prefs->jports[index].mode; freejport (prefs, index); @@ -4502,10 +4501,12 @@ void inputdevice_compa_prepare_custom (struct uae_prefs *prefs, int index, int n mode = index == 0 ? JSEM_MODE_WHEELMOUSE : (prefs->cs_cd32cd ? JSEM_MODE_JOYSTICK_CD32 : JSEM_MODE_JOYSTICK); } prefs->jports[index].mode = mode; - prefs->jports[index].id = -2; + prefs->jports[index].id = JPORT_CUSTOM; - remove_compa_config (prefs, index); - remove_custom_config (prefs, false, index); + if (removeold) { + remove_compa_config (prefs, index); + remove_custom_config (prefs, false, index); + } } // clear device before switching to new one void inputdevice_compa_clear (struct uae_prefs *prefs, int index) @@ -6334,8 +6335,8 @@ void inputdevice_testrecord (int type, int num, int wtype, int wnum, int state, if (testmode_count >= TESTMODE_MAX) return; if (type == IDTYPE_KEYBOARD) { - if (wnum == 0x100) { - wnum = -1; + if (wnum >= 0x100) { + wnum = 0x100 - wnum; } else { struct uae_input_device *na = &keyboards[num]; int j = 0; diff --git a/main.cpp b/main.cpp index 81dc58f9..0a32f126 100644 --- a/main.cpp +++ b/main.cpp @@ -173,11 +173,15 @@ void fixup_prefs_dimensions (struct uae_prefs *prefs) ap->gfx_vflip = 1; if (!i && ap->gfx_backbuffers == 2) ap->gfx_vflip = 1; + if (ap->gfx_vflip) + ap->gfx_strobo = true; } else { // legacy vsync: always wait for flip ap->gfx_vflip = -1; if (prefs->gfx_api && ap->gfx_backbuffers < 1) ap->gfx_backbuffers = 1; + if (ap->gfx_vflip) + ap->gfx_strobo = true; } } else { // no vsync: wait if triple bufferirng diff --git a/od-win32/avioutput.cpp b/od-win32/avioutput.cpp index d7dde9be..7551b62a 100644 --- a/od-win32/avioutput.cpp +++ b/od-win32/avioutput.cpp @@ -372,13 +372,14 @@ static int AVIOutput_GetAudioFromRegistry (WAVEFORMATEX *wft) return 0; getsettings (avikey); if (wft) { + ok = -1; ss = wfxMaxFmtSize; if (regquerydata (avikey, _T("AudioConfigurationVars"), wft, &ss)) { if (AVIOutput_ValidateAudio (wft, NULL, 0)) ok = 1; } } - if (!ok) + if (ok < 0) regdelete (avikey, _T("AudioConfigurationVars")); regclosetree (avikey); return ok; @@ -546,6 +547,7 @@ static int AVIOutput_GetCOMPVARSFromRegistry (COMPVARS *pcv) return 0; getsettings (avikey); if (pcv) { + ok = -1; ss = pcv->cbSize; pcv->hic = 0; if (regquerydata (avikey, _T("VideoConfigurationVars"), pcv, &ss)) { @@ -569,7 +571,7 @@ static int AVIOutput_GetCOMPVARSFromRegistry (COMPVARS *pcv) } } } - if (!ok) { + if (ok < 0) { regdelete (avikey, _T("VideoConfigurationVars")); regdelete (avikey, _T("VideoConfigurationState")); } diff --git a/od-win32/blkdev_win32_ioctl.cpp b/od-win32/blkdev_win32_ioctl.cpp index 8effa6dc..817b1082 100644 --- a/od-win32/blkdev_win32_ioctl.cpp +++ b/od-win32/blkdev_win32_ioctl.cpp @@ -697,7 +697,8 @@ static int ioctl_command_pause (int unitnum, int paused) if (!ciw) return -1; int old = ciw->cdda_paused; - ciw->cdda_paused = paused; + if ((paused && ciw->cdda_play) || !paused) + ciw->cdda_paused = paused; return old; } diff --git a/od-win32/dinput.cpp b/od-win32/dinput.cpp index 88cca154..ec16b9b2 100644 --- a/od-win32/dinput.cpp +++ b/od-win32/dinput.cpp @@ -2207,13 +2207,11 @@ static void handle_rawinput_2 (RAWINPUT *raw) } rawkeystate[scancode] = pressed; if (istest) { - if (pressed && (scancode == DIK_F12 || scancode == DIK_F11)) + if (pressed && (scancode == DIK_F12)) return; - if (scancode == DIK_F12) - scancode = -1; - if (scancode == DIK_F11) { - inputdevice_testrecord (IDTYPE_KEYBOARD, num, IDEV_WIDGET_BUTTON, 0x100, 1, -1); - inputdevice_testrecord (IDTYPE_KEYBOARD, num, IDEV_WIDGET_BUTTON, 0x100, 0, -1); + if (scancode == DIK_F12) { + inputdevice_testrecord (IDTYPE_KEYBOARD, num, IDEV_WIDGET_BUTTON, 0x101, 1, -1); + inputdevice_testrecord (IDTYPE_KEYBOARD, num, IDEV_WIDGET_BUTTON, 0x101, 0, -1); } else { inputdevice_testrecord (IDTYPE_KEYBOARD, num, IDEV_WIDGET_BUTTON, scancode, pressed, -1); } @@ -3232,13 +3230,11 @@ static void read_kb (void) continue; di_keycodes[i][scancode] = pressed; if (istest) { - if (pressed && (scancode == DIK_F12 || scancode == DIK_F11)) + if (pressed && (scancode == DIK_F12)) return; - if (scancode == DIK_F12) - scancode = -1; - if (scancode == DIK_F11) { - inputdevice_testrecord (IDTYPE_KEYBOARD, i, IDEV_WIDGET_BUTTON, 0x100, 1, -1); - inputdevice_testrecord (IDTYPE_KEYBOARD, i, IDEV_WIDGET_BUTTON, 0x100, 0, -1); + if (scancode == DIK_F12) { + inputdevice_testrecord (IDTYPE_KEYBOARD, i, IDEV_WIDGET_BUTTON, 0x101, 1, -1); + inputdevice_testrecord (IDTYPE_KEYBOARD, i, IDEV_WIDGET_BUTTON, 0x101, 0, -1); } else { inputdevice_testrecord (IDTYPE_KEYBOARD, i, IDEV_WIDGET_BUTTON, scancode, pressed, -1); } diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index a090a3f1..ffb90c53 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -2267,10 +2267,12 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int depth, int mmult) dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; getvsyncrate (dpp.FullScreen_RefreshRateInHz, &hzmult); if (hzmult < 0) { - if (d3dCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO) - dpp.PresentationInterval = D3DPRESENT_INTERVAL_TWO; - else + if (!ap->gfx_strobo) { + if (d3dCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO) + dpp.PresentationInterval = D3DPRESENT_INTERVAL_TWO; + } else { vsync2 = -1; + } } else if (hzmult > 0) { vsync2 = 1; } @@ -2281,11 +2283,13 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int depth, int mmult) getvsyncrate (dpp.FullScreen_RefreshRateInHz, &hzmult); if (hzmult > 0) { vsync2 = 1; - } else if (hzmult < 0 && ap->gfx_vflip) { - if (d3dCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO) - dpp.PresentationInterval = D3DPRESENT_INTERVAL_TWO; - else - vsync2 = -1; + } else if (hzmult < 0) { + if (ap->gfx_vflip && !ap->gfx_strobo) { + if (d3dCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO) + dpp.PresentationInterval = D3DPRESENT_INTERVAL_TWO; + else + vsync2 = -1; + } } } @@ -2464,7 +2468,7 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int depth, int mmult) if (forcedframelatency >= 0) hr = d3ddevex->SetMaximumFrameLatency (forcedframelatency); else if (v > 1 || !vsync) - hr = d3ddevex->SetMaximumFrameLatency (vsync ? 1 : 0); + hr = d3ddevex->SetMaximumFrameLatency (vsync ? (hzmult < 0 ? 2 : 1) : 0); if (FAILED (hr)) write_log (_T("%s: SetMaximumFrameLatency() failed: %s\n"), D3DHEAD, D3D_ErrorString (hr)); } @@ -3137,6 +3141,17 @@ void D3D_showframe (void) flushgpu (true); } +void D3D_showframe_special (int mode) +{ + HRESULT hr; + if (!isd3d ()) + return; + if (currprefs.turbo_emulation) + return; + hr = d3ddev->Clear (0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, d3ddebug ? 0x80 : 0, 0), 0, 0); + D3D_showframe2 (true); +} + void D3D_refresh (void) { if (!isd3d ()) diff --git a/od-win32/direct3d.h b/od-win32/direct3d.h index 1f480863..7dfbd448 100644 --- a/od-win32/direct3d.h +++ b/od-win32/direct3d.h @@ -6,6 +6,7 @@ extern void D3D_getpixelformat (int depth,int *rb, int *bb, int *gb, int *rs, in extern void D3D_refresh (void); extern bool D3D_renderframe (bool); extern void D3D_showframe (void); +extern void D3D_showframe_special (int); extern uae_u8 *D3D_locktexture(int*, bool); extern void D3D_unlocktexture(void); extern void D3D_flushtexture (int miny, int maxy); diff --git a/od-win32/fsdb_mywin32.cpp b/od-win32/fsdb_mywin32.cpp index d99b58dc..3946b32e 100644 --- a/od-win32/fsdb_mywin32.cpp +++ b/od-win32/fsdb_mywin32.cpp @@ -764,42 +764,56 @@ bool my_utime (const TCHAR *name, struct mytimeval *tv) bool my_createsoftlink(const TCHAR *path, const TCHAR *target) { - return CreateSymbolicLink(path, target, my_existsdir(target) ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) != 0; + return CreateSymbolicLink(path, target, my_existsdir (target) ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) != 0; } -bool my_issamevolume(const TCHAR *path1, const TCHAR *path2, TCHAR *path) +void my_canonicalize_path(const TCHAR *path, TCHAR *out, int size) +{ + TCHAR tmp[MAX_DPATH]; + int v; + v = GetLongPathName (path, tmp, sizeof tmp / sizeof (TCHAR)); + if (!v || v > sizeof tmp / sizeof (TCHAR)) { + _tcsncpy (out, path, size); + out[size - 1] = 0; + return; + } + PathCanonicalize(out, tmp); +} + +int my_issamevolume(const TCHAR *path1, const TCHAR *path2, TCHAR *path) { TCHAR p1[MAX_DPATH]; TCHAR p2[MAX_DPATH]; - TCHAR p1b[MAX_DPATH]; - TCHAR p2b[MAX_DPATH]; - int len; - - if (!GetFullPathName(path1, sizeof p1 / sizeof (TCHAR), p1, NULL)) - return false; - if (!GetFullPathName(path2, sizeof p2 / sizeof (TCHAR), p2, NULL)) - return false; - PathCanonicalize(p1b, p1); - PathCanonicalize(p2b, p2); - len = _tcslen (p1b); - if (len > _tcslen (p2b)) - len = _tcslen (p2b); - if (_tcsnicmp (p1b, p2b, len)) - return false; - _tcscpy (path, p2b + len); + int len, cnt; + + my_canonicalize_path(path1, p1, sizeof p1 / sizeof (TCHAR)); + my_canonicalize_path(path2, p2, sizeof p2 / sizeof (TCHAR)); + len = _tcslen (p1); + if (len > _tcslen (p2)) + len = _tcslen (p2); + if (_tcsnicmp (p1, p2, len)) + return 0; + _tcscpy (path, p2 + len); + cnt = 0; for (int i = 0; i < _tcslen (path); i++) { - if (path[i] == '\\') + if (path[i] == '\\' || path[i] == '/') { path[i] = '/'; + cnt++; + } } - return true; + write_log (_T("'%s' (%s) matched with '%s' (%s), extra = '%s'\n"), path1, p1, path2, p2, path); + return cnt; } bool my_resolvesoftlink(TCHAR *linkfile, int size) { + TCHAR tmp[MAX_DPATH]; if (my_resolvessymboliclink(linkfile, size)) return true; if (my_resolveshortcut(linkfile,size)) return true; + _tcscpy (tmp, linkfile); + my_canonicalize_path (tmp, linkfile, size); return false; } @@ -836,6 +850,7 @@ bool my_resolvessymboliclink(TCHAR *linkfile, int size) bool ret = false; DWORD returnedDataSize; uae_u8 tmp[MAX_DPATH * 2]; + TCHAR tmp2[MAX_DPATH]; h = FindFirstFile (linkfile, &fd); if (h == INVALID_HANDLE_VALUE) @@ -850,23 +865,25 @@ bool my_resolvessymboliclink(TCHAR *linkfile, int size) if (DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, tmp, sizeof tmp, &returnedDataSize, NULL)) { REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER*)tmp; if (rdb->SymbolicLinkReparseBuffer.Flags & 1) { // SYMLINK_FLAG_RELATIVE - PathRemoveFileSpec (linkfile); - _tcscat (linkfile, _T("\\")); - TCHAR *p = linkfile + _tcslen (linkfile); + _tcscpy (tmp2, linkfile); + PathRemoveFileSpec (tmp2); + _tcscat (tmp2, _T("\\")); + TCHAR *p = tmp2 + _tcslen (tmp2); memcpy (p, (uae_u8*)rdb->SymbolicLinkReparseBuffer.PathBuffer + rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset, rdb->SymbolicLinkReparseBuffer.SubstituteNameLength); p[rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / 2] = 0; } else { - memcpy (linkfile, + memcpy (tmp2, (uae_u8*)rdb->SymbolicLinkReparseBuffer.PathBuffer + rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset, rdb->SymbolicLinkReparseBuffer.SubstituteNameLength); - linkfile[rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / 2] = 0; + tmp2[rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / 2] = 0; } ret = true; - if (!_tcsnicmp (linkfile, _T("\\??\\"), 4)) { - memmove (linkfile, linkfile + 4, (_tcslen (linkfile + 4) + 1) * sizeof (TCHAR)); + if (!_tcsnicmp (tmp2, _T("\\??\\"), 4)) { + memmove (tmp2, tmp2 + 4, (_tcslen (tmp2 + 4) + 1) * sizeof (TCHAR)); } + my_canonicalize_path (tmp2, linkfile, size); } CloseHandle(h); return ret; @@ -921,8 +938,7 @@ bool my_resolveshortcut(TCHAR *linkfile, int size) if (SUCCEEDED(hres)) { - _tcsncpy (linkfile, szGotPath, size); - linkfile[size - 1] = 0; + my_canonicalize_path (szGotPath, linkfile, size); ok = SUCCEEDED(hres); } } @@ -938,3 +954,40 @@ bool my_resolveshortcut(TCHAR *linkfile, int size) } return ok; } + +// http://msdn.microsoft.com/en-us/library/aa969393.aspx +bool my_createshortcut(const TCHAR *source, const TCHAR *target, const TCHAR *description) +{ + HRESULT hres; + IShellLink* psl; + TCHAR tmp[MAX_DPATH]; + + // Get a pointer to the IShellLink interface. It is assumed that CoInitialize + // has already been called. + hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); + if (SUCCEEDED(hres)) + { + IPersistFile* ppf; + + // Set the path to the shortcut target and add the description. + psl->SetPath(target); + psl->SetDescription(description); + + // Query IShellLink for the IPersistFile interface, used for saving the + // shortcut in persistent storage. + hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf); + + if (SUCCEEDED(hres)) + { + // Save the link by calling IPersistFile::Save. + _tcscpy (tmp, source); + const TCHAR *ext = _tcsrchr (tmp, '.'); + if (!ext || _tcsicmp (ext, _T(".lnk")) != 0) + _tcscat (tmp, _T(".lnk")); + hres = ppf->Save(tmp, TRUE); + ppf->Release(); + } + psl->Release(); + } + return SUCCEEDED(hres); +} diff --git a/od-win32/fsdb_win32.cpp b/od-win32/fsdb_win32.cpp index 635fe4c6..b6857e45 100644 --- a/od-win32/fsdb_win32.cpp +++ b/od-win32/fsdb_win32.cpp @@ -363,7 +363,7 @@ int fsdb_name_invalid_dir (const TCHAR *n) return v; } -uae_u32 filesys_parse_mask(uae_u32 mask) +uae_u32 filesys_parse_mask (uae_u32 mask) { return mask ^ 0xf; } @@ -394,11 +394,22 @@ int fsdb_fill_file_attrs (a_inode *base, a_inode *aino) if (h != INVALID_HANDLE_VALUE) { FindClose(h); if (fd.dwReserved0 == IO_REPARSE_TAG_SYMLINK && (fd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { - aino->softlink = true; + aino->softlink = 1; } } } + if (!aino->softlink && !aino->dir) { + const TCHAR *ext = _tcsrchr (aino->nname, '.'); + if (ext && !_tcsicmp (ext, _T(".lnk"))) { + TCHAR tmp[MAX_DPATH]; + _tcscpy (tmp, aino->nname); + if (my_resolvesoftlink (tmp, sizeof tmp / sizeof (TCHAR))) { + aino->softlink = 2; + } + } + } + mode &= FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; if ((base->volflags & MYVOLUMEINFO_STREAMS) && read_uaefsdb (aino->nname, NULL, fsdb)) { @@ -432,17 +443,6 @@ int fsdb_fill_file_attrs (a_inode *base, a_inode *aino) write_uaefsdb (aino->nname, fsdb); } - if (!aino->softlink && !aino->dir) { - const TCHAR *ext = _tcsrchr (aino->nname, '.'); - if (ext && !_tcsicmp (ext, _T(".lnk"))) { - TCHAR tmp[MAX_DPATH]; - _tcscpy (tmp, aino->nname); - if (my_resolvesoftlink (tmp, sizeof tmp / sizeof (TCHAR))) { - aino->softlink = true; - } - } - } - return 1; } diff --git a/od-win32/resources/resource.h b/od-win32/resources/resource.h index 712d48f8..a94600a7 100644 --- a/od-win32/resources/resource.h +++ b/od-win32/resources/resource.h @@ -655,14 +655,10 @@ #define IDC_PORT0_TEST 1510 #define IDC_SCREENRESTEXT 1511 #define IDC_MAPDRIVES_AUTO 1511 -#define IDC_PORT0_TEST2 1511 -#define IDC_PORT1_TEST 1511 #define IDC_WIDTHTEXT 1512 #define IDC_WINDOWEDTEXT 1512 -#define IDC_PORT2_TEST 1512 #define IDC_MAPDRIVES_LIMIT 1512 #define IDC_HEIGHTTEXT 1513 -#define IDC_PORT3_TEST 1513 #define IDC_SETTINGSTEXT 1514 #define IDC_REFRESHTEXT 1515 #define IDC_SETTINGSTEXT2 1515 @@ -1124,6 +1120,12 @@ #define IDC_CS_IDE4 1816 #define IDC_CS_DF0IDHW 1817 #define IDC_FILTERSTACK 1818 +#define IDC_INPUTMAP_CAPTURE 1819 +#define IDC_INPUTMAP_CUSTOM 1820 +#define IDC_INPUTMAP_DELETE 1821 +#define IDC_INPUTMAP_TEST 1822 +#define IDC_INPUTMAP_DELETEALL 1823 +#define IDC_INPUTMAP_EXIT 1824 #define ID__FLOPPYDRIVES 40004 #define ID_FLOPPYDRIVES_DF0 40005 #define ID_ST_CONFIGURATION 40010 @@ -1174,7 +1176,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 388 #define _APS_NEXT_COMMAND_VALUE 40050 -#define _APS_NEXT_CONTROL_VALUE 1819 +#define _APS_NEXT_CONTROL_VALUE 1820 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/od-win32/resources/winuae.rc b/od-win32/resources/winuae.rc index 53361a72..a4441f7b 100644 --- a/od-win32/resources/winuae.rc +++ b/od-win32/resources/winuae.rc @@ -438,22 +438,18 @@ BEGIN COMBOBOX IDC_PORT0_JOYS,45,19,342,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_PORT0_AF,45,37,86,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_PORT0_JOYSMODE,136,38,106,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Test [] Test Port 1 (mouse) configuration.",IDC_PORT0_TEST,313,37,36,14 PUSHBUTTON "Remap [] Remap Port 1 configurarion.",IDC_PORT0_REMAP,352,37,36,14 RTEXT "Port 2:",IDC_STATIC,6,56,35,15,SS_CENTERIMAGE COMBOBOX IDC_PORT1_JOYS,45,57,342,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_PORT1_AF,45,74,86,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_PORT1_JOYSMODE,136,74,106,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Test [] Test Port 2 (joystick) configuration.",IDC_PORT1_TEST,313,74,36,14 PUSHBUTTON "Remap [] Remap Port 2 configuration.",IDC_PORT1_REMAP,352,74,36,14 PUSHBUTTON "Swap ports [] Swap ports 1 and 2.",IDC_SWAP,45,100,78,14 LTEXT "Emulated parallel port joystick adapter",IDC_STATIC,10,124,179,15,SS_CENTERIMAGE RTEXT "X-Arcade layout information []#1",IDC_STATIC,217,124,170,15,SS_NOTIFY | SS_CENTERIMAGE COMBOBOX IDC_PORT2_JOYS,45,142,342,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Test [] Test Parallel port joystick port 1 configuration.",IDC_PORT2_TEST,313,159,36,14 PUSHBUTTON "Remap [] Remap Parallel port joystick port 1 configurarion.",IDC_PORT2_REMAP,352,159,36,14 COMBOBOX IDC_PORT3_JOYS,45,178,342,130,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Test [] Test Parallel port joystick 2 configuration.",IDC_PORT3_TEST,313,194,36,14 PUSHBUTTON "Remap [] Remap Parallel port joystick port 2 configurarion.",IDC_PORT3_REMAP,352,194,36,14 GROUPBOX "Mouse extra settings",IDC_STATIC,1,219,393,68 RTEXT "Mouse speed:",IDC_STATIC,19,237,82,10,SS_CENTERIMAGE @@ -1077,13 +1073,21 @@ BEGIN CONTROL "Always center",IDC_RTG_CENTER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,93,212,10 END -IDD_INPUTMAP DIALOGEX 0, 0, 396, 318 -STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD -FONT 8, "MS Sans Serif", 0, 0, 0x1 +IDD_INPUTMAP DIALOGEX 0, 0, 420, 318 +STYLE DS_LOCALEDIT | DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Input Remap" +FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN - CONTROL "",IDC_INPUTMAPLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,1,1,393,268 - EDITTEXT IDC_INPUTMAPOUT,1,272,393,14,ES_AUTOHSCROLL | ES_READONLY | WS_DISABLED - EDITTEXT IDC_INPUTMAPOUTM,1,288,393,29,ES_MULTILINE | ES_READONLY | WS_DISABLED + DEFPUSHBUTTON "OK",IDOK,147,51,58,14,NOT WS_VISIBLE + CONTROL "",IDC_INPUTMAPLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOCOLUMNHEADER | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,1,1,418,248 + EDITTEXT IDC_INPUTMAPOUT,1,253,418,14,ES_AUTOHSCROLL | ES_READONLY | WS_DISABLED + EDITTEXT IDC_INPUTMAPOUTM,1,269,418,29,ES_MULTILINE | ES_READONLY | WS_DISABLED + PUSHBUTTON "Remap",IDC_INPUTMAP_CAPTURE,72,300,66,14 + PUSHBUTTON "Add special",IDC_INPUTMAP_CUSTOM,142,300,66,14 + PUSHBUTTON "Delete",IDC_INPUTMAP_DELETE,212,300,66,14 + PUSHBUTTON "Delete all",IDC_INPUTMAP_DELETEALL,282,300,66,14 + PUSHBUTTON "Test",IDC_INPUTMAP_TEST,2,300,66,14 + PUSHBUTTON "Exit",IDC_INPUTMAP_EXIT,351,300,66,14 END IDD_INFOBOX DIALOGEX 0, 0, 420, 68 @@ -1562,7 +1566,7 @@ BEGIN IDS_QS_CD "CD" IDS_QS_CD_AUTO "Autodetect" IDS_QS_CD_IMAGE "Image mode" - IDS_REMAPTITLE "Input captured. F12 = Exit. F11 = Skip current event in Remap mode." + IDS_REMAPTITLE "Input captured. F12 = Exit." IDS_FILTER_NOOVERLAYS "No overlays available" IDS_STMENUNOCD "No CD inserted" IDS_ON "on" diff --git a/od-win32/rp.cpp b/od-win32/rp.cpp index f3c3672e..a2e29808 100644 --- a/od-win32/rp.cpp +++ b/od-win32/rp.cpp @@ -283,7 +283,7 @@ int port_insert_custom (int inputmap_port, int devicetype, DWORD flags, const TC kb = inputdevice_get_device_total (IDTYPE_JOYSTICK) + inputdevice_get_device_total (IDTYPE_MOUSE); inputdevice_copyconfig (&currprefs, &changed_prefs); - inputdevice_compa_prepare_custom (&changed_prefs, inputmap_port, devicetype); + inputdevice_compa_prepare_custom (&changed_prefs, inputmap_port, devicetype, true); inputdevice_updateconfig (NULL, &changed_prefs); max = inputdevice_get_compatibility_input (&changed_prefs, inputmap_port, &mode, &events, &axistable); write_log (_T("custom='%s' max=%d port=%d dt=%d kb=%d kbnum=%d\n"), custom, max, inputmap_port, devicetype, kb, inputdevice_get_device_total (IDTYPE_KEYBOARD)); diff --git a/od-win32/srcrelease.cmd b/od-win32/srcrelease.cmd index 140058ea..7eff6cb7 100644 --- a/od-win32/srcrelease.cmd +++ b/od-win32/srcrelease.cmd @@ -124,6 +124,7 @@ cd winuae_msvc11 rm -rf debug rm -rf release rm -rf fullrelease +rm -rf test cd .. cd singlefilehelper diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index 67d13cd1..161f10d0 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -5281,6 +5281,40 @@ static TCHAR **WIN32_InitRegistry (TCHAR **argv) return NULL; } +static const TCHAR *pipename = _T("\\\\.\\pipe\\WinUAE"); + +static bool singleprocess (void) +{ + DWORD mode, ret, avail; + bool ok = false; + TCHAR buf[1000]; + + HANDLE p = CreateFile( + pipename, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + 0, + NULL); + if (p == INVALID_HANDLE_VALUE) + return false; + mode = PIPE_READMODE_MESSAGE; + if (!SetNamedPipeHandleState(p, &mode, NULL, NULL)) + goto end; + buf[0] = 0xfeff; + _tcscpy (buf + 1, _T("IPC_QUIT")); + if (!WriteFile(p, (void*)buf, (_tcslen (buf) + 1) * sizeof (TCHAR), &ret, NULL)) + goto end; + if (!PeekNamedPipe(p, NULL, 0, NULL, &avail, NULL)) + goto end; + if (!ReadFile(p, buf, sizeof buf, &ret, NULL)) + goto end; + ok = true; +end: + CloseHandle(p); + return ok; +} static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) { @@ -5296,6 +5330,7 @@ static int PASCAL WinMain2 (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR hInst = hInstance; hMutex = CreateMutex (NULL, FALSE, _T("WinUAE Instantiated")); // To tell the installer we're running + //singleprocess (); argv = xcalloc (TCHAR*, MAX_ARGUMENTS); argv3 = NULL; diff --git a/od-win32/win32.h b/od-win32/win32.h index ef3f1342..3077391e 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -19,11 +19,11 @@ #define LANG_DLL 1 #if WINUAEPUBLICBETA -#define WINUAEBETA _T("9") +#define WINUAEBETA _T("10") #else #define WINUAEBETA _T("") #endif -#define WINUAEDATE MAKEBD(2013, 2, 24) +#define WINUAEDATE MAKEBD(2013, 3, 9) #define WINUAEEXTRA _T("") //#define WINUAEEXTRA _T("AmiKit Preview") #define WINUAEREV _T("") diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index 314f6a3a..532b3dbb 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -988,15 +988,23 @@ void flush_screen (struct vidbuffer *vb, int a, int b) { } -static volatile bool render_ok; +static volatile bool render_ok, wait_render; bool render_screen (bool immediate) { bool v = false; + int cnt; render_ok = false; if (minimized || picasso_on || monitor_off || dx_islost ()) return render_ok; + cnt = 0; + while (wait_render) { + sleep_millis(1); + cnt++; + if (cnt > 500) + return render_ok; + } flushymin = 0; flushymax = currentmode->amiga_height; EnterCriticalSection (&screen_cs); @@ -1020,12 +1028,12 @@ static void waitflipevent (void) break; } } -static void doflipevent (void) +static void doflipevent (int mode) { if (flipevent == NULL) return; waitflipevent (); - flipevent_mode = 1; + flipevent_mode = mode; SetEvent (flipevent); } @@ -1034,7 +1042,7 @@ bool show_screen_maybe (bool show) struct apmode *ap = picasso_on ? &currprefs.gfx_apmode[1] : &currprefs.gfx_apmode[0]; if (!ap->gfx_vflip || ap->gfx_vsyncmode == 0 || !ap->gfx_vsync) { if (show) - show_screen (); + show_screen (0); return false; } #if 0 @@ -1046,7 +1054,16 @@ bool show_screen_maybe (bool show) return false; } -void show_screen (void) +void show_screen_special (void) +{ + EnterCriticalSection (&screen_cs); + if (currentmode->flags & DM_D3D) { + D3D_showframe_special (1); + } + LeaveCriticalSection (&screen_cs); +} + +void show_screen (int mode) { EnterCriticalSection (&screen_cs); if (!render_ok) { @@ -2746,7 +2763,7 @@ end: return 1; } -static volatile frame_time_t vblank_prev_time, thread_vblank_time; +static volatile frame_time_t vblank_prev_time, vblank_real_prev_time, thread_vblank_time; static volatile int vblank_found_flipdelay; #include @@ -2916,13 +2933,19 @@ static unsigned int __stdcall flipthread (void *dummy) if (flipthread_mode == 0) break; frame_time_t t = read_processor_time (); - while (!render_ok) { + while ((flipevent_mode & 1) && !render_ok) { sleep_millis (1); if (read_processor_time () - t > vblankbasefull) break; } - show_screen (); - render_ok = false; + if (flipevent_mode & 1) { + show_screen (0); + render_ok = false; + } + if (flipevent_mode & 2) { + show_screen_special (); + wait_render = false; + } flipevent_mode = 0; SetEvent (flipevent2); } @@ -3076,7 +3099,7 @@ static unsigned int __stdcall vblankthread (void *dummy) vblankthread_oddeven = (vp & 1) != 0; } if (!doflipped && ap->gfx_vflip > 0) { - doflipevent (); + doflipevent (1 | 2); doflipped = true; } ok = vblank_getstate (&vb, &vp); @@ -3088,7 +3111,7 @@ static unsigned int __stdcall vblankthread (void *dummy) if (read_processor_time () - t > vblankbasefull) break; } - show_screen (); + show_screen (0); render_ok = false; int delay = read_processor_time () - t; if (delay < 0) @@ -3117,7 +3140,7 @@ static unsigned int __stdcall vblankthread (void *dummy) } if (end) { if (ap->gfx_vflip > 0 && !doflipped) { - doflipevent (); + doflipevent (1); doflipped = true; } thread_vblank_time = thread_vblank_time2; @@ -3173,7 +3196,7 @@ frame_time_t vsync_busywait_end (int *flipdelay) if (flipdelay) *flipdelay = vblank_found_flipdelay; } else { - show_screen (); + show_screen (0); prev = read_processor_time (); } changevblankthreadmode_fast (VBLANKTH_ACTIVE_WAIT); @@ -3285,7 +3308,7 @@ int vsync_busywait_do (int *freetime, bool lace, bool oddeven) if (currprefs.turbo_emulation) { - show_screen (); + show_screen (0); dooddevenskip = 0; vblank_prev_time = read_processor_time (); framelost = true; @@ -3306,10 +3329,20 @@ int vsync_busywait_do (int *freetime, bool lace, bool oddeven) dooddevenskip = 1; } - if (ap->gfx_vflip != 0) { - show_screen (); + if (ap->gfx_vflip == 0 && vblank_skipeveryother) { + // make sure that we really did skip one field + while (!framelost && read_processor_time () - vblank_real_prev_time < vblankbasewait1) { + vsync_sleep (false); + } } + if (ap->gfx_vflip != 0) { + show_screen (0); + if (ap->gfx_strobo && vblank_skipeveryother) { + wait_render = true; + doflipevent (2); + } + } while (!framelost && read_processor_time () - prevtime < vblankbasewait1) { vsync_sleep (false); } @@ -3331,9 +3364,9 @@ int vsync_busywait_do (int *freetime, bool lace, bool oddeven) } if (vp >= -1) { - vblank_prev_time = read_processor_time (); + vblank_real_prev_time = vblank_prev_time = read_processor_time (); if (ap->gfx_vflip == 0) { - show_screen (); + show_screen (0); vblank_flip_delay = (read_processor_time () - vblank_prev_time) / (vblank_skipeveryother ? 2 : 1); if (vblank_flip_delay < 0) vblank_flip_delay = 0; @@ -3518,12 +3551,12 @@ double vblank_calibrate (double approx_vblank, bool waitonly) int detectcnt = 6; for (cnt = 0; cnt < detectcnt; cnt++) { render_screen (true); - show_screen (); + show_screen (0); sleep_millis (1); frame_time_t t = read_processor_time () + 1 * (syncbase / tsum); for (int cnt2 = 0; cnt2 < 4; cnt2++) { render_ok = true; - show_screen (); + show_screen (0); } int diff = (int)read_processor_time () - (int)t; if (diff >= 0) diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index f5760367..fbdcb691 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -171,8 +171,9 @@ static int C_PAGES; #define MAX_C_PAGES 30 static int LOADSAVE_ID = -1, MEMORY_ID = -1, KICKSTART_ID = -1, CPU_ID = -1, DISPLAY_ID = -1, HW3D_ID = -1, CHIPSET_ID = -1, CHIPSET2_ID = -1, SOUND_ID = -1, FLOPPY_ID = -1, DISK_ID = -1, - HARDDISK_ID = -1, IOPORTS_ID = -1, GAMEPORTS_ID = -1, INPUT_ID = -1, INPUTMAP_ID = -1, MISC1_ID = -1, MISC2_ID = -1, + HARDDISK_ID = -1, IOPORTS_ID = -1, GAMEPORTS_ID = -1, INPUT_ID = -1, MISC1_ID = -1, MISC2_ID = -1, AVIOUTPUT_ID = -1, PATHS_ID = -1, QUICKSTART_ID = -1, ABOUT_ID = -1, EXPANSION_ID = -1, FRONTEND_ID = -1; +static const int INPUTMAP_ID = MAX_C_PAGES - 1; static HWND pages[MAX_C_PAGES]; #define MAX_IMAGETOOLTIPS 10 static HWND guiDlg, panelDlg, ToolTipHWND; @@ -3447,7 +3448,7 @@ static void update_listview_input (HWND hDlg) static int inputmap_port = -1, inputmap_port_remap = -1; static int inputmap_groupindex[32]; -static int inputmap_handle (HWND list, int currentdevnum, int currentwidgetnum, int *inputmap_portp, int *inputmap_indexp, int state, int *inputmap_itemindexp) +static int inputmap_handle (HWND list, int currentdevnum, int currentwidgetnum, int *inputmap_portp, int *inputmap_indexp, int state, int *inputmap_itemindexp, int deleteindex) { int cntitem, cntgroup, portnum; int mode, *events, *axistable; @@ -3485,7 +3486,8 @@ static int inputmap_handle (HWND list, int currentdevnum, int currentwidgetnum, lvstruct.iSubItem = 0; lvstruct.iGroupId = cntgroup; if (inputmap_itemindexp) - inputmap_itemindexp[cntgroup] = -1; + inputmap_itemindexp[cntgroup - 1] = -1; + inputmap_itemindexp[cntgroup + 1 - 1] = -1; } atpidx = 0; @@ -3511,6 +3513,11 @@ static int inputmap_handle (HWND list, int currentdevnum, int currentwidgetnum, if (inputdevice_get_mapping (devnum, j, &flags, &port, NULL, NULL, sub) == evtnum) { if (!port) continue; + if (cntitem - 1 == deleteindex) { + inputdevice_set_mapping (devnum, j, NULL, NULL, 0, 0, sub); + deleteindex = -1; + continue; + } inputdevice_get_widget_type (devnum, j, name); if (list) { TCHAR target[MAX_DPATH]; @@ -3547,6 +3554,7 @@ static int inputmap_handle (HWND list, int currentdevnum, int currentwidgetnum, if (list) { lvstruct.pszText = _T(""); lvstruct.iItem = cntgroup * 256 + cntitem; + lvstruct.lParam = cntgroup; item = ListView_InsertItem (list, &lvstruct); if (inputmap_itemindexp && inputmap_itemindexp[cntgroup - 1] < 0) inputmap_itemindexp[cntgroup - 1] = item; @@ -3563,13 +3571,13 @@ static int inputmap_handle (HWND list, int currentdevnum, int currentwidgetnum, return 1; return 0; } -static void update_listview_inputmap (HWND hDlg) +static void update_listview_inputmap (HWND hDlg, int deleteindex) { HWND list = GetDlgItem (hDlg, IDC_INPUTMAPLIST); ListView_EnableGroupView (list, TRUE); - inputmap_handle (list, -1, -1, NULL, NULL, 0, inputmap_groupindex); + inputmap_handle (list, -1, -1, NULL, NULL, 0, inputmap_groupindex, deleteindex); } static int clicked_entry = -1; @@ -3792,7 +3800,7 @@ void InitializeListView (HWND hDlg) } else if (lv_type == LV_INPUTMAP) { listview_column_width[0] = 400; - update_listview_inputmap (hDlg); + update_listview_inputmap (hDlg, -1); } else if (lv_type == LV_MISC1) { @@ -4052,7 +4060,8 @@ void InitializeListView (HWND hDlg) } // Adjust our column widths so that we can see the contents... for(i = 0; i < listview_num_columns; i++) { - if (ListView_GetColumnWidth (list, i) < listview_column_width[i]) + int w = ListView_GetColumnWidth (list, i); + if (w < listview_column_width[i]) ListView_SetColumnWidth (list, i, listview_column_width[i]); } // Redraw the items in the list... @@ -4558,7 +4567,7 @@ static INT_PTR CALLBACK LoadSaveDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPA { case NM_DBLCLK: { - HTREEITEM ht = TreeView_GetSelection (GetDlgItem(hDlg, IDC_CONFIGTREE)); + HTREEITEM ht = TreeView_GetSelection (GetDlgItem (hDlg, IDC_CONFIGTREE)); if (ht != NULL) { TVITEMEX pitem; memset (&pitem, 0, sizeof (pitem)); @@ -11995,20 +12004,20 @@ static INT_PTR CALLBACK GamePortsDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP updatejoyport (hDlg); } else if (LOWORD (wParam) == IDC_PORT0_REMAP) { ports_remap (hDlg, 0); + enable_for_gameportsdlg (hDlg); + updatejoyport (hDlg); } else if (LOWORD (wParam) == IDC_PORT1_REMAP) { ports_remap (hDlg, 1); + enable_for_gameportsdlg (hDlg); + updatejoyport (hDlg); } else if (LOWORD (wParam) == IDC_PORT2_REMAP) { ports_remap (hDlg, 2); + enable_for_gameportsdlg (hDlg); + updatejoyport (hDlg); } else if (LOWORD (wParam) == IDC_PORT3_REMAP) { ports_remap (hDlg, 3); - } else if (LOWORD (wParam) == IDC_PORT0_TEST) { - input_test (hDlg, 0); - } else if (LOWORD (wParam) == IDC_PORT1_TEST) { - input_test (hDlg, 1); - } else if (LOWORD (wParam) == IDC_PORT2_TEST) { - input_test (hDlg, 2); - } else if (LOWORD (wParam) == IDC_PORT3_TEST) { - input_test (hDlg, 3); + enable_for_gameportsdlg (hDlg); + updatejoyport (hDlg); } else if (HIWORD (wParam) == CBN_SELCHANGE) { switch (LOWORD (wParam)) { @@ -12517,68 +12526,84 @@ static void showextramap (HWND hDlg) SetWindowText (GetDlgItem (hDlg, IDC_INPUTMAPOUTM), out); } -static void input_find (HWND hDlg, int mode, int set); +static void input_find (HWND hDlg, HWND mainDlg, int mode, int set, bool oneshot); static int rawmode; static int inputmap_remap_counter, inputmap_view_offset; +static int inputmap_mode_cnt; +static bool inputmap_oneshot; + +#define INPUTMAP_F12 -1 + +#if 0 +static void inputmap_next (HWND hDlg) +{ + HWND h = GetDlgItem (hDlg, IDC_INPUTMAPLIST); + int inputmap = 1; + if (inputmap == 1) { + int mode, *events, *axistable; + int max = inputdevice_get_compatibility_input (&workprefs, inputmap_port, &mode, &events, &axistable); + inputmap_remap_counter++; + if (inputmap_remap_counter >= max) + inputmap_remap_counter = 0; + int inputmap_index = inputmap_groupindex[inputmap_remap_counter]; + ListView_EnsureVisible (h, inputmap_index, FALSE); + ListView_SetItemState (h, -1, 0, LVIS_SELECTED | LVIS_FOCUSED); + ListView_SetItemState (h, inputmap_index, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); + } else if (inputmap == 2) { + int itemcnt = ListView_GetItemCount (h); + if (inputmap_view_offset >= itemcnt - 1 || inputmap_view_offset < 0) { + inputmap_view_offset = 0; + } else { + inputmap_view_offset += ListView_GetCountPerPage (h); + if (inputmap_view_offset >= itemcnt) + inputmap_view_offset = itemcnt - 1; + } + ListView_EnsureVisible (h, inputmap_view_offset, FALSE); + } +} +#endif static void CALLBACK timerfunc (HWND hDlg, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { - if (idEvent != 1) - return; int inputmap; WINDOWINFO pwi; - pwi.cbSize = sizeof pwi; - if (GetWindowInfo (guiDlg, &pwi)) { - // GUI inactive = disable capturing - if (pwi.dwWindowStatus != WS_ACTIVECAPTION) { - input_find (hDlg, 0, false); - return; - } - } - if (currentpage == INPUTMAP_ID) { + HWND myDlg; + + if (idEvent != 1) + return; + + if (pages[INPUTMAP_ID]) { inputmap = inputmap_remap_counter >= 0 ? 1 : 2; setfocus (hDlg, IDC_INPUTMAPLIST); + myDlg = hDlg; } else { inputmap = 0; setfocus (hDlg, IDC_INPUTLIST); + myDlg = guiDlg; + } + + pwi.cbSize = sizeof pwi; + if (GetWindowInfo (myDlg, &pwi)) { + // GUI inactive = disable capturing + if (pwi.dwWindowStatus != WS_ACTIVECAPTION) { + input_find (hDlg, myDlg, 0, false, false); + return; + } } + int inputmap_index; int devnum, wtype, state; int cnt = inputdevice_testread_count (); if (cnt < 0) { - input_find (hDlg, 0, FALSE); + input_find (hDlg, myDlg, 0, FALSE, false); return; } if (!cnt) return; int ret = inputdevice_testread (&devnum, &wtype, &state, true); if (ret > 0) { - if (wtype < 0) { - if (!state) - return; - HWND h = GetDlgItem (hDlg, IDC_INPUTMAPLIST); - // F11 - if (inputmap == 1) { - int mode, *events, *axistable; - int max = inputdevice_get_compatibility_input (&workprefs, inputmap_port, &mode, &events, &axistable); - inputmap_remap_counter++; - if (inputmap_remap_counter >= max) - inputmap_remap_counter = 0; - inputmap_index = inputmap_groupindex[inputmap_remap_counter]; - ListView_EnsureVisible (h, inputmap_index, FALSE); - ListView_SetItemState (h, -1, 0, LVIS_SELECTED | LVIS_FOCUSED); - ListView_SetItemState (h, inputmap_index, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); - } else if (inputmap == 2) { - int itemcnt = ListView_GetItemCount (h); - if (inputmap_view_offset >= itemcnt - 1 || inputmap_view_offset < 0) { - inputmap_view_offset = 0; - } else { - inputmap_view_offset += ListView_GetCountPerPage (h); - if (inputmap_view_offset >= itemcnt) - inputmap_view_offset = itemcnt - 1; - } - ListView_EnsureVisible (h, inputmap_view_offset, FALSE); - } + if (wtype == INPUTMAP_F12) { + input_find (hDlg, myDlg, 0, FALSE, false); return; } if (input_selected_widget != devnum || input_selected_widget != wtype) { @@ -12612,7 +12637,7 @@ static void CALLBACK timerfunc (HWND hDlg, UINT uMsg, UINT_PTR idEvent, DWORD dw wcnt++; for (;;) { ret = inputdevice_testread (&devnum, &wtype, &state, false); - if (ret <= 0) + if (ret <= 0 || wtype == -2) break; if (devnum != input_selected_device) continue; @@ -12687,8 +12712,10 @@ static void CALLBACK timerfunc (HWND hDlg, UINT uMsg, UINT_PTR idEvent, DWORD dw inputdevice_set_gameports_mapping (&workprefs, input_selected_device, input_selected_widget, evtnum, 0, inputmap_port); InitializeListView (hDlg); inputmap_remap_counter++; - if (inputmap_remap_counter >= max) - inputmap_remap_counter = 0; + if (inputmap_remap_counter >= max || inputmap_oneshot) { + input_find (hDlg, myDlg, 0, FALSE, false); + return; + } inputmap_index = inputmap_groupindex[inputmap_remap_counter]; ListView_EnsureVisible (h, inputmap_index, FALSE); @@ -12726,7 +12753,7 @@ static void CALLBACK timerfunc (HWND hDlg, UINT uMsg, UINT_PTR idEvent, DWORD dw bool found = false; HWND h = GetDlgItem (hDlg, IDC_INPUTMAPLIST); int op = inputmap_port; - if (inputmap_handle (NULL, input_selected_device, input_selected_widget, &op, &inputmap_index, state, NULL)) { + if (inputmap_handle (NULL, input_selected_device, input_selected_widget, &op, &inputmap_index, state, NULL, -1)) { if (op == inputmap_port) { ListView_EnsureVisible (h, 1, FALSE); ListView_EnsureVisible (h, inputmap_index, FALSE); @@ -12776,7 +12803,7 @@ static void CALLBACK timerfunc (HWND hDlg, UINT uMsg, UINT_PTR idEvent, DWORD dw ListView_SetItemState (GetDlgItem (hDlg, IDC_INPUTLIST), -1, 0, LVIS_SELECTED | LVIS_FOCUSED); ListView_SetItemState (GetDlgItem (hDlg, IDC_INPUTLIST), input_selected_widget, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); if (rawmode == 1) { - input_find (hDlg, 0, FALSE); + input_find (hDlg, myDlg, 0, FALSE, false); if (IsWindowEnabled (GetDlgItem (hDlg, IDC_INPUTAMIGA))) { setfocus (hDlg, IDC_INPUTAMIGA); SendDlgItemMessage (hDlg, IDC_INPUTAMIGA, CB_SHOWDROPDOWN , TRUE, 0L); @@ -12795,35 +12822,44 @@ static int rawdisable[] = { IDC_INPUTCOPY, 0, 0, IDC_INPUTCOPYFROM, 0, 0, IDC_INPUTSWAP, 0, 0, IDC_INPUTDEADZONE, 0, 0, IDC_INPUTSPEEDD, 0, 0, IDC_INPUTAUTOFIRERATE, 0, 0, IDC_INPUTSPEEDA, 0, 0, IDC_PANELTREE, 1, 0, IDC_RESETAMIGA, 1, 0, IDC_QUITEMU, 1, 0, IDC_RESTARTEMU, 1, 0, IDOK, 1, 0, IDCANCEL, 1, 0, IDHELP, 1, 0, + IDC_INPUTMAP_DELETE, 0, 0, IDC_INPUTMAP_CAPTURE, 0, 0, IDC_INPUTMAP_CUSTOM, 0, 0, + IDC_INPUTMAP_TEST, 0, 0, IDC_INPUTMAP_DELETEALL, 0, 0, IDC_INPUTMAP_EXIT, 0, 0, -1 }; +static void inputmap_disable (HWND hDlg, bool disable) +{ + for (int i = 0; rawdisable[i] >= 0; i += 3) { + HWND w = GetDlgItem (rawdisable[i + 1] ? guiDlg : hDlg, rawdisable[i]); + if (w) { + if (disable) { + rawdisable[i + 2] = IsWindowEnabled (w); + EnableWindow (w, FALSE); + } else { + EnableWindow (w, rawdisable[i + 2]); + } + } + } +} -static void input_find (HWND hDlg, int mode, int set) +static void input_find (HWND hDlg, HWND mainDlg, int mode, int set, bool oneshot) { static TCHAR tmp[200]; if (set && !rawmode) { rawmode = mode ? 2 : 1; + inputmap_oneshot = oneshot; + inputmap_disable (hDlg, true); inputdevice_settest (TRUE); inputdevice_acquire (-1); - if (rawmode == 2) { - TCHAR tmp2[MAX_DPATH]; - GetWindowText (guiDlg, tmp, sizeof tmp / sizeof (TCHAR)); - WIN32GUI_LoadUIString (IDS_REMAPTITLE, tmp2, sizeof tmp2 / sizeof (TCHAR)); - SetWindowText (guiDlg, tmp2); - } + TCHAR tmp2[MAX_DPATH]; + GetWindowText (guiDlg, tmp, sizeof tmp / sizeof (TCHAR)); + WIN32GUI_LoadUIString (IDS_REMAPTITLE, tmp2, sizeof tmp2 / sizeof (TCHAR)); + SetWindowText (mainDlg, tmp2); SetTimer (hDlg, 1, 30, timerfunc); - for (int i = 0; rawdisable[i] >= 0; i += 3) { - HWND w = GetDlgItem (rawdisable[i + 1] ? guiDlg : hDlg, rawdisable[i]); - if (w) { - rawdisable[i + 2] = IsWindowEnabled (w); - EnableWindow (w, FALSE); - } - } ShowCursor (FALSE); - SetCapture (guiDlg); + SetCapture (mainDlg); RECT r; - GetWindowRect (guiDlg, &r); + GetWindowRect (mainDlg, &r); ClipCursor (&r); } else if (rawmode) { KillTimer (hDlg, 1); @@ -12832,38 +12868,16 @@ static void input_find (HWND hDlg, int mode, int set) ShowCursor (TRUE); wait_keyrelease (); inputdevice_unacquire (); - for (int i = 0; rawdisable[i] >= 0; i += 3) { - HWND w = GetDlgItem (rawdisable[i + 1] ? guiDlg : hDlg, rawdisable[i]); - if (w) - EnableWindow (w, rawdisable[i + 2]); - } + inputmap_disable (hDlg, false); inputdevice_settest (FALSE); - if (rawmode == 2) { - SetWindowText (guiDlg, tmp); - SetFocus (hDlg); - } + SetWindowText (mainDlg, tmp); + SetFocus (hDlg); rawmode = FALSE; - if (currentpage == INPUTMAP_ID) - updatePanel (GAMEPORTS_ID); + SetWindowText (GetDlgItem (hDlg, IDC_INPUTMAPOUT), _T("")); + SetWindowText (GetDlgItem (hDlg, IDC_INPUTMAPOUTM), _T("")); } } -static void ports_remap (HWND hDlg, int port) -{ - inputmap_port_remap = port; - inputmap_port = port; - inputmap_remap_counter = 0; - updatePanel (INPUTMAP_ID); -} -static void input_test (HWND hDlg, int port) -{ - inputmap_port_remap = -1; - inputmap_port = port; - inputmap_remap_counter = -1; - inputmap_view_offset = 0; - updatePanel (INPUTMAP_ID); -} - #if 0 static void input_test (HWND hDlg, int port) { @@ -12939,105 +12953,173 @@ static void handleXbutton (WPARAM wParam, int updown) setmousebuttonstate (dinput_winmouse (), num, updown); } +static void handlerawinput (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (msg == WM_INPUT) { + handle_rawinput (lParam); + DefWindowProc (hDlg, msg, wParam, lParam); + } +} + +static int getremapcounter(int item) +{ + for (int i = 0; inputmap_groupindex[i] >= 0; i++) { + if (item < inputmap_groupindex[i + 1] || inputmap_groupindex[i + 1] < 0) + return i; + } + return 0; +} + static INT_PTR CALLBACK InputMapDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { static int recursive; + static int inputmap_selected; + HWND h = GetDlgItem (hDlg, IDC_INPUTMAPLIST); switch (msg) { + case WM_CLOSE: + DestroyWindow (hDlg); + return TRUE; case WM_INITDIALOG: { + inputmap_port_remap = -1; + inputmap_remap_counter = -1; + inputmap_view_offset = 0; pages[INPUTMAP_ID] = hDlg; - currentpage = INPUTMAP_ID; inputdevice_updateconfig (NULL, &workprefs); - if (inputmap_remap_counter == 0) { - inputdevice_compa_prepare_custom (&workprefs, inputmap_port, -1); - inputdevice_updateconfig (NULL, &workprefs); - } InitializeListView (hDlg); - HWND h = GetDlgItem (hDlg, IDC_INPUTMAPLIST); - if (inputmap_remap_counter == 0) { - ListView_EnsureVisible (h, inputmap_remap_counter, FALSE); - ListView_SetItemState (h, -1, 0, LVIS_SELECTED | LVIS_FOCUSED); - ListView_SetItemState (h, inputmap_remap_counter, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); + if (workprefs.jports[inputmap_port].id != JPORT_CUSTOM) { + ew (hDlg, IDC_INPUTMAP_CAPTURE, FALSE); + ew (hDlg, IDC_INPUTMAP_DELETE, FALSE); + ew (hDlg, IDC_INPUTMAP_CUSTOM, FALSE); } - input_find (hDlg, 1, true); - } - case WM_USER: - recursive++; - recursive--; - return TRUE; - case WM_DESTROY: - input_find (hDlg, 0, false); - break; -#if 0 - case WM_MOUSEMOVE: - { - int wm = dinput_winmouse (); - int mx = (signed short) LOWORD (lParam); - int my = (signed short) HIWORD (lParam); - setmousestate (dinput_winmouse (), 0, mx, 0); - setmousestate (dinput_winmouse (), 1, my, 0); break; } - case WM_LBUTTONUP: - setmousebuttonstate (dinput_winmouse (), 0, 0); - return 0; - case WM_LBUTTONDOWN: - case WM_LBUTTONDBLCLK: - setmousebuttonstate (dinput_winmouse (), 0, 1); - return 0; - case WM_RBUTTONUP: - setmousebuttonstate (dinput_winmouse (), 1, 0); - return 0; - case WM_RBUTTONDOWN: - case WM_RBUTTONDBLCLK: - setmousebuttonstate (dinput_winmouse (), 1, 1); - return 0; - case WM_MBUTTONUP: - setmousebuttonstate (dinput_winmouse (), 2, 0); - return 0; - case WM_MBUTTONDOWN: - case WM_MBUTTONDBLCLK: - setmousebuttonstate (dinput_winmouse (), 2, 1); - return 0; - case WM_XBUTTONUP: - handleXbutton (wParam, 0); - return TRUE; - case WM_XBUTTONDOWN: - case WM_XBUTTONDBLCLK: - handleXbutton (wParam, 1); + case WM_DESTROY: + input_find (hDlg, hDlg, 0, false, false); + pages[INPUTMAP_ID] = NULL; + inputmap_port_remap = -1; + inputmap_remap_counter = -1; + inputmap_view_offset = 0; + PostQuitMessage (0); return TRUE; - case WM_MOUSEWHEEL: - { - int val = ((short)HIWORD (wParam)); - setmousestate (dinput_winmouse (), 2, val, 0); - if (val < 0) - setmousebuttonstate (dinput_winmouse (), dinput_wheelbuttonstart () + 0, -1); - else if (val > 0) - setmousebuttonstate (dinput_winmouse (), dinput_wheelbuttonstart () + 1, -1); - return TRUE; + break; + case WM_NOTIFY: + if (((LPNMHDR) lParam)->idFrom == IDC_INPUTMAPLIST) { + NM_LISTVIEW *lv = (NM_LISTVIEW*)lParam; + switch (lv->hdr.code) + { + case NM_DBLCLK: + if (lv->iItem >= 0) { + inputmap_selected = lv->iItem; + inputmap_remap_counter = getremapcounter (lv->iItem); + if (workprefs.jports[inputmap_port].id == JPORT_CUSTOM) { + input_find (hDlg, hDlg, 1, true, true); + } + } + return TRUE; + + case NM_CLICK: + if (lv->iItem >= 0) { + inputmap_selected = lv->iItem; + inputmap_remap_counter = getremapcounter (lv->iItem); + } + return TRUE; + } } - case WM_MOUSEHWHEEL: + break; + case WM_COMMAND: + { + if (recursive) + break; + recursive++; + switch(wParam) { - int val = ((short)HIWORD (wParam)); - setmousestate (dinput_winmouse (), 3, val, 0); - if (val < 0) - setmousebuttonstate (dinput_winmouse (), dinput_wheelbuttonstart () + 2, -1); - else if (val > 0) - setmousebuttonstate (dinput_winmouse (), dinput_wheelbuttonstart () + 3, -1); - return TRUE; + case IDCANCEL: + case IDOK: + case IDC_INPUTMAP_EXIT: + pages[INPUTMAP_ID] = NULL; + DestroyWindow (hDlg); + //EndDialog (hDlg, 0); + break; + case IDC_INPUTMAP_TEST: + inputmap_port_remap = -1; + inputmap_remap_counter = -1; + inputmap_view_offset = 0; + input_find (hDlg, hDlg, 0, true, false); + break; + case IDC_INPUTMAP_CAPTURE: + if (inputmap_remap_counter < 0) + inputmap_remap_counter = 0; + inputmap_port_remap = inputmap_port; + if (workprefs.jports[inputmap_port].id != JPORT_CUSTOM) { + inputdevice_compa_prepare_custom (&workprefs, inputmap_port, -1, false); + inputdevice_updateconfig (NULL, &workprefs); + InitializeListView (hDlg); + } + ListView_EnsureVisible (h, inputmap_remap_counter, FALSE); + ListView_SetItemState (h, -1, 0, LVIS_SELECTED | LVIS_FOCUSED); + ListView_SetItemState (h, inputmap_remap_counter, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); + input_find (hDlg, hDlg, 1, true, false); + break; + case IDC_INPUTMAP_CUSTOM: + break; + case IDC_INPUTMAP_DELETE: + if (workprefs.jports[inputmap_port].id == JPORT_CUSTOM) { + update_listview_inputmap (hDlg, inputmap_selected); + InitializeListView (hDlg); + } + break; + case IDC_INPUTMAP_DELETEALL: + inputmap_remap_counter = 0; + inputmap_port_remap = inputmap_port; + inputdevice_compa_prepare_custom (&workprefs, inputmap_port, -1, true); + inputdevice_updateconfig (NULL, &workprefs); + InitializeListView (hDlg); + ListView_EnsureVisible (h, inputmap_remap_counter, FALSE); + ListView_SetItemState (h, -1, 0, LVIS_SELECTED | LVIS_FOCUSED); + ListView_SetItemState (h, inputmap_remap_counter, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); + ew (hDlg, IDC_INPUTMAP_CAPTURE, TRUE); + ew (hDlg, IDC_INPUTMAP_DELETE, TRUE); + ew (hDlg, IDC_INPUTMAP_CUSTOM, TRUE); + break; } -#endif + recursive--; + break; } - return 0; + break; + } + handlerawinput (hDlg, msg, wParam, lParam); + return FALSE; } -static void handlerawinput (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +static void ports_remap (HWND hDlg, int port) { - if (msg == WM_INPUT) { - handle_rawinput (lParam); - DefWindowProc (hDlg, msg, wParam, lParam); + inputmap_port = port; + HWND dlg = CustomCreateDialog (IDD_INPUTMAP, hDlg, InputMapDlgProc); + if (dlg == NULL) + return; + MSG msg; + for (;;) { + DWORD ret = GetMessage (&msg, dlg, 0, 0); + if (ret == -1 || ret == 0) + break; + if (rawmode) { + if (msg.message == WM_INPUT) { + handlerawinput (msg.hwnd, msg.message, msg.wParam, msg.lParam); + continue; + } + // eat all accelerators + if (msg.message == WM_KEYDOWN || msg.message == WM_MOUSEMOVE || msg.message == WM_MOUSEWHEEL + || msg.message == WM_MOUSEHWHEEL || msg.message == WM_LBUTTONDOWN) + continue; + } + // IsDialogMessage() eats WM_INPUT messages?!?! + if (!rawmode && IsDialogMessage (dlg, &msg)) + continue; + TranslateMessage (&msg); + DispatchMessage (&msg); } } @@ -13323,7 +13405,7 @@ static INT_PTR CALLBACK InputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM recursive--; return TRUE; case WM_DESTROY: - input_find (hDlg, 0, false); + input_find (hDlg, guiDlg, 0, false, false); break; case WM_COMMAND: if (recursive) @@ -13333,10 +13415,10 @@ static INT_PTR CALLBACK InputDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM { case IDC_INPUTREMAP: input_selected_event = -1; - input_find (hDlg, 0, true); + input_find (hDlg, guiDlg, 0, true, false); break; case IDC_INPUTTEST: - input_find (hDlg, 1, true); + input_find (hDlg, guiDlg, 1, true, false); break; case IDC_INPUTCOPY: input_copy (hDlg); @@ -15856,7 +15938,6 @@ static int GetSettings (int all_options, HWND hwnd) HARDDISK_ID = init_page (IDD_HARDDISK, IDI_HARDDISK, IDS_HARDDISK, HarddiskDlgProc, HarddiskAccel, _T("gui/hard-drives.htm"), 0); #endif GAMEPORTS_ID = init_page (IDD_GAMEPORTS, IDI_GAMEPORTS, IDS_GAMEPORTS, GamePortsDlgProc, NULL, _T("gui/gameports.htm"), 0); - INPUTMAP_ID = init_page (IDD_INPUTMAP, IDI_GAMEPORTS, IDS_GAMEPORTS, InputMapDlgProc, NULL, NULL, IDC_INPUTMAPLIST); IOPORTS_ID = init_page (IDD_IOPORTS, IDI_PORTS, IDS_IOPORTS, IOPortsDlgProc, NULL, _T("gui/ioports.htm"), 0); INPUT_ID = init_page (IDD_INPUT, IDI_INPUT, IDS_INPUT, InputDlgProc, NULL, _T("gui/input.htm"), IDC_INPUTLIST); MISC1_ID = init_page (IDD_MISC1, IDI_MISC1, IDS_MISC1, MiscDlgProc1, NULL, _T("gui/misc.htm"), 0); @@ -15969,8 +16050,10 @@ static int GetSettings (int all_options, HWND hwnd) if (globalipc && IPChandle != INVALID_HANDLE_VALUE) { MsgWaitForMultipleObjects (1, &IPChandle, FALSE, INFINITE, QS_ALLINPUT); while (checkIPC (globalipc, &workprefs)); + if (quit_program == -UAE_QUIT) + break; } else { - WaitMessage(); + WaitMessage (); } dialogmousemove (dhwnd); diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index f196405b..a8a892cb 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,6 +1,35 @@ - restore only single input target to default. +Beta 10: + +- SCSI CD MODE SENSE emulation fixes. +- SCSI CD Write commands should return unknown command error, it is not a CD writer. +- SCSI CD and HD: return correct sense code if Read or Write command tries to access out of bounds LBAs. +- SCSI/ATAPI CD: return medium changed unit attention sense data after media change. +- OCS and ECS Denise/AGA have slightly different behavior when program writes to BPL1DAT to enable sprites + before DDFSTRT (sort of AGA bordersprite option), OCS: only works if hpos is large enough (~40+), ECS: + smaller limit (or no limit, didn't test). +- Soft link emulation improved. +- Directory filesystem ACTION_MAKE_LINK implemented, supports soft links only, creates shortcut (*.lnk) files. +- Entering GUI Harddrives panel removed image from internel CD image mounter if mounted as ATAPI or SCSI. (introduced few betas ago) +- Restructured blkdev.cpp unit handling. +- Sound autoswitching is disabled when AVI recording is active. +- Low latency vsync no buffer mode and doubled frames (100Hz+) was unstable. +- POTGO right button bit was temporarily and incorrectly active in some situations when loading state. +- D3D Low latency vsync in double and triple buffer double rate modes (100Hz+) now blank every other field to minimize "ghosting" effect. + Will be optional later. (http://www.blurbusters.com/ for more information) +- Added hack that prevents incorrectly triggering CIA alarm interrupts in non-cycle exact modes due to not that good KS timer.device + code. (It did not cause any problems, just wasted some emulated CPU time) +- Fixed memory corruption in exe to adf conversion code. (b1) +- GamePorts panel test/remap option rewritten. + - Test and Remap buttons combined. + - One or more events can be added. + - Events can be removed one by one. + - Non-key/joystick/mouse events (insert floppy, reset emulator etc..) can be added and removed. Not yet implemented. + - Doubleclick on input list will record single input event. + NOTE: Built-in (non-custom mode) events can not be edited, you need to start from scratch. (Click "Delete all") + Beta 9: - 68000 NBCD didn't emulate undocumented V-flag behavior. (Probably forgotten long time ago because SBCD had correct @@ -121,7 +150,7 @@ Beta 2: - Fixed stuck IDE emulation interrupt that hangs the emulated system, happened randomly during A4000 IDE detection. (Old bug) - Geometry file FORCELOAD parameter added, forceload=1: do not re-use already loaded filesystem(s). - A590/A2091/A3000 SCSI CDROM emulation added, uses SCSI emulation originally made for uaescsi.device. -- Gayle/A4000 ATAPI CDROM emulation added (uses uaescsi.device SCSI emulation, ATAPI = IDE CROM SCSI command support) +- Gayle/A4000 ATAPI CDROM emulation added (uses uaescsi.device SCSI emulation, ATAPI = IDE CDROM SCSI command support) - CD image mounter SCSI emulation inquiry command's vendor/product/revision data was blank. - Ultra-minimal "Add CD Drive" GUI added. Only IDE or SCSI and only one CD entry can be added. Use hardddrives panel bottom CD drive/image selection select menu to select mounted CD. uaescsi.device still works as previously but note that diff --git a/savestate.cpp b/savestate.cpp index 6736d8af..e263bfa6 100644 --- a/savestate.cpp +++ b/savestate.cpp @@ -513,7 +513,7 @@ void restore_state (const TCHAR *filename) write_log (_T("%s is not an AmigaStateFile\n"), filename); goto error; } - write_log (_T("STATERESTORE:\n")); + write_log (_T("STATERESTORE: '%s'\n"), filename); config_changed = 1; savestate_file = f; restore_header (chunk); diff --git a/scsi.cpp b/scsi.cpp index 3fe6cead..f126be2a 100644 --- a/scsi.cpp +++ b/scsi.cpp @@ -94,8 +94,9 @@ void scsi_emulate_cmd(struct scsi_data *sd) if (sd->cd_emu_unit >= 0) { if (sd->cmd[0] == 0x03) { /* REQUEST SENSE */ int len = sd->cmd[4]; - memset (sd->buffer, 0, len); - memcpy (sd->buffer, sd->sense, sd->sense_len > len ? len : sd->sense_len); + scsi_cd_emulate(sd->cd_emu_unit, sd->cmd, 0, 0, 0, 0, 0, 0, 0, sd->atapi); /* ack request sense */ + memset(sd->buffer, 0, len); + memcpy(sd->buffer, sd->sense, sd->sense_len > len ? len : sd->sense_len); sd->data_len = len; } else { sd->status = scsi_cd_emulate(sd->cd_emu_unit, sd->cmd, sd->cmd_len, sd->buffer, &sd->data_len, sd->reply, &sd->reply_len, sd->sense, &sd->sense_len, sd->atapi); @@ -109,8 +110,8 @@ void scsi_emulate_cmd(struct scsi_data *sd) } else if (sd->nativescsiunit < 0) { if (sd->cmd[0] == 0x03) { /* REQUEST SENSE */ int len = sd->cmd[4]; - memset (sd->buffer, 0, len); - memcpy (sd->buffer, sd->sense, sd->sense_len > len ? len : sd->sense_len); + memset(sd->buffer, 0, len); + memcpy(sd->buffer, sd->sense, sd->sense_len > len ? len : sd->sense_len); sd->data_len = len; } else { sd->status = scsi_hd_emulate(&sd->hfd->hfd, sd->hfd, diff --git a/uaeipc.cpp b/uaeipc.cpp index d8abe966..fca20c7c 100644 --- a/uaeipc.cpp +++ b/uaeipc.cpp @@ -10,6 +10,7 @@ #include "zfile.h" #include "inputdevice.h" #include "debug.h" +#include "uae.h" #include @@ -39,6 +40,10 @@ static void parsemessage(TCHAR *in, struct uae_prefs *p, TCHAR *out, int outsize out[0] = 0; my_trim (in); + if (!_tcsicmp (in, _T("IPC_QUIT"))) { + uae_quit (); + return; + } if (!_tcsicmp (in, _T("ipc_config"))) { ipcmode = 1; _tcscat (out, _T("200\n"));