trunk/src/mame/machine/gdrom.c
| r22814 | r22815 | |
| 7 | 7 | #include "emu.h" |
| 8 | 8 | #include "machine/scsihle.h" |
| 9 | 9 | #include "cdrom.h" |
| 10 | | #include "sound/cdda.h" |
| 11 | 10 | #include "imagedev/chd_cd.h" |
| 12 | 11 | #include "gdrom.h" |
| 13 | 12 | |
| r22814 | r22815 | |
| 29 | 28 | const device_type GDROM = &device_creator<gdrom_device>; |
| 30 | 29 | |
| 31 | 30 | gdrom_device::gdrom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 32 | | : scsihle_device(mconfig, GDROM, "GDROM", tag, owner, clock, "gdrom", __FILE__) |
| 31 | : scsihle_device(mconfig, GDROM, "GDROM", tag, owner, clock, "gdrom", __FILE__), |
| 32 | m_cdda(*this, "cdda") |
| 33 | 33 | { |
| 34 | 34 | } |
| 35 | 35 | |
| r22814 | r22815 | |
| 103 | 103 | |
| 104 | 104 | void gdrom_device::ExecCommand( int *transferLength ) |
| 105 | 105 | { |
| 106 | | device_t *cdda; |
| 107 | 106 | int trk; |
| 108 | 107 | |
| 109 | 108 | switch ( command[0] ) |
| r22814 | r22815 | |
| 141 | 140 | break; |
| 142 | 141 | |
| 143 | 142 | case 0x1b: // START STOP UNIT |
| 144 | | cdda = cdda_from_cdrom( machine(), cdrom); |
| 145 | | if (cdda != NULL) |
| 143 | if (m_cdda != NULL) |
| 146 | 144 | { |
| 147 | | cdda_stop_audio(cdda); |
| 145 | m_cdda->stop_audio(); |
| 148 | 146 | } |
| 149 | 147 | SetPhase( SCSI_PHASE_STATUS ); |
| 150 | 148 | *transferLength = 0; |
| r22814 | r22815 | |
| 177 | 175 | cur_subblock = 0; |
| 178 | 176 | } |
| 179 | 177 | |
| 180 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 181 | | if (cdda != NULL) |
| 178 | if (m_cdda != NULL) |
| 182 | 179 | { |
| 183 | | cdda_stop_audio(cdda); |
| 180 | m_cdda->stop_audio(); |
| 184 | 181 | } |
| 185 | 182 | |
| 186 | 183 | SetPhase( SCSI_PHASE_DATAIN ); |
| r22814 | r22815 | |
| 223 | 220 | cur_subblock = 0; |
| 224 | 221 | } |
| 225 | 222 | |
| 226 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 227 | | if (cdda != NULL) |
| 223 | if (m_cdda != NULL) |
| 228 | 224 | { |
| 229 | | cdda_stop_audio(cdda); |
| 225 | m_cdda->stop_audio(); |
| 230 | 226 | } |
| 231 | 227 | |
| 232 | 228 | SetPhase( SCSI_PHASE_DATAIN ); |
| r22814 | r22815 | |
| 266 | 262 | length = 4; |
| 267 | 263 | } |
| 268 | 264 | |
| 269 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 270 | | if (cdda != NULL) |
| 265 | if (m_cdda != NULL) |
| 271 | 266 | { |
| 272 | | cdda_stop_audio(cdda); |
| 267 | m_cdda->stop_audio(); |
| 273 | 268 | } |
| 274 | 269 | |
| 275 | 270 | SetPhase( SCSI_PHASE_DATAIN ); |
| r22814 | r22815 | |
| 297 | 292 | if (cdrom_get_track_type(cdrom, trk) == CD_TRACK_AUDIO) |
| 298 | 293 | { |
| 299 | 294 | play_err_flag = 0; |
| 300 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 301 | | if (cdda != NULL) |
| 302 | | cdda_start_audio(cdda, lba, blocks); |
| 295 | if (m_cdda != NULL) |
| 296 | m_cdda->start_audio(lba, blocks); |
| 303 | 297 | } |
| 304 | 298 | else |
| 305 | 299 | { |
| r22814 | r22815 | |
| 328 | 322 | |
| 329 | 323 | if (blocks && cdrom) |
| 330 | 324 | { |
| 331 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 332 | | if (cdda != NULL) |
| 333 | | cdda_start_audio(cdda, lba, blocks); |
| 325 | if (m_cdda != NULL) |
| 326 | m_cdda->start_audio(lba, blocks); |
| 334 | 327 | } |
| 335 | 328 | |
| 336 | 329 | logerror("GDROM: PLAY AUDIO T/I: strk %d idx %d etrk %d idx %d frames %d\n", command[4], command[5], command[7], command[8], blocks); |
| r22814 | r22815 | |
| 341 | 334 | case 0x4b: // PAUSE/RESUME |
| 342 | 335 | if (cdrom) |
| 343 | 336 | { |
| 344 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 345 | | if (cdda != NULL) |
| 346 | | cdda_pause_audio(cdda, (command[8] & 0x01) ^ 0x01); |
| 337 | if (m_cdda != NULL) |
| 338 | m_cdda->pause_audio((command[8] & 0x01) ^ 0x01); |
| 347 | 339 | } |
| 348 | 340 | |
| 349 | 341 | logerror("GDROM: PAUSE/RESUME: %s\n", command[8]&1 ? "RESUME" : "PAUSE"); |
| r22814 | r22815 | |
| 383 | 375 | if (cdrom_get_track_type(cdrom, trk) == CD_TRACK_AUDIO) |
| 384 | 376 | { |
| 385 | 377 | play_err_flag = 0; |
| 386 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 387 | | if (cdda != NULL) |
| 388 | | cdda_start_audio(cdda, lba, blocks); |
| 378 | if (m_cdda != NULL) |
| 379 | m_cdda->start_audio(lba, blocks); |
| 389 | 380 | } |
| 390 | 381 | else |
| 391 | 382 | { |
| r22814 | r22815 | |
| 412 | 403 | cur_subblock = 0; |
| 413 | 404 | } |
| 414 | 405 | |
| 415 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 416 | | if (cdda != NULL) |
| 406 | if (m_cdda != NULL) |
| 417 | 407 | { |
| 418 | | cdda_stop_audio(cdda); |
| 408 | m_cdda->stop_audio(); |
| 419 | 409 | } |
| 420 | 410 | |
| 421 | 411 | SetPhase( SCSI_PHASE_DATAIN ); |
| r22814 | r22815 | |
| 444 | 434 | UINT32 last_phys_frame; |
| 445 | 435 | UINT32 temp; |
| 446 | 436 | UINT8 tmp_buffer[2048]; |
| 447 | | device_t *cdda; |
| 448 | 437 | |
| 449 | 438 | switch ( command[0] ) |
| 450 | 439 | { |
| r22814 | r22815 | |
| 455 | 444 | |
| 456 | 445 | data[0] = 0x71; // deferred error |
| 457 | 446 | |
| 458 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 459 | | if (cdda != NULL && cdda_audio_active(cdda)) |
| 447 | if (m_cdda != NULL && m_cdda->audio_active()) |
| 460 | 448 | { |
| 461 | 449 | data[12] = 0x00; |
| 462 | 450 | data[13] = 0x11; // AUDIO PLAY OPERATION IN PROGRESS |
| r22814 | r22815 | |
| 583 | 571 | |
| 584 | 572 | msf = command[1] & 0x2; |
| 585 | 573 | |
| 586 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 587 | | audio_active = cdda != NULL && cdda_audio_active(cdda); |
| 574 | audio_active = m_cdda != NULL && m_cdda->audio_active(); |
| 588 | 575 | if (audio_active) |
| 589 | 576 | { |
| 590 | | if (cdda_audio_paused(cdda)) |
| 577 | if (m_cdda->audio_paused()) |
| 591 | 578 | { |
| 592 | 579 | data[1] = 0x12; // audio is paused |
| 593 | 580 | } |
| r22814 | r22815 | |
| 598 | 585 | } |
| 599 | 586 | else |
| 600 | 587 | { |
| 601 | | if (cdda != NULL && cdda_audio_ended(cdda)) |
| 588 | if (m_cdda != NULL && m_cdda->audio_ended()) |
| 602 | 589 | { |
| 603 | 590 | data[1] = 0x13; // ended successfully |
| 604 | 591 | } |
| r22814 | r22815 | |
| 612 | 599 | // if audio is playing, get the latest LBA from the CDROM layer |
| 613 | 600 | if (audio_active) |
| 614 | 601 | { |
| 615 | | last_lba = cdda_get_audio_lba(cdda); |
| 602 | last_lba = m_cdda->get_audio_lba(); |
| 616 | 603 | } |
| 617 | 604 | else |
| 618 | 605 | { |
trunk/src/mame/machine/cd32.c
| r22814 | r22815 | |
| 61 | 61 | UINT8 m_cdrom_cmd_start; |
| 62 | 62 | UINT8 m_cdrom_cmd_end; |
| 63 | 63 | UINT8 m_cdrom_cmd_resp; |
| 64 | cdda_device *m_cdda; |
| 64 | 65 | cdrom_file *m_cdrom; |
| 65 | 66 | UINT8 * m_cdrom_toc; |
| 66 | 67 | emu_timer *m_dma_timer; |
| r22814 | r22815 | |
| 203 | 204 | state->m_dma_timer = machine.scheduler().timer_alloc(FUNC(akiko_dma_proc), state); |
| 204 | 205 | state->m_frame_timer = machine.scheduler().timer_alloc(FUNC(akiko_frame_proc), state); |
| 205 | 206 | state->m_i2cmem = machine.device("i2cmem"); |
| 206 | | |
| 207 | | |
| 207 | state->m_cdda = machine.device<cdda_device>("cdda"); |
| 208 | 208 | } |
| 209 | 209 | |
| 210 | 210 | static void akiko_nvram_write(akiko_state *state, UINT32 data) |
| r22814 | r22815 | |
| 323 | 323 | |
| 324 | 324 | static void akiko_cdda_stop(akiko_state *state) |
| 325 | 325 | { |
| 326 | | device_t *cdda = cdda_from_cdrom(state->machine(), state->m_cdrom); |
| 327 | | |
| 328 | | if (cdda != NULL) |
| 326 | if (state->m_cdda != NULL) |
| 329 | 327 | { |
| 330 | | cdda_stop_audio(cdda); |
| 328 | state->m_cdda->stop_audio(); |
| 331 | 329 | state->m_frame_timer->reset( ); |
| 332 | 330 | } |
| 333 | 331 | } |
| 334 | 332 | |
| 335 | 333 | static void akiko_cdda_play(akiko_state *state, UINT32 lba, UINT32 num_blocks) |
| 336 | 334 | { |
| 337 | | device_t *cdda = cdda_from_cdrom(state->machine(), state->m_cdrom); |
| 338 | | if (cdda != NULL) |
| 335 | if (state->m_cdda != NULL) |
| 339 | 336 | { |
| 340 | | cdda_start_audio(cdda, lba, num_blocks); |
| 337 | state->m_cdda->start_audio(lba, num_blocks); |
| 341 | 338 | state->m_frame_timer->adjust( attotime::from_hz( 75 ) ); |
| 342 | 339 | } |
| 343 | 340 | } |
| 344 | 341 | |
| 345 | 342 | static void akiko_cdda_pause(akiko_state *state, int pause) |
| 346 | 343 | { |
| 347 | | device_t *cdda = cdda_from_cdrom(state->machine(), state->m_cdrom); |
| 348 | | if (cdda != NULL) |
| 344 | if (state->m_cdda != NULL) |
| 349 | 345 | { |
| 350 | | if (cdda_audio_active(cdda) && cdda_audio_paused(cdda) != pause ) |
| 346 | if (state->m_cdda->audio_active() && state->m_cdda->audio_paused() != pause ) |
| 351 | 347 | { |
| 352 | | cdda_pause_audio(cdda, pause); |
| 348 | state->m_cdda->pause_audio(pause); |
| 353 | 349 | |
| 354 | 350 | if ( pause ) |
| 355 | 351 | { |
| r22814 | r22815 | |
| 365 | 361 | |
| 366 | 362 | static UINT8 akiko_cdda_getstatus(akiko_state *state, UINT32 *lba) |
| 367 | 363 | { |
| 368 | | device_t *cdda = cdda_from_cdrom(state->machine(), state->m_cdrom); |
| 369 | | |
| 370 | 364 | if ( lba ) *lba = 0; |
| 371 | 365 | |
| 372 | | if (cdda != NULL) |
| 366 | if (state->m_cdda != NULL) |
| 373 | 367 | { |
| 374 | | if (cdda_audio_active(cdda)) |
| 368 | if (state->m_cdda->audio_active()) |
| 375 | 369 | { |
| 376 | | if ( lba ) *lba = cdda_get_audio_lba(cdda); |
| 370 | if ( lba ) *lba = state->m_cdda->get_audio_lba(); |
| 377 | 371 | |
| 378 | | if (cdda_audio_paused(cdda)) |
| 372 | if (state->m_cdda->audio_paused()) |
| 379 | 373 | { |
| 380 | 374 | return 0x12; /* audio paused */ |
| 381 | 375 | } |
| r22814 | r22815 | |
| 384 | 378 | return 0x11; /* audio in progress */ |
| 385 | 379 | } |
| 386 | 380 | } |
| 387 | | else if (cdda_audio_ended(cdda)) |
| 381 | else if (state->m_cdda->audio_ended()) |
| 388 | 382 | { |
| 389 | 383 | return 0x13; /* audio ended */ |
| 390 | 384 | } |
| r22814 | r22815 | |
| 409 | 403 | static TIMER_CALLBACK(akiko_frame_proc) |
| 410 | 404 | { |
| 411 | 405 | akiko_state *state = (akiko_state *)ptr; |
| 412 | | device_t *cdda = cdda_from_cdrom(machine, state->m_cdrom); |
| 413 | 406 | |
| 414 | 407 | (void)param; |
| 415 | 408 | |
| 416 | | if (cdda != NULL) |
| 409 | if (state->m_cdda != NULL) |
| 417 | 410 | { |
| 418 | 411 | UINT8 s = akiko_cdda_getstatus(state, NULL); |
| 419 | 412 | |
| r22814 | r22815 | |
| 787 | 780 | switch( offset ) |
| 788 | 781 | { |
| 789 | 782 | case 0x00/4: /* ID */ |
| 790 | | if ( state->m_cdrom != NULL ) cdda_set_cdrom(state->m_space->machine().device("cdda"), state->m_cdrom); |
| 783 | if ( state->m_cdrom != NULL ) state->m_cdda->set_cdrom(state->m_cdrom); |
| 791 | 784 | return 0x0000cafe; |
| 792 | 785 | |
| 793 | 786 | case 0x04/4: /* CDROM STATUS 1 */ |
trunk/src/emu/sound/cdda.c
| r22814 | r22815 | |
| 4 | 4 | */ |
| 5 | 5 | |
| 6 | 6 | #include "emu.h" |
| 7 | | #include "cdrom.h" |
| 8 | 7 | #include "cdda.h" |
| 9 | 8 | |
| 10 | | struct cdda_info |
| 11 | | { |
| 12 | | sound_stream * stream; |
| 13 | | cdrom_file * disc; |
| 14 | | |
| 15 | | INT8 audio_playing, audio_pause, audio_ended_normally; |
| 16 | | UINT32 audio_lba, audio_length; |
| 17 | | |
| 18 | | UINT8 * audio_cache; |
| 19 | | UINT32 audio_samples; |
| 20 | | UINT32 audio_bptr; |
| 21 | | INT16 audio_volume[2]; |
| 22 | | }; |
| 23 | | |
| 24 | | INLINE cdda_info *get_safe_token(device_t *device) |
| 25 | | { |
| 26 | | assert(device != NULL); |
| 27 | | assert(device->type() == CDDA); |
| 28 | | return (cdda_info *)downcast<cdda_device *>(device)->token(); |
| 29 | | } |
| 30 | | |
| 31 | 9 | #define MAX_SECTORS ( 4 ) |
| 32 | 10 | |
| 33 | | static void get_audio_data(cdda_info *info, stream_sample_t *bufL, stream_sample_t *bufR, UINT32 samples_wanted); |
| 34 | 11 | |
| 12 | //------------------------------------------------- |
| 13 | // sound_stream_update - handle a stream update |
| 14 | //------------------------------------------------- |
| 35 | 15 | |
| 36 | | /*------------------------------------------------- |
| 37 | | cdda_update - stream update callback |
| 38 | | -------------------------------------------------*/ |
| 39 | | |
| 40 | | static STREAM_UPDATE( cdda_update ) |
| 16 | void cdda_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) |
| 41 | 17 | { |
| 42 | | cdda_info *info = (cdda_info *)param; |
| 43 | | get_audio_data(info, &outputs[0][0], &outputs[1][0], samples); |
| 44 | | info->audio_volume[0] = (INT16)outputs[0][0]; |
| 45 | | info->audio_volume[1] = (INT16)outputs[1][0]; |
| 18 | get_audio_data(&outputs[0][0], &outputs[1][0], samples); |
| 19 | m_audio_volume[0] = (INT16)outputs[0][0]; |
| 20 | m_audio_volume[1] = (INT16)outputs[1][0]; |
| 46 | 21 | } |
| 47 | 22 | |
| 23 | //------------------------------------------------- |
| 24 | // device_start - device-specific startup |
| 25 | //------------------------------------------------- |
| 48 | 26 | |
| 49 | | /*------------------------------------------------- |
| 50 | | DEVICE_START( cdda ) - audio start callback |
| 51 | | -------------------------------------------------*/ |
| 52 | | |
| 53 | | static DEVICE_START( cdda ) |
| 27 | void cdda_device::device_start() |
| 54 | 28 | { |
| 55 | | //const struct CDDAinterface *intf; |
| 56 | | cdda_info *info = get_safe_token(device); |
| 57 | | |
| 58 | 29 | /* allocate an audio cache */ |
| 59 | | info->audio_cache = auto_alloc_array( device->machine(), UINT8, CD_MAX_SECTOR_DATA * MAX_SECTORS ); |
| 30 | m_audio_cache = auto_alloc_array( machine(), UINT8, CD_MAX_SECTOR_DATA * MAX_SECTORS ); |
| 60 | 31 | |
| 61 | | //intf = (const struct CDDAinterface *)device->static_config(); |
| 32 | m_stream = machine().sound().stream_alloc(*this, 0, 2, 44100); |
| 62 | 33 | |
| 63 | | info->stream = device->machine().sound().stream_alloc(*device, 0, 2, 44100, info, cdda_update); |
| 34 | m_audio_playing = 0; |
| 35 | m_audio_pause = 0; |
| 36 | m_audio_ended_normally = 0; |
| 37 | m_audio_lba = 0; |
| 38 | m_audio_length = 0; |
| 39 | m_audio_samples = 0; |
| 40 | m_audio_bptr = 0; |
| 64 | 41 | |
| 65 | | device->save_item( NAME(info->audio_playing) ); |
| 66 | | device->save_item( NAME(info->audio_pause) ); |
| 67 | | device->save_item( NAME(info->audio_ended_normally) ); |
| 68 | | device->save_item( NAME(info->audio_lba) ); |
| 69 | | device->save_item( NAME(info->audio_length) ); |
| 70 | | device->save_pointer( NAME(info->audio_cache), CD_MAX_SECTOR_DATA * MAX_SECTORS ); |
| 71 | | device->save_item( NAME(info->audio_samples) ); |
| 72 | | device->save_item( NAME(info->audio_bptr) ); |
| 42 | save_item( NAME(m_audio_playing) ); |
| 43 | save_item( NAME(m_audio_pause) ); |
| 44 | save_item( NAME(m_audio_ended_normally) ); |
| 45 | save_item( NAME(m_audio_lba) ); |
| 46 | save_item( NAME(m_audio_length) ); |
| 47 | save_pointer( NAME(m_audio_cache), CD_MAX_SECTOR_DATA * MAX_SECTORS ); |
| 48 | save_item( NAME(m_audio_samples) ); |
| 49 | save_item( NAME(m_audio_bptr) ); |
| 73 | 50 | } |
| 74 | 51 | |
| 75 | 52 | |
| r22814 | r22815 | |
| 78 | 55 | given CDDA stream |
| 79 | 56 | -------------------------------------------------*/ |
| 80 | 57 | |
| 81 | | void cdda_set_cdrom(device_t *device, void *file) |
| 58 | void cdda_device::set_cdrom(void *file) |
| 82 | 59 | { |
| 83 | | cdda_info *info = get_safe_token(device); |
| 84 | | info->disc = (cdrom_file *)file; |
| 60 | m_disc = (cdrom_file *)file; |
| 85 | 61 | } |
| 86 | 62 | |
| 87 | 63 | |
| 88 | 64 | /*------------------------------------------------- |
| 89 | | cdda_from_cdrom - find the CDDA stream |
| 90 | | that references the given CD-ROM file |
| 91 | | -------------------------------------------------*/ |
| 92 | | |
| 93 | | device_t *cdda_from_cdrom(running_machine &machine, void *file) |
| 94 | | { |
| 95 | | sound_interface_iterator iter(machine.root_device()); |
| 96 | | for (device_sound_interface *sound = iter.first(); sound != NULL; sound = iter.next()) |
| 97 | | if (sound->device().type() == CDDA) |
| 98 | | { |
| 99 | | cdda_info *info = get_safe_token(*sound); |
| 100 | | if (info->disc == file) |
| 101 | | return *sound; |
| 102 | | } |
| 103 | | |
| 104 | | return NULL; |
| 105 | | } |
| 106 | | |
| 107 | | |
| 108 | | /*------------------------------------------------- |
| 109 | 65 | cdda_start_audio - begin playback of a Red |
| 110 | 66 | Book audio track |
| 111 | 67 | -------------------------------------------------*/ |
| 112 | 68 | |
| 113 | | void cdda_start_audio(device_t *device, UINT32 startlba, UINT32 numblocks) |
| 69 | void cdda_device::start_audio(UINT32 startlba, UINT32 numblocks) |
| 114 | 70 | { |
| 115 | | cdda_info *info = get_safe_token(device); |
| 116 | | |
| 117 | | info->stream->update(); |
| 118 | | info->audio_playing = TRUE; |
| 119 | | info->audio_pause = FALSE; |
| 120 | | info->audio_ended_normally = FALSE; |
| 121 | | info->audio_lba = startlba; |
| 122 | | info->audio_length = numblocks; |
| 71 | m_stream->update(); |
| 72 | m_audio_playing = TRUE; |
| 73 | m_audio_pause = FALSE; |
| 74 | m_audio_ended_normally = FALSE; |
| 75 | m_audio_lba = startlba; |
| 76 | m_audio_length = numblocks; |
| 77 | m_audio_samples = 0; |
| 123 | 78 | } |
| 124 | 79 | |
| 125 | 80 | |
| r22814 | r22815 | |
| 128 | 83 | audio track |
| 129 | 84 | -------------------------------------------------*/ |
| 130 | 85 | |
| 131 | | void cdda_stop_audio(device_t *device) |
| 86 | void cdda_device::stop_audio() |
| 132 | 87 | { |
| 133 | | cdda_info *info = get_safe_token(device); |
| 134 | | |
| 135 | | info->stream->update(); |
| 136 | | info->audio_playing = FALSE; |
| 137 | | info->audio_ended_normally = TRUE; |
| 88 | m_stream->update(); |
| 89 | m_audio_playing = FALSE; |
| 90 | m_audio_ended_normally = TRUE; |
| 138 | 91 | } |
| 139 | 92 | |
| 140 | 93 | |
| r22814 | r22815 | |
| 143 | 96 | a Red Book audio track |
| 144 | 97 | -------------------------------------------------*/ |
| 145 | 98 | |
| 146 | | void cdda_pause_audio(device_t *device, int pause) |
| 99 | void cdda_device::pause_audio(int pause) |
| 147 | 100 | { |
| 148 | | cdda_info *info = get_safe_token(device); |
| 149 | | |
| 150 | | info->stream->update(); |
| 151 | | info->audio_pause = pause; |
| 101 | m_stream->update(); |
| 102 | m_audio_pause = pause; |
| 152 | 103 | } |
| 153 | 104 | |
| 154 | 105 | |
| r22814 | r22815 | |
| 157 | 108 | (physical sector) during Red Book playback |
| 158 | 109 | -------------------------------------------------*/ |
| 159 | 110 | |
| 160 | | UINT32 cdda_get_audio_lba(device_t *device) |
| 111 | UINT32 cdda_device::get_audio_lba() |
| 161 | 112 | { |
| 162 | | cdda_info *info = get_safe_token(device); |
| 163 | | |
| 164 | | info->stream->update(); |
| 165 | | return info->audio_lba; |
| 113 | m_stream->update(); |
| 114 | return m_audio_lba; |
| 166 | 115 | } |
| 167 | 116 | |
| 168 | 117 | |
| r22814 | r22815 | |
| 171 | 120 | playback status |
| 172 | 121 | -------------------------------------------------*/ |
| 173 | 122 | |
| 174 | | int cdda_audio_active(device_t *device) |
| 123 | int cdda_device::audio_active() |
| 175 | 124 | { |
| 176 | | cdda_info *info = get_safe_token(device); |
| 177 | | |
| 178 | | info->stream->update(); |
| 179 | | return info->audio_playing; |
| 125 | m_stream->update(); |
| 126 | return m_audio_playing; |
| 180 | 127 | } |
| 181 | 128 | |
| 182 | 129 | |
| r22814 | r22815 | |
| 185 | 132 | playback is paused |
| 186 | 133 | -------------------------------------------------*/ |
| 187 | 134 | |
| 188 | | int cdda_audio_paused(device_t *device) |
| 135 | int cdda_device::audio_paused() |
| 189 | 136 | { |
| 190 | | cdda_info *info = get_safe_token(device); |
| 191 | | return info->audio_pause; |
| 137 | return m_audio_pause; |
| 192 | 138 | } |
| 193 | 139 | |
| 194 | 140 | |
| r22814 | r22815 | |
| 197 | 143 | track reached it's natural end |
| 198 | 144 | -------------------------------------------------*/ |
| 199 | 145 | |
| 200 | | int cdda_audio_ended(device_t *device) |
| 146 | int cdda_device::audio_ended() |
| 201 | 147 | { |
| 202 | | cdda_info *info = get_safe_token(device); |
| 203 | | return info->audio_ended_normally; |
| 148 | return m_audio_ended_normally; |
| 204 | 149 | } |
| 205 | 150 | |
| 206 | 151 | |
| r22814 | r22815 | |
| 210 | 155 | converts it to 2 16-bit 44.1 kHz streams |
| 211 | 156 | -------------------------------------------------*/ |
| 212 | 157 | |
| 213 | | static void get_audio_data(cdda_info *info, stream_sample_t *bufL, stream_sample_t *bufR, UINT32 samples_wanted) |
| 158 | void cdda_device::get_audio_data(stream_sample_t *bufL, stream_sample_t *bufR, UINT32 samples_wanted) |
| 214 | 159 | { |
| 215 | | int i, sectoread, remaining; |
| 216 | | INT16 *audio_cache = (INT16 *) info->audio_cache; |
| 160 | int i; |
| 161 | INT16 *audio_cache = (INT16 *) m_audio_cache; |
| 217 | 162 | |
| 218 | | /* if no file, audio not playing, audio paused, or out of disc data, |
| 219 | | just zero fill */ |
| 220 | | if (!info->disc || !info->audio_playing || info->audio_pause || (!info->audio_length && !info->audio_samples)) |
| 163 | while (samples_wanted > 0) |
| 221 | 164 | { |
| 222 | | if( info->disc && info->audio_playing && !info->audio_pause && !info->audio_length ) |
| 165 | /* if no file, audio not playing, audio paused, or out of disc data, |
| 166 | just zero fill */ |
| 167 | if (!m_disc || !m_audio_playing || m_audio_pause || (!m_audio_length && !m_audio_samples)) |
| 223 | 168 | { |
| 224 | | info->audio_playing = FALSE; |
| 225 | | info->audio_ended_normally = TRUE; |
| 169 | if( m_disc && m_audio_playing && !m_audio_pause && !m_audio_length ) |
| 170 | { |
| 171 | m_audio_playing = FALSE; |
| 172 | m_audio_ended_normally = TRUE; |
| 173 | } |
| 174 | |
| 175 | memset(bufL, 0, sizeof(stream_sample_t)*samples_wanted); |
| 176 | memset(bufR, 0, sizeof(stream_sample_t)*samples_wanted); |
| 177 | return; |
| 226 | 178 | } |
| 227 | 179 | |
| 228 | | memset(bufL, 0, sizeof(stream_sample_t)*samples_wanted); |
| 229 | | memset(bufR, 0, sizeof(stream_sample_t)*samples_wanted); |
| 230 | | return; |
| 231 | | } |
| 180 | int samples = samples_wanted; |
| 181 | if (samples > m_audio_samples) |
| 182 | { |
| 183 | samples = m_audio_samples; |
| 184 | } |
| 232 | 185 | |
| 233 | | /* if we've got enough samples, just feed 'em out */ |
| 234 | | if (samples_wanted <= info->audio_samples) |
| 235 | | { |
| 236 | | for (i = 0; i < samples_wanted; i++) |
| 186 | for (i = 0; i < samples; i++) |
| 237 | 187 | { |
| 238 | | *bufL++ = audio_cache[ info->audio_bptr++ ]; |
| 239 | | *bufR++ = audio_cache[ info->audio_bptr++ ]; |
| 188 | /* CD-DA data on the disc is big-endian */ |
| 189 | *bufL++ = (INT16) BIG_ENDIANIZE_INT16( audio_cache[ m_audio_bptr ] ); m_audio_bptr++; |
| 190 | *bufR++ = (INT16) BIG_ENDIANIZE_INT16( audio_cache[ m_audio_bptr ] ); m_audio_bptr++; |
| 240 | 191 | } |
| 241 | 192 | |
| 242 | | info->audio_samples -= samples_wanted; |
| 243 | | return; |
| 244 | | } |
| 193 | samples_wanted -= samples; |
| 194 | m_audio_samples -= samples; |
| 245 | 195 | |
| 246 | | /* we don't have enough, so first feed what we've got */ |
| 247 | | for (i = 0; i < info->audio_samples; i++) |
| 248 | | { |
| 249 | | *bufL++ = audio_cache[ info->audio_bptr++ ]; |
| 250 | | *bufR++ = audio_cache[ info->audio_bptr++ ]; |
| 251 | | } |
| 196 | if (m_audio_samples == 0) |
| 197 | { |
| 198 | int sectors = m_audio_length; |
| 199 | if (sectors > MAX_SECTORS) |
| 200 | { |
| 201 | sectors = MAX_SECTORS; |
| 202 | } |
| 252 | 203 | |
| 253 | | /* remember how much left for later */ |
| 254 | | remaining = samples_wanted - info->audio_samples; |
| 204 | for (i = 0; i < sectors; i++) |
| 205 | { |
| 206 | cdrom_read_data(m_disc, m_audio_lba, &m_audio_cache[CD_MAX_SECTOR_DATA*i], CD_TRACK_AUDIO); |
| 255 | 207 | |
| 256 | | /* reset the buffer and get what we can from the disc */ |
| 257 | | info->audio_samples = 0; |
| 258 | | if (info->audio_length >= MAX_SECTORS) |
| 259 | | { |
| 260 | | sectoread = MAX_SECTORS; |
| 261 | | } |
| 262 | | else |
| 263 | | { |
| 264 | | sectoread = info->audio_length; |
| 265 | | } |
| 208 | m_audio_lba++; |
| 209 | } |
| 266 | 210 | |
| 267 | | for (i = 0; i < sectoread; i++) |
| 268 | | { |
| 269 | | cdrom_read_data(info->disc, info->audio_lba, &info->audio_cache[CD_MAX_SECTOR_DATA*i], CD_TRACK_AUDIO); |
| 211 | m_audio_samples = (CD_MAX_SECTOR_DATA*sectors)/4; |
| 212 | m_audio_length -= sectors; |
| 270 | 213 | |
| 271 | | info->audio_lba++; |
| 272 | | } |
| 273 | | |
| 274 | | info->audio_samples = (CD_MAX_SECTOR_DATA*sectoread)/4; |
| 275 | | info->audio_length -= sectoread; |
| 276 | | |
| 277 | | /* CD-DA data on the disc is big-endian, flip if we're not */ |
| 278 | | if (ENDIANNESS_NATIVE == ENDIANNESS_LITTLE) |
| 279 | | { |
| 280 | | for( i = 0; i < info->audio_samples * 2; i++ ) |
| 281 | | { |
| 282 | | audio_cache[ i ] = BIG_ENDIANIZE_INT16( audio_cache[ i ] ); |
| 214 | /* reset feedout ptr */ |
| 215 | m_audio_bptr = 0; |
| 283 | 216 | } |
| 284 | 217 | } |
| 285 | | |
| 286 | | /* reset feedout ptr */ |
| 287 | | info->audio_bptr = 0; |
| 288 | | |
| 289 | | /* we've got data, feed it out by calling ourselves recursively */ |
| 290 | | get_audio_data(info, bufL, bufR, remaining); |
| 291 | 218 | } |
| 292 | 219 | |
| 293 | 220 | /*------------------------------------------------- |
| r22814 | r22815 | |
| 295 | 222 | for both speakers, used for fade in/out effects |
| 296 | 223 | -------------------------------------------------*/ |
| 297 | 224 | |
| 298 | | void cdda_set_volume(device_t *device,int volume) |
| 225 | void cdda_device::set_volume(int volume) |
| 299 | 226 | { |
| 300 | | cdda_info *cdda = get_safe_token(device); |
| 301 | | |
| 302 | | cdda->stream->set_output_gain(0,volume / 100.0); |
| 303 | | cdda->stream->set_output_gain(1,volume / 100.0); |
| 227 | m_stream->set_output_gain(0,volume / 100.0); |
| 228 | m_stream->set_output_gain(1,volume / 100.0); |
| 304 | 229 | } |
| 305 | 230 | |
| 306 | 231 | /*------------------------------------------------- |
| r22814 | r22815 | |
| 308 | 233 | for either speaker, used for fade in/out effects |
| 309 | 234 | -------------------------------------------------*/ |
| 310 | 235 | |
| 311 | | void cdda_set_channel_volume(device_t *device, int channel, int volume) |
| 236 | void cdda_device::set_channel_volume(int channel, int volume) |
| 312 | 237 | { |
| 313 | | cdda_info *cdda = get_safe_token(device); |
| 314 | | |
| 315 | | cdda->stream->set_output_gain(channel,volume / 100.0); |
| 238 | m_stream->set_output_gain(channel,volume / 100.0); |
| 316 | 239 | } |
| 317 | 240 | |
| 318 | 241 | |
| r22814 | r22815 | |
| 321 | 244 | for either speaker, used for volume control display |
| 322 | 245 | -------------------------------------------------*/ |
| 323 | 246 | |
| 324 | | INT16 cdda_get_channel_volume(device_t *device, int channel) |
| 247 | INT16 cdda_device::get_channel_volume(int channel) |
| 325 | 248 | { |
| 326 | | cdda_info *cdda = get_safe_token(device); |
| 327 | | |
| 328 | | return cdda->audio_volume[channel]; |
| 249 | return m_audio_volume[channel]; |
| 329 | 250 | } |
| 330 | 251 | |
| 331 | 252 | const device_type CDDA = &device_creator<cdda_device>; |
| r22814 | r22815 | |
| 334 | 255 | : device_t(mconfig, CDDA, "CD/DA", tag, owner, clock), |
| 335 | 256 | device_sound_interface(mconfig, *this) |
| 336 | 257 | { |
| 337 | | m_token = global_alloc_clear(cdda_info); |
| 338 | 258 | } |
| 339 | 259 | |
| 340 | 260 | //------------------------------------------------- |
| r22814 | r22815 | |
| 346 | 266 | void cdda_device::device_config_complete() |
| 347 | 267 | { |
| 348 | 268 | } |
| 349 | | |
| 350 | | //------------------------------------------------- |
| 351 | | // device_start - device-specific startup |
| 352 | | //------------------------------------------------- |
| 353 | | |
| 354 | | void cdda_device::device_start() |
| 355 | | { |
| 356 | | DEVICE_START_NAME( cdda )(this); |
| 357 | | } |
| 358 | | |
| 359 | | //------------------------------------------------- |
| 360 | | // sound_stream_update - handle a stream update |
| 361 | | //------------------------------------------------- |
| 362 | | |
| 363 | | void cdda_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) |
| 364 | | { |
| 365 | | // should never get here |
| 366 | | fatalerror("sound_stream_update called; not applicable to legacy sound devices\n"); |
| 367 | | } |
trunk/src/emu/machine/scsicd.c
| r22814 | r22815 | |
| 7 | 7 | #include "emu.h" |
| 8 | 8 | #include "machine/scsihle.h" |
| 9 | 9 | #include "cdrom.h" |
| 10 | | #include "sound/cdda.h" |
| 11 | 10 | #include "imagedev/chd_cd.h" |
| 12 | 11 | #include "scsicd.h" |
| 13 | 12 | |
| r22814 | r22815 | |
| 23 | 22 | const device_type SCSICD = &device_creator<scsicd_device>; |
| 24 | 23 | |
| 25 | 24 | scsicd_device::scsicd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 26 | | : scsihle_device(mconfig, SCSICD, "SCSICD", tag, owner, clock, "scsicd", __FILE__) |
| 25 | : scsihle_device(mconfig, SCSICD, "SCSICD", tag, owner, clock, "scsicd", __FILE__), |
| 26 | m_cdda(*this, "cdda") |
| 27 | 27 | { |
| 28 | 28 | } |
| 29 | 29 | |
| 30 | 30 | scsicd_device::scsicd_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) : |
| 31 | | scsihle_device(mconfig, type, name, tag, owner, clock, shortname, source) |
| 31 | scsihle_device(mconfig, type, name, tag, owner, clock, shortname, source), |
| 32 | m_cdda(*this, "cdda") |
| 32 | 33 | { |
| 33 | 34 | } |
| 34 | 35 | |
| r22814 | r22815 | |
| 82 | 83 | |
| 83 | 84 | void scsicd_device::ExecCommand( int *transferLength ) |
| 84 | 85 | { |
| 85 | | device_t *cdda; |
| 86 | 86 | int trk; |
| 87 | 87 | |
| 88 | 88 | switch ( command[0] ) |
| r22814 | r22815 | |
| 110 | 110 | break; |
| 111 | 111 | |
| 112 | 112 | case 0x1b: // START STOP UNIT |
| 113 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 114 | | if (cdda != NULL) |
| 115 | | { |
| 116 | | cdda_stop_audio(cdda); |
| 117 | | } |
| 113 | m_cdda->stop_audio(); |
| 118 | 114 | SetPhase( SCSI_PHASE_STATUS ); |
| 119 | 115 | *transferLength = 0; |
| 120 | 116 | break; |
| r22814 | r22815 | |
| 146 | 142 | cur_subblock = 0; |
| 147 | 143 | } |
| 148 | 144 | |
| 149 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 150 | | if (cdda != NULL) |
| 151 | | { |
| 152 | | cdda_stop_audio(cdda); |
| 153 | | } |
| 145 | m_cdda->stop_audio(); |
| 154 | 146 | |
| 155 | 147 | SetPhase( SCSI_PHASE_DATAIN ); |
| 156 | 148 | *transferLength = blocks * bytes_per_sector; |
| r22814 | r22815 | |
| 188 | 180 | length = 4; |
| 189 | 181 | } |
| 190 | 182 | |
| 191 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 192 | | if (cdda != NULL) |
| 193 | | { |
| 194 | | cdda_stop_audio(cdda); |
| 195 | | } |
| 183 | m_cdda->stop_audio(); |
| 196 | 184 | |
| 197 | 185 | SetPhase( SCSI_PHASE_DATAIN ); |
| 198 | 186 | *transferLength = length; |
| r22814 | r22815 | |
| 219 | 207 | if (cdrom_get_track_type(cdrom, trk) == CD_TRACK_AUDIO) |
| 220 | 208 | { |
| 221 | 209 | play_err_flag = 0; |
| 222 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 223 | | if (cdda != NULL) |
| 224 | | cdda_start_audio(cdda, lba, blocks); |
| 210 | m_cdda->start_audio(lba, blocks); |
| 225 | 211 | } |
| 226 | 212 | else |
| 227 | 213 | { |
| r22814 | r22815 | |
| 250 | 236 | |
| 251 | 237 | if (blocks && cdrom) |
| 252 | 238 | { |
| 253 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 254 | | if (cdda != NULL) |
| 255 | | cdda_start_audio(cdda, lba, blocks); |
| 239 | m_cdda->start_audio(lba, blocks); |
| 256 | 240 | } |
| 257 | 241 | |
| 258 | 242 | logerror("SCSICD: PLAY AUDIO T/I: strk %d idx %d etrk %d idx %d frames %d\n", command[4], command[5], command[7], command[8], blocks); |
| r22814 | r22815 | |
| 263 | 247 | case 0x4b: // PAUSE/RESUME |
| 264 | 248 | if (cdrom) |
| 265 | 249 | { |
| 266 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 267 | | if (cdda != NULL) |
| 268 | | cdda_pause_audio(cdda, (command[8] & 0x01) ^ 0x01); |
| 250 | m_cdda->pause_audio((command[8] & 0x01) ^ 0x01); |
| 269 | 251 | } |
| 270 | 252 | |
| 271 | 253 | logerror("SCSICD: PAUSE/RESUME: %s\n", command[8]&1 ? "RESUME" : "PAUSE"); |
| r22814 | r22815 | |
| 276 | 258 | case 0x4e: // STOP |
| 277 | 259 | if (cdrom) |
| 278 | 260 | { |
| 279 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 280 | | if (cdda != NULL) |
| 281 | | cdda_stop_audio(cdda); |
| 261 | m_cdda->stop_audio(); |
| 282 | 262 | } |
| 283 | 263 | |
| 284 | 264 | logerror("SCSICD: STOP_PLAY_SCAN\n"); |
| r22814 | r22815 | |
| 318 | 298 | if (cdrom_get_track_type(cdrom, trk) == CD_TRACK_AUDIO) |
| 319 | 299 | { |
| 320 | 300 | play_err_flag = 0; |
| 321 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 322 | | if (cdda != NULL) |
| 323 | | cdda_start_audio(cdda, lba, blocks); |
| 301 | m_cdda->start_audio(lba, blocks); |
| 324 | 302 | } |
| 325 | 303 | else |
| 326 | 304 | { |
| r22814 | r22815 | |
| 347 | 325 | cur_subblock = 0; |
| 348 | 326 | } |
| 349 | 327 | |
| 350 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 351 | | if (cdda != NULL) |
| 352 | | { |
| 353 | | cdda_stop_audio(cdda); |
| 354 | | } |
| 328 | m_cdda->stop_audio(); |
| 355 | 329 | |
| 356 | 330 | SetPhase( SCSI_PHASE_DATAIN ); |
| 357 | 331 | *transferLength = blocks * bytes_per_sector; |
| r22814 | r22815 | |
| 378 | 352 | UINT32 last_phys_frame; |
| 379 | 353 | UINT32 temp; |
| 380 | 354 | UINT8 tmp_buffer[2048]; |
| 381 | | device_t *cdda; |
| 382 | 355 | |
| 383 | 356 | switch ( command[0] ) |
| 384 | 357 | { |
| r22814 | r22815 | |
| 389 | 362 | |
| 390 | 363 | data[0] = 0x71; // deferred error |
| 391 | 364 | |
| 392 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 393 | | if (cdda != NULL && cdda_audio_active(cdda)) |
| 365 | if (m_cdda->audio_active()) |
| 394 | 366 | { |
| 395 | 367 | data[12] = 0x00; |
| 396 | 368 | data[13] = 0x11; // AUDIO PLAY OPERATION IN PROGRESS |
| r22814 | r22815 | |
| 470 | 442 | { |
| 471 | 443 | case 1: // return current position |
| 472 | 444 | { |
| 473 | | int audio_active; |
| 474 | 445 | int msf; |
| 475 | 446 | |
| 476 | 447 | if (!cdrom) |
| r22814 | r22815 | |
| 482 | 453 | |
| 483 | 454 | msf = command[1] & 0x2; |
| 484 | 455 | |
| 485 | | cdda = cdda_from_cdrom(machine(), cdrom); |
| 486 | | audio_active = cdda != NULL && cdda_audio_active(cdda); |
| 456 | int audio_active = m_cdda->audio_active(); |
| 487 | 457 | if (audio_active) |
| 488 | 458 | { |
| 489 | | if (cdda_audio_paused(cdda)) |
| 459 | // if audio is playing, get the latest LBA from the CDROM layer |
| 460 | last_lba = m_cdda->get_audio_lba(); |
| 461 | if (m_cdda->audio_paused()) |
| 490 | 462 | { |
| 491 | 463 | data[1] = 0x12; // audio is paused |
| 492 | 464 | } |
| r22814 | r22815 | |
| 497 | 469 | } |
| 498 | 470 | else |
| 499 | 471 | { |
| 500 | | if (cdda != NULL && cdda_audio_ended(cdda)) |
| 472 | last_lba = 0; |
| 473 | if (m_cdda->audio_ended()) |
| 501 | 474 | { |
| 502 | 475 | data[1] = 0x13; // ended successfully |
| 503 | 476 | } |
| r22814 | r22815 | |
| 508 | 481 | } |
| 509 | 482 | } |
| 510 | 483 | |
| 511 | | // if audio is playing, get the latest LBA from the CDROM layer |
| 512 | | if (audio_active) |
| 513 | | { |
| 514 | | last_lba = cdda_get_audio_lba(cdda); |
| 515 | | } |
| 516 | | else |
| 517 | | { |
| 518 | | last_lba = 0; |
| 519 | | } |
| 520 | | |
| 521 | 484 | data[2] = 0; |
| 522 | 485 | data[3] = 12; // data length |
| 523 | 486 | data[4] = 0x01; // sub-channel format code |
| r22814 | r22815 | |
| 752 | 715 | void scsicd_device::SetDevice( void *_cdrom ) |
| 753 | 716 | { |
| 754 | 717 | cdrom = (cdrom_file *)_cdrom; |
| 755 | | cdda_set_cdrom(subdevice("cdda"), cdrom); |
| 718 | m_cdda->set_cdrom(cdrom); |
| 756 | 719 | } |
| 757 | 720 | |
| 758 | 721 | int scsicd_device::GetSectorBytes() |
trunk/src/mess/machine/pce.c
| r22814 | r22815 | |
| 519 | 519 | if ( pce_cd.cdda_status != PCE_CD_CDDA_OFF ) |
| 520 | 520 | { |
| 521 | 521 | pce_cd.cdda_status = PCE_CD_CDDA_OFF; |
| 522 | | cdda_stop_audio( machine.device( "cdda" ) ); |
| 522 | machine.device<cdda_device>("cdda")->stop_audio(); |
| 523 | 523 | pce_cd.end_mark = 0; |
| 524 | 524 | } |
| 525 | 525 | |
| r22814 | r22815 | |
| 589 | 589 | if ( pce_cd.cdda_status == PCE_CD_CDDA_PAUSED ) |
| 590 | 590 | { |
| 591 | 591 | pce_cd.cdda_status = PCE_CD_CDDA_OFF; |
| 592 | | cdda_stop_audio( machine.device( "cdda" ) ); |
| 592 | machine.device<cdda_device>("cdda")->stop_audio(); |
| 593 | 593 | pce_cd.end_frame = pce_cd.last_frame; |
| 594 | 594 | pce_cd.end_mark = 0; |
| 595 | 595 | } |
| r22814 | r22815 | |
| 599 | 599 | { |
| 600 | 600 | pce_cd.cdda_status = PCE_CD_CDDA_PLAYING; |
| 601 | 601 | pce_cd.end_frame = pce_cd.last_frame; //get the end of the CD |
| 602 | | cdda_start_audio( machine.device( "cdda" ), pce_cd.current_frame, pce_cd.end_frame - pce_cd.current_frame ); |
| 602 | machine.device<cdda_device>("cdda")->start_audio( pce_cd.current_frame, pce_cd.end_frame - pce_cd.current_frame ); |
| 603 | 603 | pce_cd.cdda_play_mode = (pce_cd.command_buffer[1] & 0x02) ? 2 : 3; // mode 2 sets IRQ at end |
| 604 | 604 | pce_cd.end_mark = (pce_cd.command_buffer[1] & 0x02) ? 1 : 0; |
| 605 | 605 | } |
| r22814 | r22815 | |
| 607 | 607 | { |
| 608 | 608 | pce_cd.cdda_status = PCE_CD_CDDA_PLAYING; |
| 609 | 609 | pce_cd.end_frame = pce_cd.toc->tracks[ cdrom_get_track(pce_cd.cd, pce_cd.current_frame) + 1 ].logframeofs; //get the end of THIS track |
| 610 | | cdda_start_audio( machine.device( "cdda" ), pce_cd.current_frame, pce_cd.end_frame - pce_cd.current_frame ); |
| 610 | machine.device<cdda_device>("cdda")->start_audio( pce_cd.current_frame, pce_cd.end_frame - pce_cd.current_frame ); |
| 611 | 611 | pce_cd.end_mark = 0; |
| 612 | 612 | pce_cd.cdda_play_mode = 3; |
| 613 | 613 | } |
| r22814 | r22815 | |
| 666 | 666 | { |
| 667 | 667 | if ( pce_cd.cdda_status == PCE_CD_CDDA_PAUSED ) |
| 668 | 668 | { |
| 669 | | cdda_pause_audio( machine.device( "cdda" ), 0 ); |
| 669 | machine.device<cdda_device>("cdda")->pause_audio( 0 ); |
| 670 | 670 | } |
| 671 | 671 | else |
| 672 | 672 | { |
| 673 | 673 | //printf("%08x %08x\n",pce_cd.current_frame,pce_cd.end_frame - pce_cd.current_frame); |
| 674 | | cdda_start_audio( machine.device( "cdda" ), pce_cd.current_frame, pce_cd.end_frame - pce_cd.current_frame ); |
| 674 | machine.device<cdda_device>("cdda")->start_audio( pce_cd.current_frame, pce_cd.end_frame - pce_cd.current_frame ); |
| 675 | 675 | pce_cd.end_mark = 1; |
| 676 | 676 | } |
| 677 | 677 | pce_cd.cdda_status = PCE_CD_CDDA_PLAYING; |
| r22814 | r22815 | |
| 679 | 679 | else |
| 680 | 680 | { |
| 681 | 681 | pce_cd.cdda_status = PCE_CD_CDDA_OFF; |
| 682 | | cdda_stop_audio( machine.device( "cdda" ) ); |
| 682 | machine.device<cdda_device>("cdda")->stop_audio(); |
| 683 | 683 | pce_cd.end_frame = pce_cd.last_frame; |
| 684 | 684 | pce_cd.end_mark = 0; |
| 685 | 685 | // assert( NULL == pce_cd_nec_set_audio_stop_position ); |
| r22814 | r22815 | |
| 710 | 710 | } |
| 711 | 711 | |
| 712 | 712 | pce_cd.cdda_status = PCE_CD_CDDA_PAUSED; |
| 713 | | pce_cd.current_frame = cdda_get_audio_lba( machine.device( "cdda" ) ); |
| 714 | | cdda_pause_audio( machine.device( "cdda" ), 1 ); |
| 713 | pce_cd.current_frame = machine.device<cdda_device>("cdda")->get_audio_lba(); |
| 714 | machine.device<cdda_device>("cdda")->pause_audio( 1 ); |
| 715 | 715 | pce_cd_reply_status_byte( state, SCSI_STATUS_OK ); |
| 716 | 716 | } |
| 717 | 717 | |
| r22814 | r22815 | |
| 736 | 736 | { |
| 737 | 737 | case PCE_CD_CDDA_PAUSED: |
| 738 | 738 | pce_cd.data_buffer[0] = 2; |
| 739 | | frame = cdda_get_audio_lba( machine.device( "cdda" ) ); |
| 739 | frame = machine.device<cdda_device>("cdda")->get_audio_lba(); |
| 740 | 740 | break; |
| 741 | 741 | case PCE_CD_CDDA_PLAYING: |
| 742 | 742 | pce_cd.data_buffer[0] = 0; |
| 743 | | frame = cdda_get_audio_lba( machine.device( "cdda" ) ); |
| 743 | frame = machine.device<cdda_device>("cdda")->get_audio_lba(); |
| 744 | 744 | break; |
| 745 | 745 | default: |
| 746 | 746 | pce_cd.data_buffer[0] = 3; |
| r22814 | r22815 | |
| 999 | 999 | pce_cd.cd_motor_on = 0; |
| 1000 | 1000 | pce_cd.selected = 0; |
| 1001 | 1001 | pce_cd.cdda_status = PCE_CD_CDDA_OFF; |
| 1002 | | cdda_stop_audio( machine.device( "cdda" ) ); |
| 1002 | machine.device<cdda_device>("cdda")->stop_audio(); |
| 1003 | 1003 | pce_cd.adpcm_dma_timer->adjust(attotime::never); // stop ADPCM DMA here |
| 1004 | 1004 | } |
| 1005 | 1005 | pce_cd.scsi_last_RST = pce_cd.scsi_RST; |
| r22814 | r22815 | |
| 1064 | 1064 | } |
| 1065 | 1065 | |
| 1066 | 1066 | /* FIXME: presumably CD-DA needs an irq interface for this */ |
| 1067 | | if(cdda_audio_ended(machine.device("cdda")) && pce_cd.end_mark == 1) |
| 1067 | if(machine.device<cdda_device>("cdda")->audio_ended() && pce_cd.end_mark == 1) |
| 1068 | 1068 | { |
| 1069 | 1069 | switch(pce_cd.cdda_play_mode & 3) |
| 1070 | 1070 | { |
| 1071 | | case 1: cdda_start_audio( machine.device( "cdda" ), pce_cd.current_frame, pce_cd.end_frame - pce_cd.current_frame ); pce_cd.end_mark = 1; break; //play with repeat |
| 1071 | case 1: machine.device<cdda_device>("cdda")->start_audio( pce_cd.current_frame, pce_cd.end_frame - pce_cd.current_frame ); pce_cd.end_mark = 1; break; //play with repeat |
| 1072 | 1072 | case 2: pce_cd_set_irq_line( machine, PCE_CD_IRQ_TRANSFER_DONE, ASSERT_LINE ); pce_cd.end_mark = 0; break; //irq when finished |
| 1073 | 1073 | case 3: pce_cd.end_mark = 0; break; //play without repeat |
| 1074 | 1074 | } |
| r22814 | r22815 | |
| 1178 | 1178 | if ( pce_cd.cd ) |
| 1179 | 1179 | { |
| 1180 | 1180 | pce_cd.toc = cdrom_get_toc( pce_cd.cd ); |
| 1181 | | cdda_set_cdrom( machine.device("cdda"), pce_cd.cd ); |
| 1181 | machine.device<cdda_device>("cdda")->set_cdrom( pce_cd.cd ); |
| 1182 | 1182 | pce_cd.last_frame = cdrom_get_track_start( pce_cd.cd, cdrom_get_last_track( pce_cd.cd ) - 1 ); |
| 1183 | 1183 | pce_cd.last_frame += pce_cd.toc->tracks[ cdrom_get_last_track( pce_cd.cd ) - 1 ].frames; |
| 1184 | 1184 | pce_cd.end_frame = pce_cd.last_frame; |
| r22814 | r22815 | |
| 1234 | 1234 | if(pce_cd.cdda_volume <= 0) |
| 1235 | 1235 | { |
| 1236 | 1236 | pce_cd.cdda_volume = 0.0; |
| 1237 | | cdda_set_volume(machine().device("cdda"), 0.0); |
| 1237 | machine().device<cdda_device>("cdda")->set_volume(0.0); |
| 1238 | 1238 | pce_cd.cdda_fadeout_timer->adjust(attotime::never); |
| 1239 | 1239 | } |
| 1240 | 1240 | else |
| 1241 | 1241 | { |
| 1242 | | cdda_set_volume(machine().device("cdda"), pce_cd.cdda_volume); |
| 1242 | machine().device<cdda_device>("cdda")->set_volume(pce_cd.cdda_volume); |
| 1243 | 1243 | pce_cd.cdda_fadeout_timer->adjust(attotime::from_usec(param), param); |
| 1244 | 1244 | } |
| 1245 | 1245 | } |
| r22814 | r22815 | |
| 1252 | 1252 | if(pce_cd.cdda_volume >= 100.0) |
| 1253 | 1253 | { |
| 1254 | 1254 | pce_cd.cdda_volume = 100.0; |
| 1255 | | cdda_set_volume(machine().device("cdda"), 100.0); |
| 1255 | machine().device<cdda_device>("cdda")->set_volume(100.0); |
| 1256 | 1256 | pce_cd.cdda_fadein_timer->adjust(attotime::never); |
| 1257 | 1257 | } |
| 1258 | 1258 | else |
| 1259 | 1259 | { |
| 1260 | | cdda_set_volume(machine().device("cdda"), pce_cd.cdda_volume); |
| 1260 | machine().device<cdda_device>("cdda")->set_volume(pce_cd.cdda_volume); |
| 1261 | 1261 | pce_cd.cdda_fadein_timer->adjust(attotime::from_usec(param), param); |
| 1262 | 1262 | } |
| 1263 | 1263 | } |
| r22814 | r22815 | |
| 1599 | 1599 | case 0x04: /* CD reset */ |
| 1600 | 1600 | break; |
| 1601 | 1601 | case 0x05: /* Convert PCM data / PCM data */ |
| 1602 | | data = cdda_get_channel_volume(machine().device( "cdda" ),(pce_cd.regs[0x03] & 2) ? 0 : 1) & 0xff; |
| 1602 | data = machine().device<cdda_device>("cdda")->get_channel_volume((pce_cd.regs[0x03] & 2) ? 0 : 1) & 0xff; |
| 1603 | 1603 | break; |
| 1604 | 1604 | case 0x06: /* PCM data */ |
| 1605 | | data = cdda_get_channel_volume(machine().device( "cdda" ),(pce_cd.regs[0x03] & 2) ? 0 : 1) >> 8; |
| 1605 | data = machine().device<cdda_device>("cdda")->get_channel_volume((pce_cd.regs[0x03] & 2) ? 0 : 1) >> 8; |
| 1606 | 1606 | break; |
| 1607 | 1607 | case 0x07: /* BRAM unlock / CD status */ |
| 1608 | 1608 | data = ( pce_cd.bram_locked ? ( data & 0x7F ) : ( data | 0x80 ) ); |
trunk/src/mess/drivers/fmtowns.c
| r22814 | r22815 | |
| 1381 | 1381 | UINT8 towns_state::towns_cd_get_track() |
| 1382 | 1382 | { |
| 1383 | 1383 | cdrom_image_device* cdrom = m_cdrom; |
| 1384 | | device_t* cdda = m_cdda; |
| 1385 | | UINT32 lba = cdda_get_audio_lba(cdda); |
| 1384 | UINT32 lba = m_cdda->get_audio_lba(); |
| 1386 | 1385 | UINT8 track; |
| 1387 | 1386 | |
| 1388 | 1387 | for(track=1;track<99;track++) |
| r22814 | r22815 | |
| 1566 | 1565 | m_towns_cd.cdda_current = msf_to_lbafm(lba1); |
| 1567 | 1566 | m_towns_cd.cdda_length = msf_to_lbafm(lba2) - m_towns_cd.cdda_current; |
| 1568 | 1567 | |
| 1569 | | cdda_set_cdrom(m_cdda,device->get_cdrom_file()); |
| 1570 | | cdda_start_audio(m_cdda,m_towns_cd.cdda_current,m_towns_cd.cdda_length); |
| 1568 | m_cdda->set_cdrom(device->get_cdrom_file()); |
| 1569 | m_cdda->start_audio(m_towns_cd.cdda_current,m_towns_cd.cdda_length); |
| 1571 | 1570 | logerror("CD: CD-DA start from LBA:%i length:%i\n",m_towns_cd.cdda_current,m_towns_cd.cdda_length); |
| 1572 | 1571 | if(m_towns_cd.command & 0x20) |
| 1573 | 1572 | { |
| r22814 | r22815 | |
| 1636 | 1635 | if(m_towns_cd.command & 0x20) |
| 1637 | 1636 | { |
| 1638 | 1637 | m_towns_cd.extra_status = 0; |
| 1639 | | if(cdda_audio_active(m_cdda) && !cdda_audio_paused(m_cdda)) |
| 1638 | if(m_cdda->audio_active() && !m_cdda->audio_paused()) |
| 1640 | 1639 | towns_cd_set_status(0x00,0x03,0x00,0x00); |
| 1641 | 1640 | else |
| 1642 | 1641 | towns_cd_set_status(0x00,0x01,0x00,0x00); |
| r22814 | r22815 | |
| 1657 | 1656 | m_towns_cd.extra_status = 1; |
| 1658 | 1657 | towns_cd_set_status(0x00,0x00,0x00,0x00); |
| 1659 | 1658 | } |
| 1660 | | cdda_pause_audio(m_cdda,1); |
| 1659 | m_cdda->pause_audio(1); |
| 1661 | 1660 | logerror("CD: Command 0x84: STOP CD-DA\n"); |
| 1662 | 1661 | break; |
| 1663 | 1662 | case 0x85: // Stop CD audio track (difference from 0x84?) |
| r22814 | r22815 | |
| 1666 | 1665 | m_towns_cd.extra_status = 1; |
| 1667 | 1666 | towns_cd_set_status(0x00,0x00,0x00,0x00); |
| 1668 | 1667 | } |
| 1669 | | cdda_pause_audio(m_cdda,1); |
| 1668 | m_cdda->pause_audio(1); |
| 1670 | 1669 | logerror("CD: Command 0x85: STOP CD-DA\n"); |
| 1671 | 1670 | break; |
| 1672 | 1671 | case 0x87: // Resume CD-DA playback |
| r22814 | r22815 | |
| 1675 | 1674 | m_towns_cd.extra_status = 1; |
| 1676 | 1675 | towns_cd_set_status(0x00,0x03,0x00,0x00); |
| 1677 | 1676 | } |
| 1678 | | cdda_pause_audio(m_cdda,0); |
| 1677 | m_cdda->pause_audio(0); |
| 1679 | 1678 | logerror("CD: Command 0x87: RESUME CD-DA\n"); |
| 1680 | 1679 | break; |
| 1681 | 1680 | default: |
| r22814 | r22815 | |
| 1792 | 1791 | m_towns_cd.extra_status++; |
| 1793 | 1792 | break; |
| 1794 | 1793 | case 2: // st0/1/2 = MSF from beginning of current track |
| 1795 | | addr = cdda_get_audio_lba(m_cdda); |
| 1794 | addr = m_cdda->get_audio_lba(); |
| 1796 | 1795 | addr = lba_to_msf(addr - m_towns_cd.cdda_current); |
| 1797 | 1796 | towns_cd_set_status(0x19, |
| 1798 | 1797 | (addr & 0xff0000) >> 16,(addr & 0x00ff00) >> 8,addr & 0x0000ff); |
| 1799 | 1798 | m_towns_cd.extra_status++; |
| 1800 | 1799 | break; |
| 1801 | 1800 | case 3: // st1/2 = current MSF |
| 1802 | | addr = cdda_get_audio_lba(m_cdda); |
| 1801 | addr = m_cdda->get_audio_lba(); |
| 1803 | 1802 | addr = lba_to_msf(addr); // this data is incorrect, but will do until exact meaning is found |
| 1804 | 1803 | towns_cd_set_status(0x19, |
| 1805 | 1804 | 0x00,(addr & 0xff0000) >> 16,(addr & 0x00ff00) >> 8); |
| 1806 | 1805 | m_towns_cd.extra_status++; |
| 1807 | 1806 | break; |
| 1808 | 1807 | case 4: |
| 1809 | | addr = cdda_get_audio_lba(m_cdda); |
| 1808 | addr = m_cdda->get_audio_lba(); |
| 1810 | 1809 | addr = lba_to_msf(addr); // this data is incorrect, but will do until exact meaning is found |
| 1811 | 1810 | towns_cd_set_status(0x20, |
| 1812 | 1811 | addr & 0x0000ff,0x00,0x00); |
| r22814 | r22815 | |
| 2030 | 2029 | case 2: |
| 2031 | 2030 | m_towns_volume[m_towns_volume_select] = data; |
| 2032 | 2031 | if(m_towns_volume_select == 4) |
| 2033 | | cdda_set_channel_volume(m_cdda,0,100.0 * (data / 64.0f)); |
| 2032 | m_cdda->set_channel_volume(0,100.0 * (data / 64.0f)); |
| 2034 | 2033 | if(m_towns_volume_select == 5) |
| 2035 | | cdda_set_channel_volume(m_cdda,1,100.0 * (data / 64.0f)); |
| 2034 | m_cdda->set_channel_volume(1,100.0 * (data / 64.0f)); |
| 2036 | 2035 | break; |
| 2037 | 2036 | case 3: // select channel |
| 2038 | 2037 | if(data < 8) |
| r22814 | r22815 | |
| 2616 | 2615 | m_pit = machine().device("pit"); |
| 2617 | 2616 | m_messram = m_ram; |
| 2618 | 2617 | m_cdrom = machine().device<cdrom_image_device>("cdrom"); |
| 2619 | | m_cdda = machine().device("cdda"); |
| 2618 | m_cdda = machine().device<cdda_device>("cdda"); |
| 2620 | 2619 | m_scsi = machine().device<fmscsi_device>("scsi:fm"); |
| 2621 | 2620 | m_ftimer = 0x00; |
| 2622 | 2621 | m_freerun_timer = 0x00; |