From: Toni Wilen Date: Fri, 13 Aug 2010 13:19:24 +0000 (+0300) Subject: stuff X-Git-Tag: 2300~11 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=48b44a71ef4cb3d01a92c019b6e44a558b49f203;p=francis%2Fwinuae.git stuff --- diff --git a/akiko.cpp b/akiko.cpp index b0b26e46..294d2354 100644 --- a/akiko.cpp +++ b/akiko.cpp @@ -371,7 +371,7 @@ static uae_u32 akiko_c2p_read (int offset) #define CH_ERR_ABNORMALSEEK 0xf0 // %11110000 #define CH_ERR_NODISK 0xf8 // %11111000 -static int framecounter, subcodecounter; +static int subcodecounter; #define MAX_SUBCODEBUFFER 20 static volatile int subcodebufferoffset, subcodebufferoffsetw; @@ -399,7 +399,7 @@ static struct cd_toc_head cdrom_toc_cd_buffer; static uae_u8 qcode_buf[SUBQ_SIZE]; static int qcode_valid; -static int cdrom_disk, cdrom_paused, cdrom_playing; +static int cdrom_disk, cdrom_paused, cdrom_playing, cdrom_audiostatus; static int cdrom_command_active; static int cdrom_command_length; static int cdrom_checksum_error, cdrom_unknown_command; @@ -456,6 +456,7 @@ static void cdaudiostop_do (void) static void cdaudiostop (void) { + cdrom_audiostatus = 0; cdrom_audiotimeout = 0; cdrom_paused = 0; cdrom_playing = 0; @@ -500,6 +501,23 @@ static void subfunc (uae_u8 *data, int cnt) uae_sem_post (&sub_sem); } +static int statusfunc (int status) +{ + if (status < 0) + return 1000; + if (cdrom_audiostatus != status) { + if (status == AUDIO_STATUS_IN_PROGRESS) { + cdrom_playing = 1; + cdrom_audiotimeout = 1; + } + if (cdrom_playing && status != AUDIO_STATUS_IN_PROGRESS && status != AUDIO_STATUS_PAUSED) { + cdrom_audiotimeout = -1; + } + } + cdrom_audiostatus = status; + return 0; +} + static void cdaudioplay_do (void) { uae_u32 startlsn = read_comm_pipe_u32_blocking (&requests); @@ -509,7 +527,7 @@ static void cdaudioplay_do (void) if (unitnum < 0) return; sys_command_cd_pause (unitnum, 0); - sys_command_cd_play (unitnum, startlsn, endlsn, scan, subfunc); + sys_command_cd_play (unitnum, startlsn, endlsn, scan, statusfunc, subfunc); } static bool isaudiotrack (int startlsn) @@ -584,9 +602,7 @@ static int cd_qcode (uae_u8 *d) buf[2] = 0x80; if (!qcode_valid) return 0; - if (cdrom_playing) // fake it! - as = AUDIO_STATUS_IN_PROGRESS; - if (as != AUDIO_STATUS_IN_PROGRESS && as != AUDIO_STATUS_PAUSED && as != AUDIO_STATUS_PLAY_COMPLETE && as != AUDIO_STATUS_NO_STATUS) /* audio status ok? */ + if (cdrom_audiostatus != AUDIO_STATUS_IN_PROGRESS && cdrom_audiostatus != AUDIO_STATUS_PAUSED) return 0; s = buf + 4; last_play_pos = msf2lsn (fromlongbcd (s + 7)); @@ -878,11 +894,11 @@ static int cdrom_command_multi (void) seekpos, msf2lsn (seekpos), endpos, msf2lsn (endpos), scan); #endif cdrom_playing = 1; - cdrom_result_buffer[1] |= CDS_PLAYING; if (!cd_play_audio (seekpos, endpos, 0)) { - // play didn't start, report it in next status packet + // play didn't start, report it in next status packet cdrom_audiotimeout = -3; } + cdrom_result_buffer[1] |= CDS_PLAYING; } else { #if AKIKO_DEBUG_IO_CMD write_log (L"SEEKTO %06X\n",seekpos); @@ -895,10 +911,15 @@ static int cdrom_command_multi (void) return 2; } -static int cdrom_playend_notify (int err) +static int cdrom_playend_notify (int status) { cdrom_result_buffer[0] = 4; - cdrom_result_buffer[1] = err ? 0x80 : 0x00; + if (status < 0) + cdrom_result_buffer[1] = 0x80; // error + else if (status == 0) + cdrom_result_buffer[1] = 0x08; // play started + else + cdrom_result_buffer[1] = 0x00; // play ended return 2; } @@ -1092,6 +1113,10 @@ static void akiko_handler (void) get_cdrom_toc (); return; } + if (cdrom_audiotimeout == 1) { // play start + cdrom_start_return_data (cdrom_playend_notify (0)); + cdrom_audiotimeout = 0; + } if (cdrom_audiotimeout == -1) { // play finished (or disk end) if (cdrom_playing) { cdaudiostop (); @@ -1100,12 +1125,13 @@ static void akiko_handler (void) cdrom_audiotimeout = 0; } } - if (cdrom_audiotimeout == -2 && qcode_buf[1] != AUDIO_STATUS_IN_PROGRESS) { - cdrom_start_return_data (cdrom_playend_notify (0)); + if (cdrom_audiotimeout == -2) { // play end notification + cdrom_start_return_data (cdrom_playend_notify (1)); cdrom_audiotimeout = 0; } - if (cdrom_audiotimeout == -3) { - cdrom_start_return_data (cdrom_playend_notify (1)); + // play didn't start notification (illegal address) + if (cdrom_audiotimeout == -3) { // return error status + cdrom_start_return_data (cdrom_playend_notify (-1)); cdrom_audiotimeout = 0; } @@ -1134,6 +1160,7 @@ void AKIKO_hsync_handler (void) if (!currprefs.cs_cd32cd || !akiko_inited) return; + static float framecounter; framecounter--; if (framecounter <= 0) { if (cdrom_seek_delay <= 0) { @@ -1141,12 +1168,12 @@ void AKIKO_hsync_handler (void) } else { cdrom_seek_delay--; } - framecounter = 1000000 / (63 * 75 * cdrom_speed); + framecounter += (float)maxvpos * vblank_hz / (75.0 * cdrom_speed); } subcodecounter--; if (subcodecounter <= 0) { - if ((cdrom_flags & CDFLAG_SUBCODE) && subcodebufferoffset != subcodebufferoffsetw) { + if ((cdrom_flags & CDFLAG_SUBCODE) && cdrom_playing && subcodebufferoffset != subcodebufferoffsetw) { uae_sem_wait (&sub_sem); if (subcodebufferinuse[subcodebufferoffset]) { if (cdrom_subcodeoffset >= 128) @@ -1166,7 +1193,7 @@ void AKIKO_hsync_handler (void) } uae_sem_post (&sub_sem); } - subcodecounter = 1000000 / (70 * 75 * cdrom_speed); + subcodecounter = maxvpos * vblank_hz / (75 * cdrom_speed) - 5; } if (frame2counter > 0) @@ -1174,12 +1201,6 @@ void AKIKO_hsync_handler (void) if (mediacheckcounter > 0) mediacheckcounter--; - if (cdrom_audiotimeout > 0) { - cdrom_audiotimeout--; - if (cdrom_audiotimeout == 0) - cdrom_audiotimeout = -1; - } - akiko_internal (); akiko_handler (); } @@ -1224,16 +1245,6 @@ static void *akiko_thread (void *null) if (unitnum >= 0 && sys_command_cd_qcode (unitnum, qcode_buf)) { uae_u8 as = qcode_buf[1]; qcode_valid = 1; - if (as == AUDIO_STATUS_IN_PROGRESS) { - frame2counter /= 4; - if (cdrom_audiotimeout == 0) { - int lsn = msf2lsn (fromlongbcd (qcode_buf + 4 + 7)); - // make sure audio play really ends because not all drives report position accurately - if ((lsn >= cdrom_toc_cd_buffer.lastaddress - 3 * 75 || lsn >= last_play_end - 3 * 75)) { - cdrom_audiotimeout = 3 * 312; - } - } - } } } diff --git a/blkdev.cpp b/blkdev.cpp index 390b1f4a..c62e43d6 100644 --- a/blkdev.cpp +++ b/blkdev.cpp @@ -26,7 +26,7 @@ static int scsiemu[MAX_TOTAL_SCSI_DEVICES]; static struct device_functions *device_func[MAX_TOTAL_SCSI_DEVICES]; static int openlist[MAX_TOTAL_SCSI_DEVICES]; -static int waspaused[MAX_TOTAL_SCSI_DEVICES], wasslow[MAX_TOTAL_SCSI_DEVICES]; +static int waspaused[MAX_TOTAL_SCSI_DEVICES]; static int delayed[MAX_TOTAL_SCSI_DEVICES]; /* convert minutes, seconds and frames -> logical sector number */ @@ -439,7 +439,6 @@ static void check_changes (int unitnum) struct device_info di; device_func[unitnum]->info (unitnum, &di, 0); wasopen[unitnum] = di.open; - wasslow[unitnum] = di.slow_unit; if (wasopen[unitnum]) { device_func[unitnum]->closedev (unitnum); if (currprefs.scsi) { @@ -465,7 +464,7 @@ static void check_changes (int unitnum) write_log (L"CD: delayed insert '%s'\n", currprefs.cdslots[unitnum].name[0] ? currprefs.cdslots[unitnum].name : L""); device_func_init (0); if (wasopen[unitnum]) { - if (!device_func[unitnum]->opendev (unitnum, currprefs.cdslots[unitnum].name, wasslow[unitnum])) { + if (!device_func[unitnum]->opendev (unitnum, currprefs.cdslots[unitnum].name, 0)) { write_log (L"-> device open failed\n"); } } @@ -591,18 +590,18 @@ int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int scan) return do_scsi (unitnum, cmd, sizeof cmd) ? 0 : 1; } //startlsn = adjustplaypos (unitnum, startlsn); - return device_func[unitnum]->play (unitnum, startlsn, endlsn, scan, NULL); + return device_func[unitnum]->play (unitnum, startlsn, endlsn, scan, NULL, NULL); } /* play CD audio with subchannels */ -int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int scan, play_subchannel_callback subfunc) +int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int scan, play_status_callback statusfunc, play_subchannel_callback subfunc) { if (failunit (unitnum)) return 0; if (device_func[unitnum]->play == NULL) return sys_command_cd_play (unitnum, startlsn, endlsn, scan); //startlsn = adjustplaypos (unitnum, startlsn); - return device_func[unitnum]->play (unitnum, startlsn, endlsn, scan, subfunc); + return device_func[unitnum]->play (unitnum, startlsn, endlsn, scan, statusfunc, subfunc); } /* set CD audio volume */ @@ -1337,7 +1336,7 @@ static int scsi_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, goto errreq; start = toc->toc[toc->first_track_offset + start].paddress; } - sys_command_cd_play (unitnum, start, end, scan, NULL); + sys_command_cd_play (unitnum, start, end, scan); scsi_len = 0; } break; @@ -1357,7 +1356,7 @@ static int scsi_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, goto errreq; int start = toc->toc[toc->first_track_offset + strack - 1].paddress; int end = etrack == toc->last_track ? toc->lastaddress : toc->toc[toc->first_track_offset + etrack - 1 + 1].paddress; - if (!sys_command_cd_play (unitnum, start, end, 0, NULL)) + if (!sys_command_cd_play (unitnum, start, end, 0)) goto notdatatrack; scsi_len = 0; } @@ -1378,7 +1377,7 @@ static int scsi_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, if (end > di.toc.lastaddress) end = di.toc.lastaddress; if (len > 0) { - if (!sys_command_cd_play (unitnum, start, start + len, 0, NULL)) + if (!sys_command_cd_play (unitnum, start, start + len, 0)) goto notdatatrack; } scsi_len = 0; @@ -1401,7 +1400,7 @@ static int scsi_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, if (start > end) goto errreq; if (start < end) - if (!sys_command_cd_play (unitnum, start, end, 0, NULL)) + if (!sys_command_cd_play (unitnum, start, end, 0)) goto notdatatrack; scsi_len = 0; } @@ -1426,7 +1425,7 @@ static int scsi_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, int end = start + len; if (end > di.toc.lastaddress) end = di.toc.lastaddress; - if (!sys_command_cd_play (unitnum, start, end, 0, NULL)) + if (!sys_command_cd_play (unitnum, start, end, 0)) goto notdatatrack; } scsi_len = 0; @@ -1450,7 +1449,7 @@ static int scsi_emulate (int unitnum, uae_u8 *cmdbuf, int scsi_cmd_len, if (start > end) goto errreq; if (start < end) { - if (!sys_command_cd_play (unitnum, start, end, 0, NULL)) + if (!sys_command_cd_play (unitnum, start, end, 0)) goto notdatatrack; } } diff --git a/blkdev_cdimage.cpp b/blkdev_cdimage.cpp index 88be9a03..7918de3d 100644 --- a/blkdev_cdimage.cpp +++ b/blkdev_cdimage.cpp @@ -67,7 +67,7 @@ struct cdunit { uae_u64 cdsize; int blocksize; - int cdda_play_finished; + int cdda_play_state; int cdda_play; int cdda_paused; int cdda_volume[2]; @@ -75,7 +75,8 @@ struct cdunit { int cd_last_pos; int cdda_start, cdda_end; play_subchannel_callback cdda_subfunc; - bool slowunit; + play_status_callback cdda_statusfunc; + int cdda_delay; int imagechange; TCHAR newfile[MAX_DPATH]; @@ -333,6 +334,13 @@ static void dosub (struct cdunit *cdu, struct cdtoc *t, int sector) cdu->cdda_subfunc (d, 1); } +static int setstate (struct cdunit *cdu, int state) +{ + cdu->cdda_play_state = state; + if (cdu->cdda_statusfunc) + return cdu->cdda_statusfunc (cdu->cdda_play_state); + return 0; +} static void *cdda_unpack_func (void *v) { @@ -393,7 +401,6 @@ static void *cdda_play_func (void *v) int volume[2], volume_main; int oldplay; struct cdunit *cdu = (struct cdunit*)v; - int firstloops; for (i = 0; i < 2; i++) { memset (&whdr[i], 0, sizeof (WAVEHDR)); @@ -431,10 +438,10 @@ static void *cdda_play_func (void *v) if (oldplay != cdu->cdda_play) { struct cdtoc *t; - int sector; - struct _timeb tb; + int sector, diff; + struct _timeb tb1, tb2; - _ftime (&tb); + _ftime (&tb1); cdda_pos = cdu->cdda_start; oldplay = cdu->cdda_play; cdu->cd_last_pos = cdda_pos; @@ -442,6 +449,7 @@ static void *cdda_play_func (void *v) t = findtoc (cdu, §or); if (!t) { write_log (L"IMAGE CDDA: illegal sector number %d\n", cdu->cdda_start); + setstate (cdu, AUDIO_STATUS_PLAY_ERROR); } else { write_log (L"IMAGE CDDA: playing from %d to %d, track %d ('%s', offset %d, secoffset %d)\n", cdu->cdda_start, cdu->cdda_end, t->track, t->fname, t->offset, sector); @@ -455,13 +463,12 @@ static void *cdda_play_func (void *v) while (cdimage_unpack_active == 0) Sleep (10); } - firstloops = cdu->slowunit ? 150 : 30; - while (cdu->cdda_paused && cdu->cdda_play > 0) { - Sleep (10); - firstloops = -1; - } - if (firstloops > 0) - firstloops /= num_sectors; + _ftime (&tb2); + diff = (tb2.time * (uae_s64)1000 + tb2.millitm) - (tb1.time * (uae_s64)1000 + tb1.millitm); + diff -= cdu->cdda_delay; + if (diff < 0 && cdu->cdda_play > 0) + Sleep (-diff); + setstate (cdu, AUDIO_STATUS_IN_PROGRESS); } while (!(whdr[bufnum].dwFlags & WHDR_DONE)) { @@ -471,8 +478,10 @@ static void *cdda_play_func (void *v) } bufon[bufnum] = 0; - if (!isaudiotrack (&cdu->di.toc, cdda_pos)) + if (!isaudiotrack (&cdu->di.toc, cdda_pos)) { + setstate (cdu, AUDIO_STATUS_PLAY_ERROR); goto end; // data track? + } if ((cdda_pos < cdu->cdda_end || cdu->cdda_end == 0xffffffff) && !cdu->cdda_paused && cdu->cdda_play > 0) { struct cdtoc *t; @@ -483,46 +492,36 @@ static void *cdda_play_func (void *v) memset (px[bufnum], 0, num_sectors * 2352); - if (firstloops > 0) { - - firstloops--; - for (cnt = 0; cnt < num_sectors; cnt++) - dosub (cdu, NULL, -1); - - } else { - - for (cnt = 0; cnt < num_sectors; cnt++) { - sector = cdda_pos; + for (cnt = 0; cnt < num_sectors; cnt++) { + sector = cdda_pos; - if (cdu->cdda_scan) { - cdda_pos += cdu->cdda_scan; - if (cdda_pos < 0) - cdda_pos = 0; - } else { - cdda_pos++; - } - if (cdda_pos - num_sectors < cdu->cdda_end && cdda_pos >= cdu->cdda_end) - dofinish = 1; - - t = findtoc (cdu, §or); - if (t) { - if (t->handle && !(t->ctrl & 4)) { - uae_u8 *dst = px[bufnum] + cnt * t->size; - int totalsize = t->size + t->skipsize; - if ((t->enctype == AUDENC_MP3 || t->enctype == AUDENC_FLAC) && t->data) { - if (t->filesize >= sector * totalsize + t->offset + t->size) - memcpy (dst, t->data + sector * totalsize + t->offset, t->size); - } else if (t->enctype == AUDENC_PCM) { - if (sector * totalsize + t->offset + totalsize < t->filesize) { - zfile_fseek (t->handle, sector * totalsize + t->offset, SEEK_SET); - zfile_fread (dst, t->size, 1, t->handle); - } + if (cdu->cdda_scan) { + cdda_pos += cdu->cdda_scan; + if (cdda_pos < 0) + cdda_pos = 0; + } else { + cdda_pos++; + } + if (cdda_pos - num_sectors < cdu->cdda_end && cdda_pos >= cdu->cdda_end) + dofinish = 1; + + t = findtoc (cdu, §or); + if (t) { + if (t->handle && !(t->ctrl & 4)) { + uae_u8 *dst = px[bufnum] + cnt * t->size; + int totalsize = t->size + t->skipsize; + if ((t->enctype == AUDENC_MP3 || t->enctype == AUDENC_FLAC) && t->data) { + if (t->filesize >= sector * totalsize + t->offset + t->size) + memcpy (dst, t->data + sector * totalsize + t->offset, t->size); + } else if (t->enctype == AUDENC_PCM) { + if (sector * totalsize + t->offset + totalsize < t->filesize) { + zfile_fseek (t->handle, sector * totalsize + t->offset, SEEK_SET); + zfile_fread (dst, t->size, 1, t->handle); } } - dosub (cdu, t, cdda_pos); } + dosub (cdu, t, cdda_pos); } - } volume_main = currprefs.sound_volume; @@ -551,7 +550,7 @@ static void *cdda_play_func (void *v) cdu->cd_last_pos = cdda_pos; if (dofinish) { - cdu->cdda_play_finished = 1; + setstate (cdu, AUDIO_STATUS_PLAY_COMPLETE); cdu->cdda_play = -1; cdda_pos = cdu->cdda_end + 1; } @@ -597,7 +596,6 @@ static void cdda_stop (struct cdunit *cdu) Sleep (10); } } - cdu->cdda_play_finished = 0; cdu->cdda_paused = 0; } @@ -621,19 +619,23 @@ static int command_stop (int unitnum) return 1; } -static int command_play (int unitnum, int startlsn, int endlsn, int scan, play_subchannel_callback subfunc) +static int command_play (int unitnum, int startlsn, int endlsn, int scan, play_status_callback statusfunc, play_subchannel_callback subfunc) { struct cdunit *cdu = unitisopen (unitnum); if (!cdu) return 0; - if (!isaudiotrack (&cdu->di.toc, startlsn)) - return 0; - cdu->cdda_play_finished = 0; cdu->cd_last_pos = startlsn; cdu->cdda_start = startlsn; cdu->cdda_end = endlsn; cdu->cdda_subfunc = subfunc; + cdu->cdda_statusfunc = statusfunc; cdu->cdda_scan = scan > 0 ? 10 : (scan < 0 ? 10 : 0); + cdu->cdda_delay = setstate (cdu, -1); + setstate (cdu, AUDIO_STATUS_NOT_SUPPORTED); + if (!isaudiotrack (&cdu->di.toc, startlsn)) { + setstate (cdu, AUDIO_STATUS_PLAY_ERROR); + return 0; + } if (!cdu->cdda_play) uae_start_thread (L"cdimage_cdda_play", cdda_play_func, cdu, NULL); cdu->cdda_play++; @@ -655,14 +657,10 @@ static int command_qcode (int unitnum, uae_u8 *buf, int sector) memset (buf, 0, SUBQ_SIZE); p = buf; - status = AUDIO_STATUS_NO_STATUS; - if (cdu->cdda_play > 0) { - status = AUDIO_STATUS_IN_PROGRESS; - if (cdu->cdda_paused) - status = AUDIO_STATUS_PAUSED; - } else if (cdu->cdda_play_finished) { - status = AUDIO_STATUS_PLAY_COMPLETE; - } + status = cdu->cdda_play_state; + if (cdu->cdda_play > 0 && cdu->cdda_paused) + status = AUDIO_STATUS_PAUSED; + if (sector < 0) pos = cdu->cd_last_pos; else @@ -1574,7 +1572,6 @@ static struct device_info *info_device (int unitnum, struct device_info *di, int if (!cdu->enabled) return NULL; di->open = cdu->open; - di->slow_unit = cdu->slowunit; di->removable = 1; di->bus = unitnum; di->target = 0; @@ -1635,7 +1632,6 @@ static int open_device (int unitnum, const TCHAR *ident, int flags) cdu->enabled = true; cdu->cdda_volume[0] = 0x7fff; cdu->cdda_volume[1] = 0x7fff; - cdu->slowunit = (flags & 1) != 0; blkdev_cd_change (unitnum, currprefs.cdslots[unitnum].name); if (cdimage_unpack_thread == 0) { init_comm_pipe (&unpack_pipe, 10, 1); diff --git a/cdtv.cpp b/cdtv.cpp index 3d97b25c..2daf2bf6 100644 --- a/cdtv.cpp +++ b/cdtv.cpp @@ -76,9 +76,9 @@ static volatile uae_u32 dmac_acr; static volatile int dmac_wtc; static volatile int dmac_dma; -static volatile int activate_stch, cdrom_command_done, play_state, play_statewait; +static volatile int activate_stch, cdrom_command_done; static volatile int cdrom_sector, cdrom_sectors, cdrom_length, cdrom_offset; -static volatile int cd_playing, cd_paused, cd_motor, cd_media, cd_error, cd_finished, cd_isready; +static volatile int cd_playing, cd_paused, cd_motor, cd_media, cd_error, cd_finished, cd_isready, cd_audio_finished; static uae_u32 last_play_pos, last_play_end; static volatile int cdtv_hsync, dma_finished, cdtv_sectorsize; @@ -140,28 +140,10 @@ static int get_toc (void) return 1; } -static void finished_cdplay (void) -{ - cd_audio_status = AUDIO_STATUS_PLAY_COMPLETE; - cd_playing = 0; - cd_finished = 1; - cd_paused = 0; - do_stch (); -} - static int get_qcode (void) { if (!sys_command_cd_qcode (unitnum, cdrom_qcode)) return 0; - if (cd_playing) { - if (cdrom_qcode[1] == AUDIO_STATUS_IN_PROGRESS) { - int end = msf2lsn (fromlongbcd (cdrom_qcode + 4 + 7)); - if (end >= play_end - 75) - finished_cdplay (); - } else if (cdrom_qcode[1] == AUDIO_STATUS_PLAY_COMPLETE) { - finished_cdplay (); - } - } cdrom_qcode[1] = cd_audio_status; return 1; } @@ -185,6 +167,7 @@ static void cdaudiostop (void) cd_playing = 0; cd_paused = 0; cd_motor = 0; + cd_audio_finished = 0; write_comm_pipe_u32 (&requests, 0x0104, 1); } @@ -283,7 +266,22 @@ static void subfunc (uae_u8 *data, int cnt) subcodebufferoffsetw = offset; uae_sem_post (&sub_sem); } - +static int statusfunc (int status) +{ + if (status < 0) + return 500; + if (cd_audio_status != status) { + if (status == AUDIO_STATUS_PLAY_COMPLETE || status == AUDIO_STATUS_PLAY_ERROR) { + cd_audio_finished = 1; + } else { + if (status == AUDIO_STATUS_IN_PROGRESS) + cd_playing = 1; + activate_stch = 1; + } + } + cd_audio_status = status; + return 0; +} static void do_play (void) { @@ -292,15 +290,21 @@ static void do_play (void) uae_u32 scan = read_comm_pipe_u32_blocking (&requests); subreset (); sys_command_cd_pause (unitnum, 0); - cd_audio_status = AUDIO_STATUS_PLAY_ERROR; sys_command_cd_volume (unitnum, (cd_volume_stored << 5) | (cd_volume_stored >> 5), (cd_volume_stored << 5) | (cd_volume_stored >> 5)); - if (sys_command_cd_play (unitnum, start, end, 0, subfunc)) { - cd_audio_status = AUDIO_STATUS_IN_PROGRESS; - cd_playing = 1; - } else { - cd_error = 1; + sys_command_cd_play (unitnum, start, end, 0, statusfunc, subfunc); +} + +static void startplay (void) +{ + subreset (); + write_comm_pipe_u32 (&requests, 0x0110, 0); + write_comm_pipe_u32 (&requests, play_start, 0); + write_comm_pipe_u32 (&requests, play_end, 0); + write_comm_pipe_u32 (&requests, 0, 1); + if (!cd_motor) { + cd_motor = 1; + activate_stch = 1; } - activate_stch = 1; } static int play_cdtrack (uae_u8 *p) @@ -344,7 +348,7 @@ static int play_cdtrack (uae_u8 *p) write_log (L"PLAY CD AUDIO from %d-%d, %06X (%d) to %06X (%d)\n", track_start, track_end, start, start, end, end); #endif - play_state = 1; + startplay (); return 0; } @@ -364,11 +368,10 @@ static int play_cd (uae_u8 *p) cd_playing = 0; cd_paused = 0; cd_motor = 0; - cd_audio_status = AUDIO_STATUS_PLAY_COMPLETE; - sys_command_cd_pause (unitnum, 0); - sys_command_cd_stop (unitnum); - cd_isready = 50; + write_comm_pipe_u32 (&requests, 0x0104, 1); + cd_audio_status = AUDIO_STATUS_NO_STATUS; cd_error = 1; + activate_stch = 1; return 0; } if (p[0] != 0x09) { /* msf */ @@ -386,7 +389,7 @@ static int play_cd (uae_u8 *p) write_log (L"PLAY CD AUDIO from %06X (%d) to %06X (%d)\n", lsn2msf (start), start, lsn2msf (end), end); #endif - play_state = 1; + startplay (); return 0; } @@ -510,7 +513,6 @@ static void cdrom_command_thread (uae_u8 b) { case 0x01: /* seek */ if (cdrom_command_cnt_in == 7) { - sleep_millis (500); cdrom_command_accepted (0, s, &cdrom_command_cnt_in); cd_finished = 1; } @@ -795,8 +797,7 @@ static void init_play (int start, int end) write_log (L"PLAY CD AUDIO from %06X (%d) to %06X (%d)\n", lsn2msf (start), start, lsn2msf (end), end); #endif - play_state = 1; - subreset (); + startplay (); } bool cdtv_front_panel (int button) @@ -1162,7 +1163,17 @@ void CDTV_hsync_handler (void) sten = 0; } + if (cd_audio_finished) { + cd_audio_finished = 0; + cd_playing = 0; + cd_finished = 1; + cd_paused = 0; + //cd_error = 1; + activate_stch = 1; + } + static int subchannelcounter; + int cntmax = maxvpos * vblank_hz / 75 - 6; if (subchannelcounter > 0) subchannelcounter--; if (subchannelcounter <= 0) { @@ -1187,7 +1198,7 @@ void CDTV_hsync_handler (void) tp_check_interrupts (); } uae_sem_post (&sub_sem); - subchannelcounter = 200; + subchannelcounter = cntmax; } } if (!scor && !cd_playing) { @@ -1195,35 +1206,20 @@ void CDTV_hsync_handler (void) scor = 1; tp_check_interrupts (); scor = 0; - subchannelcounter = 200; + subchannelcounter = cntmax; } } - if (cdtv_hsync < 200 && cdtv_hsync >= 0) + if (cdtv_hsync < cntmax && cdtv_hsync >= 0) return; cdtv_hsync = 0; - - if (play_state == 1) { - play_state = 2; - cd_playing = 1; - cd_motor = 1; - activate_stch = 1; - play_statewait = 2; - } else if (play_statewait > 0) { - play_statewait--; - } else if (play_state == 2) { - write_comm_pipe_u32 (&requests, 0x0110, 0); - write_comm_pipe_u32 (&requests, play_start, 0); - write_comm_pipe_u32 (&requests, play_end, 0); - write_comm_pipe_u32 (&requests, 0, 1); - play_state = 0; - } - +#if 0 if (cd_isready > 0) { cd_isready--; if (!cd_isready) do_stch (); } +#endif if (dmac_dma || dma_finished) cd_led |= LED_CD_ACTIVE; else @@ -1877,7 +1873,7 @@ uae_u8 *save_cdtv (int *len) (cd_motor ? 8 : 0) | (cd_error ? 16 : 0) | (cd_finished ? 32 : 0) | (cdrom_command_done ? 64 : 0) | (activate_stch ? 128 : 0) | (sten ? 256 : 0) | (stch ? 512 : 0) | (frontpanel ? 1024 : 0)); save_u8 (cd_isready); - save_u8 (play_state); + save_u8 (0); save_u16 (cd_volume_stored); if (cd_playing) get_qcode (); @@ -1930,7 +1926,7 @@ uae_u8 *restore_cdtv (uae_u8 *src) stch = (v & 512) ? 1 : 0; frontpanel = (v & 1024) ? 1 : 0; cd_isready = restore_u8 (); - play_state = restore_u8 (); + restore_u8 (); cd_volume_stored = restore_u16 (); last_play_pos = restore_u32 (); last_play_end = restore_u32 (); diff --git a/drawing.cpp b/drawing.cpp index da4c2a6d..ca65de57 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -1953,13 +1953,11 @@ STATIC_INLINE void do_color_changes (line_draw_func worker_border, line_draw_fun (*worker_border) (lastpos, nextpos_in_range); lastpos = nextpos_in_range; } - if (i != dip_for_drawing->last_color_change) { - if (regno >= 0x1000) { - pfield_expand_dp_bplconx (regno, value); - } else { - color_reg_set (&colors_for_drawing, regno, value); - colors_for_drawing.acolors[regno] = getxcolor (value); - } + if (regno >= 0x1000) { + pfield_expand_dp_bplconx (regno, value); + } else if (regno >= 0) { + color_reg_set (&colors_for_drawing, regno, value); + colors_for_drawing.acolors[regno] = getxcolor (value); } if (lastpos >= endpos) break; diff --git a/include/blkdev.h b/include/blkdev.h index 4b315acb..edbf4d11 100644 --- a/include/blkdev.h +++ b/include/blkdev.h @@ -80,7 +80,6 @@ struct device_info { TCHAR productid[18]; TCHAR revision[6]; TCHAR *backend; - int slow_unit; struct cd_toc_head toc; }; @@ -110,10 +109,11 @@ typedef uae_u8* (*execscsicmd_in_func)(int, uae_u8*, int, int*); typedef int (*execscsicmd_direct_func)(int, struct amigascsi*); typedef void (*play_subchannel_callback)(uae_u8*, int); +typedef int (*play_status_callback)(int); typedef int (*pause_func)(int, int); typedef int (*stop_func)(int); -typedef int (*play_func)(int, int, int, int, play_subchannel_callback); +typedef int (*play_func)(int, int, int, int, play_status_callback, play_subchannel_callback); typedef uae_u32 (*volume_func)(int, uae_u16, uae_u16); typedef int (*qcode_func)(int, uae_u8*, int); typedef int (*toc_func)(int, struct cd_toc_head*); @@ -160,7 +160,7 @@ extern struct device_info *sys_command_info (int unitnum, struct device_info *di extern int sys_command_cd_pause (int unitnum, int paused); extern void sys_command_cd_stop (int unitnum); extern int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int); -extern int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int scan, play_subchannel_callback subfunc); +extern int sys_command_cd_play (int unitnum, int startlsn, int endlsn, int scan, play_status_callback statusfunc, play_subchannel_callback subfunc); extern uae_u32 sys_command_cd_volume (int unitnum, uae_u16 volume_left, uae_u16 volume_right); extern int sys_command_cd_qcode (int unitnum, uae_u8*); extern int sys_command_cd_toc (int unitnum, struct cd_toc_head*); diff --git a/include/drawing.h b/include/drawing.h index 27e6fa6f..50b34979 100644 --- a/include/drawing.h +++ b/include/drawing.h @@ -244,7 +244,6 @@ struct draw_info { extern int next_sprite_entry; extern struct decision line_decisions[2 * (MAXVPOS + 2) + 1]; -extern struct draw_info line_drawinfo[2][2 * (MAXVPOS + 2) + 1]; extern uae_u8 line_data[(MAXVPOS + 2) * 2][MAX_PLANES * MAX_WORDS_PER_LINE * 2]; diff --git a/newcpu.cpp b/newcpu.cpp index 8ce65408..1917686c 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -8,6 +8,7 @@ #define MOVEC_DEBUG 0 #define MMUOP_DEBUG 2 +#define DEBUG_CD32CDTVIO 0 #include "sysconfig.h" #include "sysdeps.h" @@ -2763,8 +2764,7 @@ STATIC_INLINE int do_specialties (int cycles) //static uae_u32 pcs[1000]; -//#define DEBUG_CD32CDTVIO -#ifdef DEBUG_CD32CDTVIO +#if DEBUG_CD32CDTVIO static uae_u32 cd32nextpc, cd32request; @@ -2856,7 +2856,7 @@ static void m68k_run_1 (void) count_instr (opcode); -#ifdef DEBUG_CD32CDTVIO +#if DEBUG_CD32CDTVIO out_cd32io (m68k_getpc ()); #endif @@ -2903,7 +2903,7 @@ static void m68k_run_1_ce (void) ipl_fetch (); for (;;) { uae_u32 opcode = r->ir; -#ifdef DEBUG_CD32CDTVIO +#if DEBUG_CD32CDTVIO out_cd32io (m68k_getpc ()); #endif (*cpufunctbl[opcode])(opcode); @@ -3138,7 +3138,7 @@ static void m68k_run_2p (void) uae_u32 opcode; uae_u32 pc = m68k_getpc (); -#ifdef DEBUG_CD32CDTVIO +#if DEBUG_CD32CDTVIO out_cd32io (m68k_getpc ()); #endif diff --git a/od-win32/blkdev_win32_ioctl.cpp b/od-win32/blkdev_win32_ioctl.cpp index 9fafdca8..b9081bbe 100644 --- a/od-win32/blkdev_win32_ioctl.cpp +++ b/od-win32/blkdev_win32_ioctl.cpp @@ -12,6 +12,8 @@ #ifdef WINDDK +#include + #include "options.h" #include "uae.h" #include "threaddep/thread.h" @@ -60,11 +62,13 @@ struct dev_info_ioctl { uae_u8 subcodebuf[SUB_CHANNEL_SIZE]; bool subcodevalid; play_subchannel_callback cdda_subfunc; + play_status_callback cdda_statusfunc; + int cdda_play_state; + int cdda_delay; struct device_info di; uae_sem_t sub_sem, sub_sem2; bool open; bool usesptiread; - bool slowunit; }; static struct dev_info_ioctl ciw32[MAX_TOTAL_SCSI_DEVICES]; @@ -447,6 +451,14 @@ static int cdda_openwav (struct dev_info_ioctl *ciw) return 1; } +static int setstate (struct dev_info_ioctl *ciw, int state) +{ + ciw->cdda_play_state = state; + if (ciw->cdda_statusfunc) + return ciw->cdda_statusfunc (ciw->cdda_play_state); + return 0; +} + static void *cdda_play (void *v) { struct dev_info_ioctl *ciw = (struct dev_info_ioctl*)v; @@ -461,8 +473,8 @@ static void *cdda_play (void *v) MMRESULT mmr; int volume[2], volume_main; int oldplay; - int firstloops; int readblocksize = 2352 + 96; + int current_sector = -1; for (i = 0; i < 2; i++) { memset (&whdr[i], 0, sizeof (WAVEHDR)); @@ -506,23 +518,33 @@ static void *cdda_play (void *v) bufon[bufnum] = 0; if (oldplay != ciw->cdda_play) { + struct _timeb tb1, tb2; + current_sector = -1; + _ftime (&tb1); cdda_pos = ciw->cdda_start; oldplay = ciw->cdda_play; - firstloops = ciw->slowunit ? 25 : 5; write_log (L"IOCTL%s CDDA: playing from %d to %d\n", ciw->usesptiread ? L"(SPTI)" : L"", ciw->cdda_start, ciw->cdda_end); ciw->subcodevalid = false; - while (ciw->cdda_paused && ciw->cdda_play > 0) { - firstloops = -1; + while (ciw->cdda_paused && ciw->cdda_play > 0) Sleep (10); - } + // pre-load first sectors + if (read_block (ciw, -1, px[bufnum], cdda_pos, num_sectors, readblocksize)) + current_sector = cdda_pos; + _ftime (&tb2); + int diff = (tb2.time * (uae_s64)1000 + tb2.millitm) - (tb1.time * (uae_s64)1000 + tb1.millitm); + diff -= ciw->cdda_delay; + if (diff < 0 && ciw->cdda_play > 0) + Sleep (-diff); + setstate (ciw, AUDIO_STATUS_IN_PROGRESS); } if ((cdda_pos < ciw->cdda_end || ciw->cdda_end == 0xffffffff) && !ciw->cdda_paused && ciw->cdda_play) { - int sectors = num_sectors; - if (!isaudiotrack (&ciw->di.toc, cdda_pos)) + if (!isaudiotrack (&ciw->di.toc, cdda_pos)) { + setstate (ciw, AUDIO_STATUS_PLAY_ERROR); goto end; // data track? + } gui_flicker_led (LED_CD, ciw->di.unitnum - 1, LED_CD_AUDIO); @@ -530,38 +552,35 @@ static void *cdda_play (void *v) ciw->subcodevalid = false; memset (ciw->subcode, 0, sizeof ciw->subcode); - memset (px[bufnum], 0, sectors * readblocksize); - - if (firstloops > 0) { - - firstloops--; + bool readerr = false; + if (current_sector != cdda_pos) { + current_sector = -1; + memset (px[bufnum], 0, num_sectors * readblocksize); + readerr = read_block (ciw, -1, px[bufnum], cdda_pos, num_sectors, readblocksize) == 0; + if (!readerr) + current_sector = cdda_pos; + } + if (readerr) { if (ciw->cdda_subfunc) - ciw->cdda_subfunc (ciw->subcode, sectors); - + ciw->cdda_subfunc (ciw->subcode, num_sectors); } else { - - firstloops = -1; - if (!read_block (ciw, -1, px[bufnum], cdda_pos, sectors, readblocksize)) { - if (ciw->cdda_subfunc) - ciw->cdda_subfunc (ciw->subcode, sectors); - } else { - for (i = 0; i < sectors; i++) { - memcpy (ciw->subcode + i * SUB_CHANNEL_SIZE, px[bufnum] + readblocksize * i + 2352, SUB_CHANNEL_SIZE); - } - if (ciw->cdda_subfunc) - ciw->cdda_subfunc (ciw->subcode, sectors); - for (i = 1; i < sectors; i++) { - memmove (px[bufnum] + 2352 * i, px[bufnum] + readblocksize * i, 2352); - } - ciw->subcodevalid = true; + for (i = 0; i < num_sectors; i++) { + memcpy (ciw->subcode + i * SUB_CHANNEL_SIZE, px[bufnum] + readblocksize * i + 2352, SUB_CHANNEL_SIZE); } - reseterrormode (ciw); + if (ciw->cdda_subfunc) + ciw->cdda_subfunc (ciw->subcode, num_sectors); + for (i = 1; i < num_sectors; i++) { + memmove (px[bufnum] + 2352 * i, px[bufnum] + readblocksize * i, 2352); + } + ciw->subcodevalid = true; } + reseterrormode (ciw); uae_sem_post (&ciw->sub_sem); + if (ciw->subcodevalid) { uae_sem_wait (&ciw->sub_sem2); - memcpy (ciw->subcodebuf, ciw->subcode + (sectors - 1) * SUB_CHANNEL_SIZE, SUB_CHANNEL_SIZE); + memcpy (ciw->subcodebuf, ciw->subcode + (num_sectors - 1) * SUB_CHANNEL_SIZE, SUB_CHANNEL_SIZE); uae_sem_post (&ciw->sub_sem2); } @@ -588,21 +607,19 @@ static void *cdda_play (void *v) break; } - if (firstloops < 0) { - if (ciw->cdda_scan) { - cdda_pos += ciw->cdda_scan * num_sectors; - if (cdda_pos < 0) - cdda_pos = 0; - } else { - cdda_pos += num_sectors; - } - if (cdda_pos - num_sectors < ciw->cdda_end && cdda_pos >= ciw->cdda_end) { - ciw->cdda_play_finished = 1; - ciw->cdda_play = -1; - cdda_pos = ciw->cdda_end; - } + if (ciw->cdda_scan) { + cdda_pos += ciw->cdda_scan * num_sectors; + if (cdda_pos < 0) + cdda_pos = 0; + } else { + cdda_pos += num_sectors; + } + if (cdda_pos - num_sectors < ciw->cdda_end && cdda_pos >= ciw->cdda_end) { + setstate (ciw, AUDIO_STATUS_PLAY_COMPLETE); + ciw->cdda_play_finished = 1; + ciw->cdda_play = -1; + cdda_pos = ciw->cdda_end; } - ciw->cd_last_pos = cdda_pos; } @@ -682,19 +699,27 @@ static uae_u32 ioctl_command_volume (int unitnum, uae_u16 volume_left, uae_u16 v } /* play CD audio */ -static int ioctl_command_play (int unitnum, int startlsn, int endlsn, int scan, play_subchannel_callback subfunc) +static int ioctl_command_play (int unitnum, int startlsn, int endlsn, int scan, play_status_callback statusfunc, play_subchannel_callback subfunc) { struct dev_info_ioctl *ciw = unitisopen (unitnum); if (!ciw) return 0; - if (!open_createfile (ciw, 0)) - return 0; - if (!isaudiotrack (&ciw->di.toc, startlsn)) - return 0; ciw->cdda_play_finished = 0; ciw->cdda_subfunc = subfunc; + ciw->cdda_statusfunc = statusfunc; ciw->cdda_scan = scan > 0 ? 10 : (scan < 0 ? 10 : 0); + ciw->cdda_delay = setstate (ciw, -1); + setstate (ciw, AUDIO_STATUS_NOT_SUPPORTED); + + if (!open_createfile (ciw, 0)) { + setstate (ciw, AUDIO_STATUS_PLAY_ERROR); + return 0; + } + if (!isaudiotrack (&ciw->di.toc, startlsn)) { + setstate (ciw, AUDIO_STATUS_PLAY_ERROR); + return 0; + } if (!ciw->cdda_play) { uae_start_thread (L"ioctl_cdda_play", cdda_play, ciw, NULL); } @@ -1121,7 +1146,6 @@ static void update_device_info (int unitnum) di->type = ciw->type == DRIVE_CDROM ? INQ_ROMD : INQ_DASD; di->unitnum = unitnum + 1; _tcscpy (di->label, ciw->drvlettername); - di->slow_unit = ciw->slowunit; di->backend = L"IOCTL"; } @@ -1235,7 +1259,6 @@ static int open_device (int unitnum, const TCHAR *ident, int flags) if (ciw->drvletter == 0) return 0; unittable[unitnum] = unitnum + 1; - ciw->slowunit = (flags & 1) != 0; if (sys_cddev_open (ciw, unitnum) == 0) return 1; unittable[unitnum] = 0; diff --git a/od-win32/win32.h b/od-win32/win32.h index 188ce05f..80613cfb 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -19,7 +19,7 @@ #define LANG_DLL 1 #define WINUAEBETA L"10" -#define WINUAEDATE MAKEBD(2010, 8, 10) +#define WINUAEDATE MAKEBD(2010, 8, 11) #define WINUAEEXTRA L"" #define WINUAEREV L"" diff --git a/scsiemul.cpp b/scsiemul.cpp index 7b948a28..07661857 100644 --- a/scsiemul.cpp +++ b/scsiemul.cpp @@ -798,7 +798,7 @@ static int dev_do_io (struct devstruct *dev, uaecptr request) { int start = io_offset; int end = io_length + start; - if (!sys_command_cd_play (dev->di.unitnum, start, end, 0, NULL)) + if (!sys_command_cd_play (dev->di.unitnum, start, end, 0)) io_error = IOERR_BADADDRESS; } break; @@ -806,7 +806,7 @@ static int dev_do_io (struct devstruct *dev, uaecptr request) { int start = msf2lsn (io_offset); int end = msf2lsn (io_length) + start; - if (!sys_command_cd_play (dev->di.unitnum, start, end, 0, NULL)) + if (!sys_command_cd_play (dev->di.unitnum, start, end, 0)) io_error = IOERR_BADADDRESS; } break; @@ -817,7 +817,7 @@ static int dev_do_io (struct devstruct *dev, uaecptr request) if (sys_command_cd_toc (dev->di.unitnum, &toc)) { for (int i = toc.first_track_offset; i < toc.last_track_offset; i++) { if (i == io_offset && i + io_length <= toc.last_track_offset) { - ok = sys_command_cd_play (dev->di.unitnum, toc.toc[i].address, toc.toc[i + io_length].address, 0, NULL); + ok = sys_command_cd_play (dev->di.unitnum, toc.toc[i].address, toc.toc[i + io_length].address, 0); break; } }