2017-05-30 03:38:38 +02:00
/*
2022-11-13 16:37:58 -05:00
* 86 Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus .
2017-05-30 03:38:38 +02:00
*
2022-11-13 16:37:58 -05:00
* This file is part of the 86 Box distribution .
2017-05-30 03:38:38 +02:00
*
2022-11-13 16:37:58 -05:00
* Generic CD - ROM drive core .
2017-05-30 03:38:38 +02:00
*
2017-10-08 19:14:46 -04:00
*
2022-11-13 16:37:58 -05:00
*
* Authors : Miran Grca , < mgrca8 @ gmail . com >
*
* Copyright 2018 - 2021 Miran Grca .
2017-05-30 03:38:38 +02:00
*/
2018-03-21 14:46:54 +01:00
# include <inttypes.h>
2018-05-21 19:04:05 +02:00
# include <stdarg.h>
2017-01-16 01:49:19 +01:00
# include <stdint.h>
2018-05-21 19:04:05 +02:00
# include <stdio.h>
2017-01-17 00:01:59 +01:00
# include <string.h>
2017-09-25 04:31:20 -04:00
# include <stdlib.h>
# include <wchar.h>
2017-12-10 19:36:41 +01:00
# define HAVE_STDARG_H
2020-03-29 14:24:42 +02:00
# include <86box/86box.h>
2023-01-07 23:48:45 +01:00
# include <86box/device.h>
2020-03-29 14:24:42 +02:00
# include <86box/config.h>
# include <86box/cdrom.h>
# include <86box/cdrom_image.h>
2023-01-07 23:48:45 +01:00
# include <86box/cdrom_interface.h>
# include <86box/cdrom_mitsumi.h>
2020-03-29 14:24:42 +02:00
# include <86box/plat.h>
2022-08-02 20:11:23 -04:00
# include <86box/scsi.h>
2020-06-14 21:59:45 +02:00
# include <86box/scsi_device.h>
2020-03-29 14:24:42 +02:00
# include <86box/sound.h>
2017-09-04 01:52:29 -04:00
2018-10-30 13:32:25 +01:00
/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong:
there is a seeming 2 seconds in which audio plays but counter does not move , while a data track before audio jumps to 2 seconds before the actual start
of the audio while audio still plays . With an absolute conversion , the counter is fine . */
2020-06-14 21:59:45 +02:00
# undef MSFtoLBA
2022-09-18 17:11:56 -04:00
# define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f)
2018-10-30 13:32:25 +01:00
2022-09-18 17:11:56 -04:00
# define RAW_SECTOR_SIZE 2352
# define COOKED_SECTOR_SIZE 2048
2018-10-30 13:32:25 +01:00
2022-09-18 17:11:56 -04:00
# define MIN_SEEK 2000
# define MAX_SEEK 333333
2018-04-25 23:51:13 +02:00
2022-09-18 17:11:56 -04:00
# pragma pack(push, 1)
2018-10-30 13:32:25 +01:00
typedef struct {
uint8_t user_data [ 2048 ] ,
2022-09-18 17:11:56 -04:00
ecc [ 288 ] ;
2018-10-30 13:32:25 +01:00
} m1_data_t ;
typedef struct {
uint8_t sub_header [ 8 ] ,
2022-09-18 17:11:56 -04:00
user_data [ 2328 ] ;
2018-10-30 13:32:25 +01:00
} m2_data_t ;
typedef union {
m1_data_t m1_data ;
m2_data_t m2_data ;
2022-09-18 17:11:56 -04:00
uint8_t raw_data [ 2336 ] ;
2018-10-30 13:32:25 +01:00
} sector_data_t ;
typedef struct {
2022-09-18 17:11:56 -04:00
uint8_t sync [ 12 ] ;
uint8_t header [ 4 ] ;
2018-10-30 13:32:25 +01:00
sector_data_t data ;
} sector_raw_data_t ;
typedef union {
sector_raw_data_t sector_data ;
2022-09-18 17:11:56 -04:00
uint8_t raw_data [ 2352 ] ;
2018-10-30 13:32:25 +01:00
} sector_t ;
typedef struct {
sector_t sector ;
2022-09-18 17:11:56 -04:00
uint8_t c2 [ 296 ] ;
uint8_t subchannel_raw [ 96 ] ;
uint8_t subchannel_q [ 16 ] ;
uint8_t subchannel_rw [ 96 ] ;
2018-10-30 13:32:25 +01:00
} cdrom_sector_t ;
typedef union {
cdrom_sector_t cdrom_sector ;
2022-09-18 17:11:56 -04:00
uint8_t buffer [ 2856 ] ;
2018-10-30 13:32:25 +01:00
} sector_buffer_t ;
# pragma pack(pop)
2022-09-18 17:11:56 -04:00
static int cdrom_sector_size ;
static uint8_t raw_buffer [ 2856 ] ; /* Needs to be the same size as sector_buffer_t in the structs. */
static uint8_t extra_buffer [ 296 ] ;
2018-10-30 13:32:25 +01:00
2022-09-18 17:11:56 -04:00
cdrom_t cdrom [ CDROM_NUM ] ;
2017-01-16 01:49:19 +01:00
2023-01-07 23:48:45 +01:00
int cdrom_interface_current ;
2017-10-16 06:19:18 +02:00
# ifdef ENABLE_CDROM_LOG
2022-09-18 17:11:56 -04:00
int cdrom_do_log = ENABLE_CDROM_LOG ;
2017-11-24 02:23:00 -05:00
2018-10-17 05:29:48 +02:00
void
cdrom_log ( const char * fmt , . . . )
2017-01-16 01:49:19 +01:00
{
2018-04-25 23:51:13 +02:00
va_list ap ;
2017-12-05 23:35:35 +01:00
2018-04-25 23:51:13 +02:00
if ( cdrom_do_log ) {
2022-02-22 22:04:40 +01:00
va_start ( ap , fmt ) ;
pclog_ex ( fmt , ap ) ;
va_end ( ap ) ;
2018-04-25 23:51:13 +02:00
}
2017-01-16 01:49:19 +01:00
}
2018-10-17 05:29:48 +02:00
# else
2022-09-18 17:11:56 -04:00
# define cdrom_log(fmt, ...)
2018-10-17 05:29:48 +02:00
# endif
2017-01-16 01:49:19 +01:00
2023-01-07 23:48:45 +01:00
static const device_t cdrom_interface_none_device = {
. name = " None " ,
. internal_name = " none " ,
. flags = 0 ,
. local = 0 ,
. init = NULL ,
. close = NULL ,
. reset = NULL ,
{ . available = NULL } ,
. speed_changed = NULL ,
. force_redraw = NULL ,
. config = NULL
} ;
static const struct {
const device_t * device ;
} controllers [ ] = {
// clang-format off
{ & cdrom_interface_none_device } ,
{ NULL }
// clang-format on
} ;
/* Reset the CD-ROM Interface, whichever one that is. */
void
cdrom_interface_reset ( void )
{
cdrom_log ( " CD-ROM Interface: reset(current=%d) \n " ,
cdrom_interface_current ) ;
/* If we have a valid controller, add its device. */
2023-10-14 06:45:45 +02:00
if ( ( cdrom_interface_current > 0 ) & & controllers [ cdrom_interface_current ] . device )
device_add ( controllers [ cdrom_interface_current ] . device ) ;
2023-01-07 23:48:45 +01:00
}
2023-08-21 20:22:09 -04:00
const char *
2023-01-07 23:48:45 +01:00
cdrom_interface_get_internal_name ( int cdinterface )
{
return device_get_internal_name ( controllers [ cdinterface ] . device ) ;
}
int
cdrom_interface_get_from_internal_name ( char * s )
{
int c = 0 ;
while ( controllers [ c ] . device ! = NULL ) {
2023-06-09 23:46:54 -04:00
if ( ! strcmp ( controllers [ c ] . device - > internal_name , s ) )
2023-01-07 23:48:45 +01:00
return c ;
c + + ;
}
return 0 ;
}
const device_t *
cdrom_interface_get_device ( int cdinterface )
{
return ( controllers [ cdinterface ] . device ) ;
}
int
cdrom_interface_has_config ( int cdinterface )
{
const device_t * dev = cdrom_interface_get_device ( cdinterface ) ;
if ( dev = = NULL )
2023-05-16 15:43:20 -04:00
return 0 ;
2023-01-07 23:48:45 +01:00
if ( ! device_has_config ( dev ) )
2023-05-16 15:43:20 -04:00
return 0 ;
2023-01-07 23:48:45 +01:00
2023-05-16 15:43:20 -04:00
return 1 ;
2023-01-07 23:48:45 +01:00
}
int
cdrom_interface_get_flags ( int cdinterface )
{
return ( controllers [ cdinterface ] . device - > flags ) ;
}
int
cdrom_interface_available ( int cdinterface )
{
return ( device_available ( controllers [ cdinterface ] . device ) ) ;
}
char *
cdrom_getname ( int type )
{
return ( char * ) cdrom_drive_types [ type ] . name ;
}
char *
cdrom_get_internal_name ( int type )
{
return ( char * ) cdrom_drive_types [ type ] . internal_name ;
}
int
cdrom_get_from_internal_name ( char * s )
{
int c = 0 ;
while ( strlen ( cdrom_drive_types [ c ] . internal_name ) ) {
if ( ! strcmp ( ( char * ) cdrom_drive_types [ c ] . internal_name , s ) )
return c ;
c + + ;
}
return 0 ;
}
void
cdrom_set_type ( int model , int type )
{
cdrom [ model ] . type = type ;
}
int
cdrom_get_type ( int model )
{
return cdrom [ model ] . type ;
}
static __inline int
bin2bcd ( int x )
{
return ( x % 10 ) | ( ( x / 10 ) < < 4 ) ;
}
static __inline int
bcd2bin ( int x )
{
return ( x > > 4 ) * 10 + ( x & 0x0f ) ;
}
2018-04-25 23:51:13 +02:00
int
cdrom_lba_to_msf_accurate ( int lba )
2017-01-16 01:49:19 +01:00
{
2018-10-17 05:29:48 +02:00
int pos ;
2023-05-16 15:43:20 -04:00
int m ;
int s ;
int f ;
2018-04-25 23:51:13 +02:00
2018-10-17 05:29:48 +02:00
pos = lba + 150 ;
2022-09-18 17:11:56 -04:00
f = pos % 75 ;
2018-10-17 05:29:48 +02:00
pos - = f ;
pos / = 75 ;
s = pos % 60 ;
pos - = s ;
pos / = 60 ;
m = pos ;
2018-04-25 23:51:13 +02:00
return ( ( m < < 16 ) | ( s < < 8 ) | f ) ;
2017-01-16 01:49:19 +01:00
}
2018-10-17 05:29:48 +02:00
static double
cdrom_get_short_seek ( cdrom_t * dev )
2018-04-25 23:51:13 +02:00
{
2022-09-18 17:11:56 -04:00
switch ( dev - > cur_speed ) {
2022-02-22 22:04:40 +01:00
case 0 :
fatal ( " CD-ROM %i: 0x speed \n " , dev - > id ) ;
return 0.0 ;
case 1 :
return 240.0 ;
case 2 :
return 160.0 ;
case 3 :
return 150.0 ;
2022-09-18 17:11:56 -04:00
case 4 :
case 5 :
case 6 :
case 7 :
case 8 :
case 9 :
case 10 :
case 11 :
2022-02-22 22:04:40 +01:00
return 112.0 ;
2022-09-18 17:11:56 -04:00
case 12 :
case 13 :
case 14 :
case 15 :
2022-02-22 22:04:40 +01:00
return 75.0 ;
2022-09-18 17:11:56 -04:00
case 16 :
case 17 :
case 18 :
case 19 :
2022-02-22 22:04:40 +01:00
return 58.0 ;
2022-09-18 17:11:56 -04:00
case 20 :
case 21 :
case 22 :
case 23 :
case 40 :
case 41 :
case 42 :
case 43 :
case 44 :
case 45 :
case 46 :
case 47 :
2022-02-22 22:04:40 +01:00
case 48 :
return 50.0 ;
default :
/* 24-32, 52+ */
return 45.0 ;
2018-04-25 23:51:13 +02:00
}
2018-03-17 20:32:20 +01:00
}
2018-10-17 05:29:48 +02:00
static double
cdrom_get_long_seek ( cdrom_t * dev )
2018-04-25 23:51:13 +02:00
{
2022-09-18 17:11:56 -04:00
switch ( dev - > cur_speed ) {
2022-02-22 22:04:40 +01:00
case 0 :
fatal ( " CD-ROM %i: 0x speed \n " , dev - > id ) ;
return 0.0 ;
case 1 :
return 1446.0 ;
case 2 :
return 1000.0 ;
case 3 :
return 900.0 ;
2022-09-18 17:11:56 -04:00
case 4 :
case 5 :
case 6 :
case 7 :
case 8 :
case 9 :
case 10 :
case 11 :
2022-02-22 22:04:40 +01:00
return 675.0 ;
2022-09-18 17:11:56 -04:00
case 12 :
case 13 :
case 14 :
case 15 :
2022-02-22 22:04:40 +01:00
return 400.0 ;
2022-09-18 17:11:56 -04:00
case 16 :
case 17 :
case 18 :
case 19 :
2022-02-22 22:04:40 +01:00
return 350.0 ;
2022-09-18 17:11:56 -04:00
case 20 :
case 21 :
case 22 :
case 23 :
case 40 :
case 41 :
case 42 :
case 43 :
case 44 :
case 45 :
case 46 :
case 47 :
2022-02-22 22:04:40 +01:00
case 48 :
return 300.0 ;
default :
/* 24-32, 52+ */
return 270.0 ;
2018-04-25 23:51:13 +02:00
}
2018-03-17 20:32:20 +01:00
}
2018-10-10 22:33:24 +02:00
double
2018-10-17 05:29:48 +02:00
cdrom_seek_time ( cdrom_t * dev )
2018-03-17 20:32:20 +01:00
{
2018-04-25 23:51:13 +02:00
uint32_t diff = dev - > seek_diff ;
2022-09-18 17:11:56 -04:00
double sd = ( double ) ( MAX_SEEK - MIN_SEEK ) ;
2018-03-17 20:32:20 +01:00
2018-04-25 23:51:13 +02:00
if ( diff < MIN_SEEK )
2022-02-22 22:04:40 +01:00
return 0.0 ;
2018-04-25 23:51:13 +02:00
if ( diff > MAX_SEEK )
2022-02-22 22:04:40 +01:00
diff = MAX_SEEK ;
2018-03-17 20:32:20 +01:00
2018-04-25 23:51:13 +02:00
diff - = MIN_SEEK ;
2018-03-17 20:32:20 +01:00
2018-04-25 23:51:13 +02:00
return cdrom_get_short_seek ( dev ) + ( ( cdrom_get_long_seek ( dev ) * ( ( double ) diff ) ) / sd ) ;
2018-03-17 20:32:20 +01:00
}
2018-10-30 13:32:25 +01:00
void
cdrom_stop ( cdrom_t * dev )
{
if ( dev - > cd_status > CD_STATUS_DATA_ONLY )
2022-02-22 22:04:40 +01:00
dev - > cd_status = CD_STATUS_STOPPED ;
2018-10-30 13:32:25 +01:00
}
2018-10-10 22:33:24 +02:00
void
2023-01-07 23:48:45 +01:00
cdrom_seek ( cdrom_t * dev , uint32_t pos , uint8_t vendor_type )
2018-04-25 23:51:13 +02:00
{
2023-05-16 15:43:20 -04:00
int m ;
int s ;
int f ;
2023-01-07 23:48:45 +01:00
2018-10-11 10:34:12 +02:00
if ( ! dev )
2022-02-22 22:04:40 +01:00
return ;
2018-10-11 10:34:12 +02:00
2023-01-07 23:48:45 +01:00
cdrom_log ( " CD-ROM %i: Seek to LBA %08X, vendor type = %02x. \n " , dev - > id , pos , vendor_type ) ;
switch ( vendor_type ) {
case 0x40 :
m = bcd2bin ( ( pos > > 24 ) & 0xff ) ;
s = bcd2bin ( ( pos > > 16 ) & 0xff ) ;
f = bcd2bin ( ( pos > > 8 ) & 0xff ) ;
pos = MSFtoLBA ( m , s , f ) - 150 ;
break ;
case 0x80 :
pos = bcd2bin ( ( pos > > 24 ) & 0xff ) ;
break ;
2023-06-26 12:47:04 -04:00
default :
break ;
2023-01-07 23:48:45 +01:00
}
2018-10-30 13:32:25 +01:00
2022-09-18 17:11:56 -04:00
dev - > seek_pos = pos ;
2018-10-30 13:32:25 +01:00
cdrom_stop ( dev ) ;
2017-01-16 01:49:19 +01:00
}
2021-09-02 20:52:30 +02:00
int
cdrom_is_pre ( cdrom_t * dev , uint32_t lba )
{
if ( dev - > ops & & dev - > ops - > is_track_pre )
2022-02-22 22:04:40 +01:00
return dev - > ops - > is_track_pre ( dev , lba ) ;
2021-09-02 20:52:30 +02:00
return 0 ;
}
2018-10-10 22:33:24 +02:00
int
2018-10-30 13:32:25 +01:00
cdrom_audio_callback ( cdrom_t * dev , int16_t * output , int len )
2018-04-25 23:51:13 +02:00
{
2018-10-30 13:32:25 +01:00
int ret = 1 ;
2024-02-06 21:18:25 +01:00
if ( ! dev - > sound_on | | ( dev - > cd_status ! = CD_STATUS_PLAYING ) | | dev - > audio_muted_soft ) {
2022-02-22 22:04:40 +01:00
cdrom_log ( " CD-ROM %i: Audio callback while not playing \n " , dev - > id ) ;
if ( dev - > cd_status = = CD_STATUS_PLAYING )
dev - > seek_pos + = ( len > > 11 ) ;
memset ( output , 0 , len * 2 ) ;
return 0 ;
2018-10-30 13:32:25 +01:00
}
while ( dev - > cd_buflen < len ) {
2022-02-22 22:04:40 +01:00
if ( dev - > seek_pos < dev - > cd_end ) {
if ( dev - > ops - > read_sector ( dev , CD_READ_AUDIO , ( uint8_t * ) & ( dev - > cd_buffer [ dev - > cd_buflen ] ) ,
dev - > seek_pos ) ) {
cdrom_log ( " CD-ROM %i: Read LBA %08X successful \n " , dev - > id , dev - > seek_pos ) ;
dev - > seek_pos + + ;
dev - > cd_buflen + = ( RAW_SECTOR_SIZE / 2 ) ;
ret = 1 ;
} else {
cdrom_log ( " CD-ROM %i: Read LBA %08X failed \n " , dev - > id , dev - > seek_pos ) ;
memset ( & ( dev - > cd_buffer [ dev - > cd_buflen ] ) , 0x00 , ( BUF_SIZE - dev - > cd_buflen ) * 2 ) ;
dev - > cd_status = CD_STATUS_STOPPED ;
dev - > cd_buflen = len ;
2022-09-18 17:11:56 -04:00
ret = 0 ;
2022-02-22 22:04:40 +01:00
}
} else {
cdrom_log ( " CD-ROM %i: Playing completed \n " , dev - > id ) ;
memset ( & dev - > cd_buffer [ dev - > cd_buflen ] , 0x00 , ( BUF_SIZE - dev - > cd_buflen ) * 2 ) ;
dev - > cd_status = CD_STATUS_PLAYING_COMPLETED ;
dev - > cd_buflen = len ;
2022-09-18 17:11:56 -04:00
ret = 0 ;
2022-02-22 22:04:40 +01:00
}
2018-10-30 13:32:25 +01:00
}
memcpy ( output , dev - > cd_buffer , len * 2 ) ;
memmove ( dev - > cd_buffer , & dev - > cd_buffer [ len ] , ( BUF_SIZE - len ) * 2 ) ;
dev - > cd_buflen - = len ;
cdrom_log ( " CD-ROM %i: Audio callback returning %i \n " , dev - > id , ret ) ;
return ret ;
}
2022-10-29 06:44:30 +02:00
static void
msf_from_bcd ( int * m , int * s , int * f )
{
* m = bcd2bin ( * m ) ;
* s = bcd2bin ( * s ) ;
* f = bcd2bin ( * f ) ;
}
static void
msf_to_bcd ( int * m , int * s , int * f )
{
* m = bin2bcd ( * m ) ;
* s = bin2bcd ( * s ) ;
* f = bin2bcd ( * f ) ;
}
2018-10-30 13:32:25 +01:00
uint8_t
cdrom_audio_play ( cdrom_t * dev , uint32_t pos , uint32_t len , int ismsf )
{
track_info_t ti ;
2023-05-16 15:43:20 -04:00
int m = 0 ;
int s = 0 ;
int f = 0 ;
2018-10-30 13:32:25 +01:00
if ( dev - > cd_status = = CD_STATUS_DATA_ONLY )
2022-02-22 22:04:40 +01:00
return 0 ;
2018-10-30 13:32:25 +01:00
cdrom_log ( " CD-ROM %i: Play audio - %08X %08X %i \n " , dev - > id , pos , len , ismsf ) ;
2018-10-30 16:42:43 +01:00
if ( ismsf & 0x100 ) {
2022-02-22 22:04:40 +01:00
/* Track-relative audio play. */
dev - > ops - > get_track_info ( dev , ismsf & 0xff , 0 , & ti ) ;
pos + = MSFtoLBA ( ti . m , ti . s , ti . f ) - 150 ;
2023-01-07 23:48:45 +01:00
} else if ( ( ismsf = = 2 ) | | ( ismsf = = 3 ) ) {
2022-02-22 22:04:40 +01:00
dev - > ops - > get_track_info ( dev , pos , 0 , & ti ) ;
pos = MSFtoLBA ( ti . m , ti . s , ti . f ) - 150 ;
2023-01-07 23:48:45 +01:00
if ( ismsf = = 2 ) {
/* We have to end at the *end* of the specified track,
not at the beginning . */
dev - > ops - > get_track_info ( dev , len , 1 , & ti ) ;
len = MSFtoLBA ( ti . m , ti . s , ti . f ) - 150 ;
}
2018-10-30 13:32:25 +01:00
} else if ( ismsf = = 1 ) {
2022-02-22 22:04:40 +01:00
m = ( pos > > 16 ) & 0xff ;
s = ( pos > > 8 ) & 0xff ;
f = pos & 0xff ;
2022-10-29 06:44:30 +02:00
/* NEC CDR-260 speaks BCD. */
2023-09-24 07:44:25 +02:00
if ( ( dev - > type = = CDROM_TYPE_NEC_260_100 ) | | ( dev - > type = = CDROM_TYPE_NEC_260_101 ) ) /*NEC*/
2022-10-29 06:44:30 +02:00
msf_from_bcd ( & m , & s , & f ) ;
2022-02-22 22:04:40 +01:00
if ( pos = = 0xffffff ) {
cdrom_log ( " CD-ROM %i: Playing from current position (MSF) \n " , dev - > id ) ;
pos = dev - > seek_pos ;
} else
pos = MSFtoLBA ( m , s , f ) - 150 ;
2022-11-05 20:15:00 -04:00
m = ( len > > 16 ) & 0xff ;
s = ( len > > 8 ) & 0xff ;
f = len & 0xff ;
2022-10-29 06:44:30 +02:00
/* NEC CDR-260 speaks BCD. */
2023-09-24 07:44:25 +02:00
if ( ( dev - > type = = CDROM_TYPE_NEC_260_100 ) | | ( dev - > type = = CDROM_TYPE_NEC_260_101 ) ) /*NEC*/
2022-10-29 06:44:30 +02:00
msf_from_bcd ( & m , & s , & f ) ;
2022-02-22 22:04:40 +01:00
len = MSFtoLBA ( m , s , f ) - 150 ;
cdrom_log ( " CD-ROM %i: MSF - pos = %08X len = %08X \n " , dev - > id , pos , len ) ;
2018-10-30 13:32:25 +01:00
} else if ( ismsf = = 0 ) {
2022-02-22 22:04:40 +01:00
if ( pos = = 0xffffffff ) {
cdrom_log ( " CD-ROM %i: Playing from current position \n " , dev - > id ) ;
pos = dev - > seek_pos ;
}
len + = pos ;
2018-10-30 13:32:25 +01:00
}
2024-02-06 21:18:25 +01:00
dev - > audio_muted_soft = 0 ;
2018-10-30 13:32:25 +01:00
/* Do this at this point, since it's at this point that we know the
actual LBA position to start playing from . */
if ( ! ( dev - > ops - > track_type ( dev , pos ) & CD_TRACK_AUDIO ) ) {
2022-02-22 22:04:40 +01:00
cdrom_log ( " CD-ROM %i: LBA %08X not on an audio track \n " , dev - > id , pos ) ;
cdrom_stop ( dev ) ;
return 0 ;
2018-10-30 13:32:25 +01:00
}
2022-09-18 17:11:56 -04:00
dev - > seek_pos = pos ;
dev - > cd_end = len ;
2018-10-30 13:32:25 +01:00
dev - > cd_status = CD_STATUS_PLAYING ;
dev - > cd_buflen = 0 ;
return 1 ;
}
2020-03-24 01:00:28 +01:00
uint8_t
cdrom_audio_track_search ( cdrom_t * dev , uint32_t pos , int type , uint8_t playbit )
{
2023-05-16 15:43:20 -04:00
int m = 0 ;
int s = 0 ;
int f = 0 ;
2024-02-06 21:18:25 +01:00
uint32_t pos2 = 0 ;
2022-02-20 02:26:27 -05:00
2020-03-24 01:00:28 +01:00
if ( dev - > cd_status = = CD_STATUS_DATA_ONLY )
2022-02-22 22:04:40 +01:00
return 0 ;
2022-02-20 02:26:27 -05:00
2022-12-04 20:53:03 +01:00
cdrom_log ( " Audio Track Search: MSF = %06x, type = %02x, playbit = %02x \n " , pos , type , playbit ) ;
2020-03-24 01:00:28 +01:00
switch ( type ) {
2022-12-04 20:53:03 +01:00
case 0x00 :
if ( pos = = 0xffffffff ) {
2023-01-07 23:48:45 +01:00
cdrom_log ( " CD-ROM %i: (type 0) Search from current position \n " , dev - > id ) ;
2022-12-04 20:53:03 +01:00
pos = dev - > seek_pos ;
}
2023-01-07 23:48:45 +01:00
dev - > seek_pos = pos ;
2022-12-04 20:53:03 +01:00
break ;
2022-02-22 22:04:40 +01:00
case 0x40 :
2023-01-07 23:48:45 +01:00
m = bcd2bin ( ( pos > > 24 ) & 0xff ) ;
s = bcd2bin ( ( pos > > 16 ) & 0xff ) ;
f = bcd2bin ( ( pos > > 8 ) & 0xff ) ;
2022-12-04 20:53:03 +01:00
if ( pos = = 0xffffffff ) {
2023-01-07 23:48:45 +01:00
cdrom_log ( " CD-ROM %i: (type 1) Search from current position \n " , dev - > id ) ;
2022-12-04 20:53:03 +01:00
pos = dev - > seek_pos ;
} else
pos = MSFtoLBA ( m , s , f ) - 150 ;
2023-01-07 23:48:45 +01:00
dev - > seek_pos = pos ;
break ;
case 0x80 :
if ( pos = = 0xffffffff ) {
cdrom_log ( " CD-ROM %i: (type 2) Search from current position \n " , dev - > id ) ;
pos = dev - > seek_pos ;
}
dev - > seek_pos = ( pos > > 24 ) & 0xff ;
2022-02-22 22:04:40 +01:00
break ;
2023-06-26 12:47:04 -04:00
default :
break ;
2020-03-24 01:00:28 +01:00
}
2022-02-20 02:26:27 -05:00
2024-02-06 21:18:25 +01:00
pos2 = pos - 1 ;
if ( pos2 = = 0xffffffff )
pos2 = pos + 1 ;
2023-12-16 14:03:42 +01:00
/* Do this at this point, since it's at this point that we know the
actual LBA position to start playing from . */
2024-02-06 21:18:25 +01:00
if ( ! ( dev - > ops - > track_type ( dev , pos2 ) & CD_TRACK_AUDIO ) ) {
cdrom_log ( " CD-ROM %i: Track Search: LBA %08X not on an audio track \n " , dev - > id , pos ) ;
dev - > audio_muted_soft = 1 ;
if ( dev - > ops - > track_type ( dev , pos ) & CD_TRACK_AUDIO )
dev - > audio_muted_soft = 0 ;
} else
dev - > audio_muted_soft = 0 ;
2023-12-16 14:03:42 +01:00
2024-02-06 21:18:25 +01:00
cdrom_log ( " Track Search Toshiba: Muted?=%d, LBA=%08X. \n " , dev - > audio_muted_soft , pos ) ;
2022-12-04 20:53:03 +01:00
dev - > cd_buflen = 0 ;
2020-03-24 01:00:28 +01:00
dev - > cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED ;
return 1 ;
}
2023-09-20 20:29:32 +02:00
uint8_t
cdrom_audio_track_search_pioneer ( cdrom_t * dev , uint32_t pos , uint8_t playbit )
{
int m = 0 ;
int s = 0 ;
int f = 0 ;
if ( dev - > cd_status = = CD_STATUS_DATA_ONLY )
return 0 ;
f = bcd2bin ( ( pos > > 24 ) & 0xff ) ;
s = bcd2bin ( ( pos > > 16 ) & 0xff ) ;
m = bcd2bin ( ( pos > > 8 ) & 0xff ) ;
if ( pos = = 0xffffffff ) {
pos = dev - > seek_pos ;
} else
pos = MSFtoLBA ( m , s , f ) - 150 ;
dev - > seek_pos = pos ;
2024-02-06 21:18:25 +01:00
dev - > audio_muted_soft = 0 ;
2023-12-16 14:03:42 +01:00
/* Do this at this point, since it's at this point that we know the
actual LBA position to start playing from . */
if ( ! ( dev - > ops - > track_type ( dev , pos ) & CD_TRACK_AUDIO ) ) {
cdrom_log ( " CD-ROM %i: LBA %08X not on an audio track \n " , dev - > id , pos ) ;
cdrom_stop ( dev ) ;
return 0 ;
}
2023-09-20 20:29:32 +02:00
dev - > cd_buflen = 0 ;
dev - > cd_status = playbit ? CD_STATUS_PLAYING : CD_STATUS_PAUSED ;
return 1 ;
}
uint8_t
cdrom_audio_play_pioneer ( cdrom_t * dev , uint32_t pos )
{
int m = 0 ;
int s = 0 ;
int f = 0 ;
if ( dev - > cd_status = = CD_STATUS_DATA_ONLY )
return 0 ;
f = bcd2bin ( ( pos > > 24 ) & 0xff ) ;
s = bcd2bin ( ( pos > > 16 ) & 0xff ) ;
m = bcd2bin ( ( pos > > 8 ) & 0xff ) ;
pos = MSFtoLBA ( m , s , f ) - 150 ;
dev - > cd_end = pos ;
2024-02-06 21:18:25 +01:00
dev - > audio_muted_soft = 0 ;
2023-09-20 20:29:32 +02:00
dev - > cd_buflen = 0 ;
dev - > cd_status = CD_STATUS_PLAYING ;
return 1 ;
}
2022-02-20 02:26:27 -05:00
uint8_t
2023-01-07 23:48:45 +01:00
cdrom_audio_play_toshiba ( cdrom_t * dev , uint32_t pos , int type )
2020-03-24 01:00:28 +01:00
{
2023-05-16 15:43:20 -04:00
int m = 0 ;
int s = 0 ;
int f = 0 ;
2020-03-24 01:00:28 +01:00
if ( dev - > cd_status = = CD_STATUS_DATA_ONLY )
2022-02-22 22:04:40 +01:00
return 0 ;
2020-03-24 01:00:28 +01:00
/*Preliminary support, revert if too incomplete*/
switch ( type ) {
2023-01-07 23:48:45 +01:00
case 0x00 :
dev - > cd_end = pos ;
break ;
2022-02-22 22:04:40 +01:00
case 0x40 :
2023-01-07 23:48:45 +01:00
m = bcd2bin ( ( pos > > 24 ) & 0xff ) ;
s = bcd2bin ( ( pos > > 16 ) & 0xff ) ;
f = bcd2bin ( ( pos > > 8 ) & 0xff ) ;
2022-02-22 22:04:40 +01:00
pos = MSFtoLBA ( m , s , f ) - 150 ;
2023-01-07 23:48:45 +01:00
dev - > cd_end = pos ;
break ;
case 0x80 :
dev - > cd_end = ( pos > > 24 ) & 0xff ;
2022-02-22 22:04:40 +01:00
break ;
2022-12-04 20:53:03 +01:00
case 0xc0 :
if ( pos = = 0xffffffff ) {
cdrom_log ( " CD-ROM %i: Playing from current position \n " , dev - > id ) ;
pos = dev - > cd_end ;
}
2023-01-07 23:48:45 +01:00
dev - > cd_end = pos ;
2022-12-04 20:53:03 +01:00
break ;
2023-06-26 12:47:04 -04:00
default :
break ;
2020-03-24 01:00:28 +01:00
}
2022-02-20 02:26:27 -05:00
2024-02-06 21:18:25 +01:00
cdrom_log ( " Toshiba Play Audio: Muted?=%d, LBA=%08X. \n " , dev - > audio_muted_soft , pos ) ;
2020-03-24 01:00:28 +01:00
dev - > cd_buflen = 0 ;
2022-12-04 20:53:03 +01:00
dev - > cd_status = CD_STATUS_PLAYING ;
2020-03-24 01:00:28 +01:00
return 1 ;
}
2018-10-30 13:32:25 +01:00
2023-01-07 23:48:45 +01:00
uint8_t
cdrom_audio_scan ( cdrom_t * dev , uint32_t pos , int type )
{
2023-05-16 15:43:20 -04:00
int m = 0 ;
int s = 0 ;
int f = 0 ;
2023-01-07 23:48:45 +01:00
if ( dev - > cd_status = = CD_STATUS_DATA_ONLY )
return 0 ;
cdrom_log ( " Audio Scan: MSF = %06x, type = %02x \n " , pos , type ) ;
switch ( type ) {
case 0x00 :
if ( pos = = 0xffffffff ) {
cdrom_log ( " CD-ROM %i: (type 0) Search from current position \n " , dev - > id ) ;
pos = dev - > seek_pos ;
}
dev - > seek_pos = pos ;
break ;
case 0x40 :
m = bcd2bin ( ( pos > > 24 ) & 0xff ) ;
s = bcd2bin ( ( pos > > 16 ) & 0xff ) ;
f = bcd2bin ( ( pos > > 8 ) & 0xff ) ;
if ( pos = = 0xffffffff ) {
cdrom_log ( " CD-ROM %i: (type 1) Search from current position \n " , dev - > id ) ;
pos = dev - > seek_pos ;
} else
pos = MSFtoLBA ( m , s , f ) - 150 ;
dev - > seek_pos = pos ;
break ;
case 0x80 :
dev - > seek_pos = ( pos > > 24 ) & 0xff ;
break ;
2023-06-26 12:47:04 -04:00
default :
break ;
2023-01-07 23:48:45 +01:00
}
2024-02-06 21:18:25 +01:00
dev - > audio_muted_soft = 0 ;
2023-01-07 23:48:45 +01:00
/* Do this at this point, since it's at this point that we know the
actual LBA position to start playing from . */
if ( ! ( dev - > ops - > track_type ( dev , pos ) & CD_TRACK_AUDIO ) ) {
cdrom_log ( " CD-ROM %i: LBA %08X not on an audio track \n " , dev - > id , pos ) ;
cdrom_stop ( dev ) ;
return 0 ;
}
dev - > cd_buflen = 0 ;
return 1 ;
}
2018-10-30 13:32:25 +01:00
void
cdrom_audio_pause_resume ( cdrom_t * dev , uint8_t resume )
{
if ( ( dev - > cd_status = = CD_STATUS_PLAYING ) | | ( dev - > cd_status = = CD_STATUS_PAUSED ) )
2022-02-22 22:04:40 +01:00
dev - > cd_status = ( dev - > cd_status & 0xfe ) | ( resume & 0x01 ) ;
2018-10-30 13:32:25 +01:00
}
uint8_t
cdrom_get_current_subchannel ( cdrom_t * dev , uint8_t * b , int msf )
{
2022-09-18 17:11:56 -04:00
uint8_t ret ;
2018-10-30 13:32:25 +01:00
subchannel_t subc ;
2023-05-16 15:43:20 -04:00
int pos = 1 ;
int m ;
int s ;
int f ;
2022-09-18 17:11:56 -04:00
uint32_t dat ;
2018-10-30 13:32:25 +01:00
dev - > ops - > get_subchannel ( dev , dev - > seek_pos , & subc ) ;
if ( dev - > cd_status = = CD_STATUS_DATA_ONLY )
2022-02-22 22:04:40 +01:00
ret = 0x15 ;
2018-10-17 05:29:48 +02:00
else {
2022-02-22 22:04:40 +01:00
if ( dev - > cd_status = = CD_STATUS_PLAYING )
ret = 0x11 ;
else if ( dev - > cd_status = = CD_STATUS_PAUSED )
ret = 0x12 ;
else
ret = 0x13 ;
2018-10-30 13:32:25 +01:00
}
2023-09-20 20:29:32 +02:00
cdrom_log ( " CD-ROM %i: Returned subchannel absolute at %02i:%02i.%02i, relative at %02i:%02i.%02i, ret = %02x, seek pos = %08x, cd_end = %08x. \n " , dev - > id , subc . abs_m , subc . abs_s , subc . abs_f , subc . rel_m , subc . rel_s , subc . rel_f , ret , dev - > seek_pos , dev - > cd_end ) ;
2023-01-07 23:48:45 +01:00
if ( b [ pos ] > 1 ) {
cdrom_log ( " B[%i] = %02x, ret = %02x. \n " , pos , b [ pos ] , ret ) ;
2022-02-22 22:04:40 +01:00
return ret ;
2023-01-07 23:48:45 +01:00
}
Added the IBM 5161 ISA expansion for PC and XT;
Cleaned up the parallel port emulation, added IRQ support, and made enabling/disabling per port;
Added the Award 430NX and the Intel Classic/PCI (Alfredo, 420TX);
Finished the 586MC1;
Added 8087 emulation;
Moved Cyrix 6x86'es to the Dev branch;
Sanitized/cleaned up memregs.c/h and intel.c/h;
Split the chipsets from machines and sanitized Port 92 emulation;
Added support for the 15bpp mode to the Compaq ATI 28800;
Moved the MR 386DX and 486 machines to the Dev branch;
Ported the new dynamic recompiler from PCem, but it remains in Dev branch until after v2.00;
Ported the new timer code from PCem;
Cleaned up the CPU table of unused stuff and better optimized its structure;
Ported the Open-XT and Open-AT from VARCem, the Open-AT is in the Dev branch;
Ported the XT MFM controller rewrite and adding of more controllers (incl. two RLL ones), from VARCem;
Added the AHA-1540A and the BusTek BT-542B;
Moved the Sumo SCSI-AT to the Dev branch;
Minor IDE, FDC, and floppy drive code clean-ups;
Made NCR 5380/53C400-based cards' BIOS address configurable;
Got rid of the legacy romset variable;
Unified (video) buffer and buffer32 into one and make the unified buffer 32-bit;
Added the Amstead PPC512 per PCem patch by John Elliott;
Switched memory mapping granularity from 16k to 4k (less than 1k not possible due to internal pages);
Rewrote the CL-GD 54xx blitter, fixes Win-OS/2 on the 54x6 among other thing;
Added the Image Manager 1024 and Professional Graphics Controller per PCem patch by John Elliott and work done on VARCem;
Added Headland HT-216, GC-205 and Video 7 VGA 1024i emulation based on PCem commit;
Implemented the fuction keys for the Toshiba T1000/T1200/T3100 enhancement;
Amstrad MegaPC does now works correctly with non-internal graphics card;
The SLiRP code no longer casts a packed struct type to a non-packed struct type;
The Xi8088 and PB410a no longer hang on 86Box when PS/2 mouse is not present;
The S3 Virge on BeOS is no longer broken (was broken by build #1591);
OS/2 2.0 build 6.167 now sees key presses again;
Xi8088 now work on CGA again;
86F images converted from either the old or new variants of the HxC MFM format now work correctly;
Hardware interrupts with a vector of 0xFF are now handled correctly;
OPTi 495SX boards no longer incorrectly have 64 MB maximum RAM when 32 MB is correct;
Fixed VNC keyboard input bugs;
Fixed AT RTC periodic interrupt - Chicago 58s / 73f / 73g / 81 MIDI play no longer hangs with the build's own VTD driver;
Fixed mouse polling with internal mice - Amstrad and Olivetti mice now work correctly;
Triones ATAPI DMA driver now correctly reads a file at the end of a CD image with a sectors number not divisible by 4;
Compaq Portable now works with all graphics cards;
Fixed various MDSI Genius bugs;
Added segment limit checks and improved page fault checks for several CPU instructions - Memphis 15xx WINSETUP and Chicago 58s WINDISK.CPL no longer issue a GPF, and some S3 drivers that used to have glitches, now work correctly;
Further improved the 808x emulation, also fixes the noticably choppy sound when using 808x CPU's, also fixes #355;
OS/2 installer no logner locks up on splash screen on PS/2 Model 70 and 80, fixes #400.
Fixed several Amstead bugs, GEM no longer crashes on the Amstrad 1640, fixes #391.
Ported John Elliott's Amstrad fixes and improvement from PCem, and fixed the default language so it's correctly Engliish, fixes #278, fixes #389.
Fixed a minor IDE timing bug, fixes #388.
Fixed Toshiba T1000 RAM issues, fixes #379.
Fixed EGA/(S)VGA overscan border handling, fixes #378;
Got rid of the now long useless IDE channel 2 auto-removal, fixes #370;
Fixed the BIOS files used by the AMSTRAD PC1512, fixes #366;
Ported the Unicode CD image file name fix from VARCem, fixes #365;
Fixed high density floppy disks on the Xi8088, fixes #359;
Fixed some bugs in the Hercules emulation, fixes #346, fixes #358;
Fixed the SCSI hard disk mode sense pages, fixes #356;
Removed the AMI Unknown 386SX because of impossibility to identify the chipset, closes #349;
Fixed bugs in the serial mouse emulation, fixes #344;
Compiled 86Box binaries now include all the required .DLL's, fixes #341;
Made some combo boxes in the Settings dialog slightly wider, fixes #276.
2019-09-20 14:02:30 +02:00
2018-10-30 13:32:25 +01:00
b [ pos + + ] = subc . attr ;
b [ pos + + ] = subc . track ;
b [ pos + + ] = subc . index ;
if ( msf ) {
2022-11-05 20:15:00 -04:00
b [ pos ] = 0 ;
2022-10-29 06:44:30 +02:00
/* NEC CDR-260 speaks BCD. */
2023-09-24 07:44:25 +02:00
if ( ( dev - > type = = CDROM_TYPE_NEC_260_100 ) | | ( dev - > type = = CDROM_TYPE_NEC_260_101 ) ) { /*NEC*/
2022-10-29 06:44:30 +02:00
m = subc . abs_m ;
s = subc . abs_s ;
f = subc . abs_f ;
msf_to_bcd ( & m , & s , & f ) ;
b [ pos + 1 ] = m ;
b [ pos + 2 ] = s ;
b [ pos + 3 ] = f ;
} else {
b [ pos + 1 ] = subc . abs_m ;
b [ pos + 2 ] = subc . abs_s ;
b [ pos + 3 ] = subc . abs_f ;
}
2022-02-22 22:04:40 +01:00
pos + = 4 ;
2022-10-29 06:44:30 +02:00
2022-11-05 20:15:00 -04:00
b [ pos ] = 0 ;
2022-10-29 06:44:30 +02:00
/* NEC CDR-260 speaks BCD. */
2023-09-24 07:44:25 +02:00
if ( ( dev - > type = = CDROM_TYPE_NEC_260_100 ) | | ( dev - > type = = CDROM_TYPE_NEC_260_101 ) ) { /*NEC*/
2022-10-29 06:44:30 +02:00
m = subc . rel_m ;
s = subc . rel_s ;
f = subc . rel_f ;
msf_to_bcd ( & m , & s , & f ) ;
b [ pos + 1 ] = m ;
b [ pos + 2 ] = s ;
b [ pos + 3 ] = f ;
} else {
b [ pos + 1 ] = subc . rel_m ;
b [ pos + 2 ] = subc . rel_s ;
b [ pos + 3 ] = subc . rel_f ;
}
2022-02-22 22:04:40 +01:00
pos + = 4 ;
2018-10-30 13:32:25 +01:00
} else {
2022-09-18 17:11:56 -04:00
dat = MSFtoLBA ( subc . abs_m , subc . abs_s , subc . abs_f ) - 150 ;
2022-02-22 22:04:40 +01:00
b [ pos + + ] = ( dat > > 24 ) & 0xff ;
b [ pos + + ] = ( dat > > 16 ) & 0xff ;
b [ pos + + ] = ( dat > > 8 ) & 0xff ;
b [ pos + + ] = dat & 0xff ;
2022-09-18 17:11:56 -04:00
dat = MSFtoLBA ( subc . rel_m , subc . rel_s , subc . rel_f ) ;
2022-02-22 22:04:40 +01:00
b [ pos + + ] = ( dat > > 24 ) & 0xff ;
b [ pos + + ] = ( dat > > 16 ) & 0xff ;
b [ pos + + ] = ( dat > > 8 ) & 0xff ;
b [ pos + + ] = dat & 0xff ;
2018-10-30 13:32:25 +01:00
}
return ret ;
}
2023-01-07 23:48:45 +01:00
void
cdrom_get_current_subchannel_sony ( cdrom_t * dev , uint8_t * b , int msf )
{
subchannel_t subc ;
uint32_t dat ;
dev - > ops - > get_subchannel ( dev , dev - > seek_pos , & subc ) ;
2023-09-20 20:29:32 +02:00
cdrom_log ( " CD-ROM %i: Returned subchannel at %02i:%02i.%02i, seek pos = %08x, cd_end = %08x, msf = %x. \n " , dev - > id , subc . abs_m , subc . abs_s , subc . abs_f , dev - > seek_pos , dev - > cd_end , msf ) ;
2023-01-07 23:48:45 +01:00
2023-09-20 20:29:32 +02:00
b [ 0 ] = subc . attr ;
b [ 1 ] = subc . track ;
b [ 2 ] = subc . index ;
2023-01-07 23:48:45 +01:00
if ( msf ) {
2023-09-20 20:29:32 +02:00
b [ 3 ] = subc . rel_m ;
b [ 4 ] = subc . rel_s ;
b [ 5 ] = subc . rel_f ;
b [ 6 ] = subc . abs_m ;
b [ 7 ] = subc . abs_s ;
b [ 8 ] = subc . abs_f ;
2023-01-07 23:48:45 +01:00
} else {
dat = MSFtoLBA ( subc . rel_m , subc . rel_s , subc . rel_f ) ;
2023-09-20 20:29:32 +02:00
b [ 3 ] = ( dat > > 16 ) & 0xff ;
b [ 4 ] = ( dat > > 8 ) & 0xff ;
b [ 5 ] = dat & 0xff ;
2023-01-07 23:48:45 +01:00
dat = MSFtoLBA ( subc . abs_m , subc . abs_s , subc . abs_f ) - 150 ;
2023-09-20 20:29:32 +02:00
b [ 6 ] = ( dat > > 16 ) & 0xff ;
b [ 7 ] = ( dat > > 8 ) & 0xff ;
b [ 8 ] = dat & 0xff ;
2023-01-07 23:48:45 +01:00
}
}
2023-09-20 20:29:32 +02:00
uint8_t
cdrom_get_audio_status_pioneer ( cdrom_t * dev , uint8_t * b )
{
uint8_t ret ;
subchannel_t subc ;
dev - > ops - > get_subchannel ( dev , dev - > seek_pos , & subc ) ;
if ( dev - > cd_status = = CD_STATUS_DATA_ONLY )
ret = 0x05 ;
else {
if ( dev - > cd_status = = CD_STATUS_PLAYING )
ret = dev - > sound_on ? 0x00 : 0x02 ;
else if ( dev - > cd_status = = CD_STATUS_PAUSED )
ret = 0x01 ;
else
ret = 0x03 ;
}
b [ 0 ] = 0 ;
b [ 1 ] = bin2bcd ( subc . abs_m ) ;
b [ 2 ] = bin2bcd ( subc . abs_s ) ;
b [ 3 ] = bin2bcd ( subc . abs_f ) ;
return ret ;
}
2023-01-07 23:48:45 +01:00
uint8_t
cdrom_get_audio_status_sony ( cdrom_t * dev , uint8_t * b , int msf )
{
uint8_t ret ;
subchannel_t subc ;
uint32_t dat ;
dev - > ops - > get_subchannel ( dev , dev - > seek_pos , & subc ) ;
if ( dev - > cd_status = = CD_STATUS_DATA_ONLY )
ret = 0x05 ;
else {
if ( dev - > cd_status = = CD_STATUS_PLAYING )
ret = dev - > sound_on ? 0x00 : 0x02 ;
else if ( dev - > cd_status = = CD_STATUS_PAUSED )
ret = 0x01 ;
else
ret = 0x03 ;
}
if ( msf ) {
b [ 0 ] = 0 ;
b [ 1 ] = subc . abs_m ;
b [ 2 ] = subc . abs_s ;
b [ 3 ] = subc . abs_f ;
} else {
dat = MSFtoLBA ( subc . abs_m , subc . abs_s , subc . abs_f ) - 150 ;
b [ 0 ] = ( dat > > 24 ) & 0xff ;
b [ 1 ] = ( dat > > 16 ) & 0xff ;
b [ 2 ] = ( dat > > 8 ) & 0xff ;
b [ 3 ] = dat & 0xff ;
}
return ret ;
}
2023-09-20 20:29:32 +02:00
void
cdrom_get_current_subcodeq ( cdrom_t * dev , uint8_t * b )
{
subchannel_t subc ;
dev - > ops - > get_subchannel ( dev , dev - > seek_pos , & subc ) ;
b [ 0 ] = subc . attr ;
b [ 1 ] = bin2bcd ( subc . track ) ;
b [ 2 ] = bin2bcd ( subc . index ) ;
b [ 3 ] = bin2bcd ( subc . rel_m ) ;
b [ 4 ] = bin2bcd ( subc . rel_s ) ;
b [ 5 ] = bin2bcd ( subc . rel_f ) ;
b [ 6 ] = bin2bcd ( subc . abs_m ) ;
b [ 7 ] = bin2bcd ( subc . abs_s ) ;
b [ 8 ] = bin2bcd ( subc . abs_f ) ;
}
2020-03-24 01:00:28 +01:00
uint8_t
cdrom_get_current_subcodeq_playstatus ( cdrom_t * dev , uint8_t * b )
{
2023-09-20 20:29:32 +02:00
uint8_t ret ;
2020-03-24 01:00:28 +01:00
subchannel_t subc ;
dev - > ops - > get_subchannel ( dev , dev - > seek_pos , & subc ) ;
2022-02-20 02:26:27 -05:00
2023-09-20 20:29:32 +02:00
if ( ( dev - > cd_status = = CD_STATUS_DATA_ONLY ) | |
( dev - > cd_status = = CD_STATUS_PLAYING_COMPLETED ) | |
( dev - > cd_status = = CD_STATUS_STOPPED ) )
2022-02-22 22:04:40 +01:00
ret = 0x03 ;
2022-12-04 20:53:03 +01:00
else
ret = ( dev - > cd_status = = CD_STATUS_PLAYING ) ? 0x00 : dev - > audio_op ;
2020-03-24 01:00:28 +01:00
2024-02-06 21:18:25 +01:00
/*If a valid audio track is detected with audio on, unmute it.*/
if ( dev - > ops - > track_type ( dev , dev - > seek_pos ) & CD_TRACK_AUDIO )
dev - > audio_muted_soft = 0 ;
cdrom_log ( " SubCodeQ: Play Status: Seek LBA=%08x, CDEND=%08x, mute=%d. \n " , dev - > seek_pos , dev - > cd_end , dev - > audio_muted_soft ) ;
2020-03-24 01:00:28 +01:00
b [ 0 ] = subc . attr ;
2023-01-07 23:48:45 +01:00
b [ 1 ] = bin2bcd ( subc . track ) ;
b [ 2 ] = bin2bcd ( subc . index ) ;
b [ 3 ] = bin2bcd ( subc . rel_m ) ;
b [ 4 ] = bin2bcd ( subc . rel_s ) ;
b [ 5 ] = bin2bcd ( subc . rel_f ) ;
b [ 6 ] = bin2bcd ( subc . abs_m ) ;
b [ 7 ] = bin2bcd ( subc . abs_s ) ;
b [ 8 ] = bin2bcd ( subc . abs_f ) ;
2020-03-24 01:00:28 +01:00
return ret ;
}
2018-10-30 13:32:25 +01:00
static int
read_toc_normal ( cdrom_t * dev , unsigned char * b , unsigned char start_track , int msf )
{
track_info_t ti ;
2023-05-16 15:43:20 -04:00
int i ;
int len = 4 ;
int m ;
int s ;
int f ;
int first_track ;
int last_track ;
2022-09-18 17:11:56 -04:00
uint32_t temp ;
2018-10-30 13:32:25 +01:00
2020-07-20 03:18:56 +02:00
cdrom_log ( " read_toc_normal(%08X, %08X, %02X, %i) \n " , dev , b , start_track , msf ) ;
2018-10-30 13:32:25 +01:00
dev - > ops - > get_tracks ( dev , & first_track , & last_track ) ;
2020-07-20 03:18:56 +02:00
/* Byte 2 = Number of the first track */
dev - > ops - > get_track_info ( dev , 1 , 0 , & ti ) ;
b [ 2 ] = ti . number ;
cdrom_log ( " b[2] = %02X \n " , b [ 2 ] ) ;
2018-10-30 13:32:25 +01:00
2020-07-20 03:18:56 +02:00
/* Byte 3 = Number of the last track before the lead-out track */
dev - > ops - > get_track_info ( dev , last_track , 0 , & ti ) ;
b [ 3 ] = ti . number ;
cdrom_log ( " b[3] = %02X \n " , b [ 2 ] ) ;
if ( start_track = = 0x00 )
2022-02-22 22:04:40 +01:00
first_track = 0 ;
2020-07-20 03:18:56 +02:00
else {
2022-02-22 22:04:40 +01:00
first_track = - 1 ;
for ( i = 0 ; i < = last_track ; i + + ) {
dev - > ops - > get_track_info ( dev , i + 1 , 0 , & ti ) ;
if ( ti . number > = start_track ) {
first_track = i ;
break ;
}
}
2018-10-30 13:32:25 +01:00
}
2020-07-20 03:18:56 +02:00
cdrom_log ( " first_track = %i, last_track = %i \n " , first_track , last_track ) ;
2018-10-30 13:32:25 +01:00
2020-07-20 03:18:56 +02:00
/* No suitable starting track, return with error. */
if ( first_track = = - 1 ) {
2022-02-22 22:04:40 +01:00
cdrom_log ( " [ERROR] No suitable track found \n " ) ;
return - 1 ;
2018-10-30 13:32:25 +01:00
}
2020-07-20 03:18:56 +02:00
for ( i = first_track ; i < = last_track ; i + + ) {
2022-02-22 22:04:40 +01:00
cdrom_log ( " tracks(%i) = %02X, %02X, %i:%02i.%02i \n " , i , ti . attr , ti . number , ti . m , ti . s , ti . f ) ;
dev - > ops - > get_track_info ( dev , i + 1 , 0 , & ti ) ;
2018-10-30 13:32:25 +01:00
2022-09-18 17:11:56 -04:00
b [ len + + ] = 0 ; /* reserved */
b [ len + + ] = ti . attr ;
b [ len + + ] = ti . number ; /* track number */
b [ len + + ] = 0 ; /* reserved */
2018-10-30 13:32:25 +01:00
2022-09-18 17:11:56 -04:00
if ( msf ) {
2022-02-22 22:04:40 +01:00
b [ len + + ] = 0 ;
2022-10-29 06:44:30 +02:00
/* NEC CDR-260 speaks BCD. */
2023-09-24 07:44:25 +02:00
if ( ( dev - > type = = CDROM_TYPE_NEC_260_100 ) | | ( dev - > type = = CDROM_TYPE_NEC_260_101 ) ) { /*NEC*/
2022-10-29 06:44:30 +02:00
m = ti . m ;
s = ti . s ;
f = ti . f ;
msf_to_bcd ( & m , & s , & f ) ;
b [ len + + ] = m ;
b [ len + + ] = s ;
b [ len + + ] = f ;
} else {
b [ len + + ] = ti . m ;
b [ len + + ] = ti . s ;
b [ len + + ] = ti . f ;
}
2022-09-18 17:11:56 -04:00
} else {
temp = MSFtoLBA ( ti . m , ti . s , ti . f ) - 150 ;
2022-02-22 22:04:40 +01:00
b [ len + + ] = temp > > 24 ;
b [ len + + ] = temp > > 16 ;
b [ len + + ] = temp > > 8 ;
b [ len + + ] = temp ;
}
2018-10-30 13:32:25 +01:00
}
return len ;
}
static int
read_toc_session ( cdrom_t * dev , unsigned char * b , int msf )
{
track_info_t ti ;
2023-05-16 15:43:20 -04:00
int len = 4 ;
int m ;
int s ;
int f ;
2022-09-18 17:11:56 -04:00
uint32_t temp ;
2018-10-30 13:32:25 +01:00
2020-07-20 03:18:56 +02:00
cdrom_log ( " read_toc_session(%08X, %08X, %i) \n " , dev , b , msf ) ;
/* Bytes 2 and 3 = Number of first and last sessions */
b [ 2 ] = b [ 3 ] = 1 ;
2018-10-30 13:32:25 +01:00
dev - > ops - > get_track_info ( dev , 1 , 0 , & ti ) ;
2020-07-20 03:18:56 +02:00
cdrom_log ( " tracks(0) = %02X, %02X, %i:%02i.%02i \n " , ti . attr , ti . number , ti . m , ti . s , ti . f ) ;
2018-10-30 13:32:25 +01:00
b [ len + + ] = 0 ; /* reserved */
b [ len + + ] = ti . attr ;
b [ len + + ] = ti . number ; /* track number */
2022-09-18 17:11:56 -04:00
b [ len + + ] = 0 ; /* reserved */
2020-07-20 03:18:56 +02:00
2018-10-30 13:32:25 +01:00
if ( msf ) {
2022-02-22 22:04:40 +01:00
b [ len + + ] = 0 ;
2022-10-29 06:44:30 +02:00
/* NEC CDR-260 speaks BCD. */
2023-10-24 20:15:08 +02:00
if ( ( dev - > type = = CDROM_TYPE_NEC_260_100 ) | | ( dev - > type = = CDROM_TYPE_NEC_260_101 ) ) { /*NEC*/
2022-10-29 06:44:30 +02:00
m = ti . m ;
s = ti . s ;
f = ti . f ;
msf_to_bcd ( & m , & s , & f ) ;
b [ len + + ] = m ;
b [ len + + ] = s ;
b [ len + + ] = f ;
} else {
b [ len + + ] = ti . m ;
b [ len + + ] = ti . s ;
b [ len + + ] = ti . f ;
}
2018-10-30 13:32:25 +01:00
} else {
2022-09-18 17:11:56 -04:00
temp = MSFtoLBA ( ti . m , ti . s , ti . f ) - 150 ;
2022-02-22 22:04:40 +01:00
b [ len + + ] = temp > > 24 ;
b [ len + + ] = temp > > 16 ;
b [ len + + ] = temp > > 8 ;
b [ len + + ] = temp ;
2018-10-30 13:32:25 +01:00
}
return len ;
}
static int
read_toc_raw ( cdrom_t * dev , unsigned char * b )
{
track_info_t ti ;
2023-05-16 15:43:20 -04:00
int len = 4 ;
int first_track ;
int last_track ;
2020-07-20 03:18:56 +02:00
cdrom_log ( " read_toc_raw(%08X, %08X) \n " , dev , b ) ;
2018-10-30 13:32:25 +01:00
dev - > ops - > get_tracks ( dev , & first_track , & last_track ) ;
2020-07-20 03:18:56 +02:00
/* Bytes 2 and 3 = Number of first and last sessions */
b [ 2 ] = b [ 3 ] = 1 ;
2018-10-30 13:32:25 +01:00
2023-05-16 15:43:20 -04:00
for ( int i = 0 ; i < = last_track ; i + + ) {
2022-02-22 22:04:40 +01:00
dev - > ops - > get_track_info ( dev , i + 1 , 0 , & ti ) ;
cdrom_log ( " tracks(%i) = %02X, %02X, %i:%02i.%02i \n " , i , ti . attr , ti . number , ti . m , ti . s , ti . f ) ;
2022-09-18 17:11:56 -04:00
b [ len + + ] = 1 ; /* Session number */
b [ len + + ] = ti . attr ; /* Track ADR and Control */
b [ len + + ] = 0 ; /* TNO (always 0) */
b [ len + + ] = ti . number ; /* Point (for track points - track number) */
b [ len + + ] = ti . m ; /* M */
b [ len + + ] = ti . s ; /* S */
b [ len + + ] = ti . f ; /* F */
2022-02-22 22:04:40 +01:00
b [ len + + ] = 0 ;
b [ len + + ] = 0 ;
b [ len + + ] = 0 ;
2018-10-30 13:32:25 +01:00
}
return len ;
}
2023-01-07 23:48:45 +01:00
static int
read_toc_sony ( cdrom_t * dev , unsigned char * b , unsigned char start_track , int msf )
{
track_info_t ti ;
2023-05-16 15:43:20 -04:00
int i ;
int len = 4 ;
int first_track ;
int last_track ;
2023-01-07 23:48:45 +01:00
uint32_t temp ;
cdrom_log ( " read_toc_sony(%08X, %08X, %02X, %i) \n " , dev , b , start_track , msf ) ;
dev - > ops - > get_tracks ( dev , & first_track , & last_track ) ;
/* Byte 2 = Number of the first track */
dev - > ops - > get_track_info ( dev , 1 , 0 , & ti ) ;
b [ 2 ] = ti . number ;
cdrom_log ( " b[2] = %02X \n " , b [ 2 ] ) ;
/* Byte 3 = Number of the last track before the lead-out track */
dev - > ops - > get_track_info ( dev , last_track , 0 , & ti ) ;
b [ 3 ] = ti . number ;
cdrom_log ( " b[3] = %02X \n " , b [ 2 ] ) ;
if ( start_track = = 0x00 )
first_track = 0 ;
else {
first_track = - 1 ;
for ( i = 0 ; i < = last_track ; i + + ) {
dev - > ops - > get_track_info ( dev , i + 1 , 0 , & ti ) ;
if ( ti . number > = start_track ) {
first_track = i ;
break ;
}
}
}
cdrom_log ( " first_track = %i, last_track = %i \n " , first_track , last_track ) ;
/* No suitable starting track, return with error. */
if ( first_track = = - 1 ) {
cdrom_log ( " [ERROR] No suitable track found \n " ) ;
return - 1 ;
}
for ( i = first_track ; i < = last_track ; i + + ) {
cdrom_log ( " tracks(%i) = %02X, %02X, %i:%02i.%02i \n " , i , ti . attr , ti . number , ti . m , ti . s , ti . f ) ;
dev - > ops - > get_track_info ( dev , i + 1 , 0 , & ti ) ;
b [ len + + ] = ti . number ; /* track number */
2023-09-20 20:29:32 +02:00
b [ len + + ] = ti . attr ;
2023-01-07 23:48:45 +01:00
if ( msf ) {
b [ len + + ] = 0 ;
b [ len + + ] = ti . m ;
b [ len + + ] = ti . s ;
b [ len + + ] = ti . f ;
} else {
temp = MSFtoLBA ( ti . m , ti . s , ti . f ) - 150 ;
b [ len + + ] = temp > > 24 ;
b [ len + + ] = temp > > 16 ;
b [ len + + ] = temp > > 8 ;
b [ len + + ] = temp ;
}
}
return len ;
}
2018-10-30 13:32:25 +01:00
int
cdrom_read_toc ( cdrom_t * dev , unsigned char * b , int type , unsigned char start_track , int msf , int max_len )
{
int len ;
2022-09-18 17:11:56 -04:00
switch ( type ) {
2022-02-22 22:04:40 +01:00
case CD_TOC_NORMAL :
len = read_toc_normal ( dev , b , start_track , msf ) ;
break ;
case CD_TOC_SESSION :
len = read_toc_session ( dev , b , msf ) ;
break ;
case CD_TOC_RAW :
len = read_toc_raw ( dev , b ) ;
break ;
default :
cdrom_log ( " CD-ROM %i: Unknown TOC read type: %i \n " , dev - > id , type ) ;
return 0 ;
2018-10-30 13:32:25 +01:00
}
len = MIN ( len , max_len ) ;
b [ 0 ] = ( uint8_t ) ( ( ( len - 2 ) > > 8 ) & 0xff ) ;
b [ 1 ] = ( uint8_t ) ( ( len - 2 ) & 0xff ) ;
return len ;
}
2023-01-07 23:48:45 +01:00
int
cdrom_read_toc_sony ( cdrom_t * dev , unsigned char * b , unsigned char start_track , int msf , int max_len )
{
int len ;
len = read_toc_sony ( dev , b , start_track , msf ) ;
len = MIN ( len , max_len ) ;
b [ 0 ] = ( uint8_t ) ( ( ( len - 2 ) > > 8 ) & 0xff ) ;
b [ 1 ] = ( uint8_t ) ( ( len - 2 ) & 0xff ) ;
return len ;
}
2022-11-05 20:15:00 -04:00
/* New API calls for Mitsumi CD-ROM. */
2022-02-14 19:47:48 +01:00
void
cdrom_get_track_buffer ( cdrom_t * dev , uint8_t * buf )
{
track_info_t ti ;
2023-05-16 15:43:20 -04:00
int first_track ;
int last_track ;
2022-02-14 19:47:48 +01:00
if ( dev ! = NULL ) {
2022-02-22 22:04:40 +01:00
dev - > ops - > get_tracks ( dev , & first_track , & last_track ) ;
buf [ 0 ] = 1 ;
buf [ 1 ] = last_track + 1 ;
dev - > ops - > get_track_info ( dev , 1 , 0 , & ti ) ;
buf [ 2 ] = ti . m ;
buf [ 3 ] = ti . s ;
buf [ 4 ] = ti . f ;
dev - > ops - > get_track_info ( dev , last_track + 1 , 0 , & ti ) ;
buf [ 5 ] = ti . m ;
buf [ 6 ] = ti . s ;
buf [ 7 ] = ti . f ;
buf [ 8 ] = 0x00 ;
2022-02-14 19:47:48 +01:00
} else
2022-02-22 22:04:40 +01:00
memset ( buf , 0x00 , 9 ) ;
2022-02-14 19:47:48 +01:00
}
2022-11-05 20:15:00 -04:00
void
cdrom_get_q ( cdrom_t * dev , uint8_t * buf , int * curtoctrk , uint8_t mode )
{
track_info_t ti ;
2023-05-16 15:43:20 -04:00
int first_track ;
int last_track ;
2022-11-05 20:15:00 -04:00
if ( dev ! = NULL ) {
dev - > ops - > get_tracks ( dev , & first_track , & last_track ) ;
dev - > ops - > get_track_info ( dev , * curtoctrk , 0 , & ti ) ;
buf [ 0 ] = ( ti . attr < < 4 ) & 0xf0 ;
buf [ 1 ] = ti . number ;
2023-01-07 23:48:45 +01:00
buf [ 2 ] = bin2bcd ( * curtoctrk + 1 ) ;
2022-11-05 20:15:00 -04:00
buf [ 3 ] = ti . m ;
buf [ 4 ] = ti . s ;
buf [ 5 ] = ti . f ;
buf [ 6 ] = 0x00 ;
dev - > ops - > get_track_info ( dev , 1 , 0 , & ti ) ;
buf [ 7 ] = ti . m ;
buf [ 8 ] = ti . s ;
buf [ 9 ] = ti . f ;
if ( * curtoctrk > = ( last_track + 1 ) )
* curtoctrk = 0 ;
else if ( mode )
* curtoctrk = * curtoctrk + 1 ;
} else
memset ( buf , 0x00 , 10 ) ;
}
uint8_t
cdrom_mitsumi_audio_play ( cdrom_t * dev , uint32_t pos , uint32_t len )
{
track_info_t ti ;
if ( dev - > cd_status = = CD_STATUS_DATA_ONLY )
return 0 ;
cdrom_log ( " CD-ROM 0: Play Mitsumi audio - %08X %08X \n " , pos , len ) ;
dev - > ops - > get_track_info ( dev , pos , 0 , & ti ) ;
pos = MSFtoLBA ( ti . m , ti . s , ti . f ) - 150 ;
dev - > ops - > get_track_info ( dev , len , 1 , & ti ) ;
len = MSFtoLBA ( ti . m , ti . s , ti . f ) - 150 ;
/* Do this at this point, since it's at this point that we know the
actual LBA position to start playing from . */
if ( ! ( dev - > ops - > track_type ( dev , pos ) & CD_TRACK_AUDIO ) ) {
cdrom_log ( " CD-ROM %i: LBA %08X not on an audio track \n " , dev - > id , pos ) ;
cdrom_stop ( dev ) ;
return 0 ;
}
dev - > seek_pos = pos ;
dev - > cd_end = len ;
dev - > cd_status = CD_STATUS_PLAYING ;
dev - > cd_buflen = 0 ;
return 1 ;
}
2023-01-07 23:48:45 +01:00
uint8_t
2020-03-24 01:00:28 +01:00
cdrom_read_disc_info_toc ( cdrom_t * dev , unsigned char * b , unsigned char track , int type )
{
track_info_t ti ;
2023-05-16 15:43:20 -04:00
int first_track ;
int last_track ;
int m = 0 ;
int s = 0 ;
int f = 0 ;
2023-10-24 20:15:08 +02:00
uint32_t temp ;
2020-03-24 01:00:28 +01:00
dev - > ops - > get_tracks ( dev , & first_track , & last_track ) ;
2023-01-07 23:48:45 +01:00
cdrom_log ( " Read DISC Info TOC Type = %d, track = %d, first_track = %d, last_track = %d. \n " , type , track , first_track , last_track ) ;
2020-03-24 01:00:28 +01:00
switch ( type ) {
2022-02-22 22:04:40 +01:00
case 0 :
2023-01-07 23:48:45 +01:00
b [ 0 ] = bin2bcd ( first_track ) ;
b [ 1 ] = bin2bcd ( last_track ) ;
2022-02-22 22:04:40 +01:00
b [ 2 ] = 0 ;
b [ 3 ] = 0 ;
2023-01-07 23:48:45 +01:00
cdrom_log ( " CD-ROM %i: Returned Toshiba/NEC disc information (type 0) at %02i:%02i \n " , dev - > id , b [ 0 ] , b [ 1 ] ) ;
2022-02-22 22:04:40 +01:00
break ;
case 1 :
2023-01-07 23:48:45 +01:00
dev - > ops - > get_track_info ( dev , 0xaa , 0 , & ti ) ;
m = ti . m ;
s = ti . s ;
f = ti . f ;
msf_to_bcd ( & m , & s , & f ) ;
b [ 0 ] = m ;
b [ 1 ] = s ;
b [ 2 ] = f ;
2022-02-22 22:04:40 +01:00
b [ 3 ] = 0 ;
2023-01-07 23:48:45 +01:00
cdrom_log ( " CD-ROM %i: Returned Toshiba/NEC disc information (type 1) at %02i:%02i.%02i, track=%d \n " , dev - > id , b [ 0 ] , b [ 1 ] , b [ 2 ] , bcd2bin ( track ) ) ;
2022-02-22 22:04:40 +01:00
break ;
case 2 :
2023-01-07 23:48:45 +01:00
if ( track > bin2bcd ( last_track ) )
return 0 ;
dev - > ops - > get_track_info ( dev , bcd2bin ( track ) , 0 , & ti ) ;
m = ti . m ;
s = ti . s ;
f = ti . f ;
msf_to_bcd ( & m , & s , & f ) ;
b [ 0 ] = m ;
b [ 1 ] = s ;
b [ 2 ] = f ;
2022-02-22 22:04:40 +01:00
b [ 3 ] = ti . attr ;
2023-01-07 23:48:45 +01:00
cdrom_log ( " CD-ROM %i: Returned Toshiba/NEC disc information (type 2) at %02i:%02i.%02i, track=%d, m=%02i,s=%02i,f=%02i, tno=%02x. \n " , dev - > id , b [ 0 ] , b [ 1 ] , b [ 2 ] , bcd2bin ( track ) , m , s , f , ti . attr ) ;
2022-02-22 22:04:40 +01:00
break ;
2023-11-10 17:27:30 -03:00
case 3 : /* Undocumented on NEC CD-ROM's, from information based on sr_vendor.c from the Linux kernel */
2023-10-24 20:15:08 +02:00
switch ( dev - > type ) {
case CDROM_TYPE_NEC_25_10a :
case CDROM_TYPE_NEC_38_103 :
case CDROM_TYPE_NEC_75_103 :
case CDROM_TYPE_NEC_77_106 :
case CDROM_TYPE_NEC_211_100 :
case CDROM_TYPE_NEC_464_105 :
dev - > ops - > get_track_info ( dev , 1 , 0 , & ti ) ;
b [ 0x0e ] = 0 ;
temp = MSFtoLBA ( ti . m , ti . s , ti . f ) - 150 ;
b [ 0x0f ] = temp > > 24 ;
b [ 0x10 ] = temp > > 16 ;
b [ 0x11 ] = temp > > 8 ;
b [ 0x12 ] = temp ;
break ;
default :
dev - > ops - > get_track_info ( dev , 1 , 0 , & ti ) ;
b [ 0 ] = 0 ;
temp = MSFtoLBA ( ti . m , ti . s , ti . f ) - 150 ;
b [ 1 ] = temp > > 24 ;
b [ 2 ] = temp > > 16 ;
b [ 3 ] = temp > > 8 ;
break ;
}
2022-02-22 22:04:40 +01:00
break ;
2023-06-26 12:47:04 -04:00
default :
break ;
2020-03-24 01:00:28 +01:00
}
2023-01-07 23:48:45 +01:00
return 1 ;
2020-03-24 01:00:28 +01:00
}
2018-10-30 13:32:25 +01:00
static int
2023-06-26 12:47:04 -04:00
track_type_is_valid ( UNUSED ( uint8_t id ) , int type , int flags , int audio , int mode2 )
2018-10-30 13:32:25 +01:00
{
2022-09-18 17:11:56 -04:00
if ( ! ( flags & 0x70 ) & & ( flags & 0xf8 ) ) { /* 0x08/0x80/0x88 are illegal modes */
2022-02-22 22:04:40 +01:00
cdrom_log ( " CD-ROM %i: [Any Mode] 0x08/0x80/0x88 are illegal modes \n " , id ) ;
return 0 ;
2018-10-30 13:32:25 +01:00
}
if ( ( type ! = 1 ) & & ! audio ) {
2022-02-22 22:04:40 +01:00
if ( ( flags & 0x06 ) = = 0x06 ) {
cdrom_log ( " CD-ROM %i: [Any Data Mode] Invalid error flags \n " , id ) ;
return 0 ;
}
if ( ( ( flags & 0x700 ) = = 0x300 ) | | ( ( flags & 0x700 ) > 0x400 ) ) {
cdrom_log ( " CD-ROM %i: [Any Data Mode] Invalid subchannel data flags (%02X) \n " , id , flags & 0x700 ) ;
return 0 ;
}
2022-09-18 17:11:56 -04:00
if ( ( flags & 0x18 ) = = 0x08 ) { /* EDC/ECC without user data is an illegal mode */
2022-02-22 22:04:40 +01:00
cdrom_log ( " CD-ROM %i: [Any Data Mode] EDC/ECC without user data is an illegal mode \n " , id ) ;
return 0 ;
}
2022-09-18 17:11:56 -04:00
if ( ( ( flags & 0xf0 ) = = 0x90 ) | | ( ( flags & 0xf0 ) = = 0xc0 ) ) { /* 0x90/0x98/0xC0/0xC8 are illegal modes */
2022-02-22 22:04:40 +01:00
cdrom_log ( " CD-ROM %i: [Any Data Mode] 0x90/0x98/0xC0/0xC8 are illegal modes \n " , id ) ;
return 0 ;
}
if ( ( ( type > 3 ) & & ( type ! = 8 ) ) | | ( mode2 & & ( mode2 & 0x03 ) ) ) {
2022-09-18 17:11:56 -04:00
if ( ( flags & 0xf0 ) = = 0x30 ) { /* 0x30/0x38 are illegal modes */
2022-02-22 22:04:40 +01:00
cdrom_log ( " CD-ROM %i: [Any XA Mode 2] 0x30/0x38 are illegal modes \n " , id ) ;
return 0 ;
}
2022-09-18 17:11:56 -04:00
if ( ( ( flags & 0xf0 ) = = 0xb0 ) | | ( ( flags & 0xf0 ) = = 0xd0 ) ) { /* 0xBx and 0xDx are illegal modes */
2022-02-22 22:04:40 +01:00
cdrom_log ( " CD-ROM %i: [Any XA Mode 2] 0xBx and 0xDx are illegal modes \n " , id ) ;
return 0 ;
}
}
2018-10-30 13:32:25 +01:00
}
return 1 ;
}
static void
read_sector_to_buffer ( cdrom_t * dev , uint8_t * rbuf , uint32_t msf , uint32_t lba , int mode2 , int len )
{
uint8_t * bb = rbuf ;
2024-04-22 02:04:57 +02:00
const int offset = ( ! ! ( mode2 & 0x03 ) ) ? 24 : 16 ;
2018-10-30 13:32:25 +01:00
2024-04-22 02:04:57 +02:00
dev - > ops - > read_sector ( dev , CD_READ_DATA , rbuf + offset , lba ) ;
2018-10-30 13:32:25 +01:00
/* Sync bytes */
bb [ 0 ] = 0 ;
memset ( bb + 1 , 0xff , 10 ) ;
bb [ 11 ] = 0 ;
bb + = 12 ;
/* Sector header */
bb [ 0 ] = ( msf > > 16 ) & 0xff ;
bb [ 1 ] = ( msf > > 8 ) & 0xff ;
bb [ 2 ] = msf & 0xff ;
bb [ 3 ] = 1 ; /* mode 1 data */
bb + = mode2 ? 12 : 4 ;
bb + = len ;
if ( mode2 & & ( ( mode2 & 0x03 ) = = 1 ) )
2022-02-22 22:04:40 +01:00
memset ( bb , 0 , 280 ) ;
2018-10-30 13:32:25 +01:00
else if ( ! mode2 )
2022-02-22 22:04:40 +01:00
memset ( bb , 0 , 288 ) ;
2018-10-30 13:32:25 +01:00
}
static void
read_audio ( cdrom_t * dev , uint32_t lba , uint8_t * b )
{
dev - > ops - > read_sector ( dev , CD_READ_RAW , raw_buffer , lba ) ;
memcpy ( b , raw_buffer , 2352 ) ;
cdrom_sector_size = 2352 ;
}
static void
read_mode1 ( cdrom_t * dev , int cdrom_sector_flags , uint32_t lba , uint32_t msf , int mode2 , uint8_t * b )
{
if ( ( dev - > cd_status = = CD_STATUS_DATA_ONLY ) | | ( dev - > ops - > sector_size ( dev , lba ) = = 2048 ) )
2022-02-22 22:04:40 +01:00
read_sector_to_buffer ( dev , raw_buffer , msf , lba , mode2 , 2048 ) ;
2018-10-30 13:32:25 +01:00
else
2022-02-22 22:04:40 +01:00
dev - > ops - > read_sector ( dev , CD_READ_RAW , raw_buffer , lba ) ;
2018-10-30 13:32:25 +01:00
cdrom_sector_size = 0 ;
2022-02-22 22:04:40 +01:00
if ( cdrom_sector_flags & 0x80 ) {
/* Sync */
cdrom_log ( " CD-ROM %i: [Mode 1] Sync \n " , dev - > id ) ;
memcpy ( b , raw_buffer , 12 ) ;
cdrom_sector_size + = 12 ;
b + = 12 ;
2018-10-30 13:32:25 +01:00
}
2022-02-22 22:04:40 +01:00
if ( cdrom_sector_flags & 0x20 ) {
/* Header */
cdrom_log ( " CD-ROM %i: [Mode 1] Header \n " , dev - > id ) ;
memcpy ( b , raw_buffer + 12 , 4 ) ;
cdrom_sector_size + = 4 ;
b + = 4 ;
2018-10-30 13:32:25 +01:00
}
2022-02-22 22:04:40 +01:00
if ( cdrom_sector_flags & 0x40 ) {
/* Sub-header */
if ( ! ( cdrom_sector_flags & 0x10 ) ) {
/* No user data */
cdrom_log ( " CD-ROM %i: [Mode 1] Sub-header \n " , dev - > id ) ;
memcpy ( b , raw_buffer + 16 , 8 ) ;
cdrom_sector_size + = 8 ;
b + = 8 ;
}
2018-10-30 13:32:25 +01:00
}
2022-02-22 22:04:40 +01:00
if ( cdrom_sector_flags & 0x10 ) {
/* User data */
cdrom_log ( " CD-ROM %i: [Mode 1] User data \n " , dev - > id ) ;
memcpy ( b , raw_buffer + 16 , 2048 ) ;
cdrom_sector_size + = 2048 ;
b + = 2048 ;
2018-10-30 13:32:25 +01:00
}
2022-02-22 22:04:40 +01:00
if ( cdrom_sector_flags & 0x08 ) {
/* EDC/ECC */
cdrom_log ( " CD-ROM %i: [Mode 1] EDC/ECC \n " , dev - > id ) ;
memcpy ( b , raw_buffer + 2064 , 288 ) ;
cdrom_sector_size + = 288 ;
b + = 288 ;
2018-10-30 13:32:25 +01:00
}
}
static void
read_mode2_non_xa ( cdrom_t * dev , int cdrom_sector_flags , uint32_t lba , uint32_t msf , int mode2 , uint8_t * b )
{
if ( ( dev - > cd_status = = CD_STATUS_DATA_ONLY ) | | ( dev - > ops - > sector_size ( dev , lba ) = = 2336 ) )
2022-02-22 22:04:40 +01:00
read_sector_to_buffer ( dev , raw_buffer , msf , lba , mode2 , 2336 ) ;
2018-10-30 13:32:25 +01:00
else
2022-02-22 22:04:40 +01:00
dev - > ops - > read_sector ( dev , CD_READ_RAW , raw_buffer , lba ) ;
2018-10-30 13:32:25 +01:00
cdrom_sector_size = 0 ;
2022-02-22 22:04:40 +01:00
if ( cdrom_sector_flags & 0x80 ) {
/* Sync */
cdrom_log ( " CD-ROM %i: [Mode 2 Formless] Sync \n " , dev - > id ) ;
memcpy ( b , raw_buffer , 12 ) ;
cdrom_sector_size + = 12 ;
b + = 12 ;
2018-10-30 13:32:25 +01:00
}
2022-02-22 22:04:40 +01:00
if ( cdrom_sector_flags & 0x20 ) {
/* Header */
cdrom_log ( " CD-ROM %i: [Mode 2 Formless] Header \n " , dev - > id ) ;
memcpy ( b , raw_buffer + 12 , 4 ) ;
cdrom_sector_size + = 4 ;
b + = 4 ;
2018-10-30 13:32:25 +01:00
}
/* Mode 1 sector, expected type is 1 type. */
2022-02-22 22:04:40 +01:00
if ( cdrom_sector_flags & 0x40 ) {
/* Sub-header */
cdrom_log ( " CD-ROM %i: [Mode 2 Formless] Sub-header \n " , dev - > id ) ;
memcpy ( b , raw_buffer + 16 , 8 ) ;
cdrom_sector_size + = 8 ;
b + = 8 ;
2018-10-30 13:32:25 +01:00
}
2022-02-22 22:04:40 +01:00
if ( cdrom_sector_flags & 0x10 ) {
/* User data */
cdrom_log ( " CD-ROM %i: [Mode 2 Formless] User data \n " , dev - > id ) ;
memcpy ( b , raw_buffer + 24 , 2336 ) ;
cdrom_sector_size + = 2336 ;
b + = 2336 ;
2018-10-30 13:32:25 +01:00
}
}
static void
read_mode2_xa_form1 ( cdrom_t * dev , int cdrom_sector_flags , uint32_t lba , uint32_t msf , int mode2 , uint8_t * b )
{
if ( ( dev - > cd_status = = CD_STATUS_DATA_ONLY ) | | ( dev - > ops - > sector_size ( dev , lba ) = = 2048 ) )
2022-02-22 22:04:40 +01:00
read_sector_to_buffer ( dev , raw_buffer , msf , lba , mode2 , 2048 ) ;
2018-10-30 13:32:25 +01:00
else
2022-02-22 22:04:40 +01:00
dev - > ops - > read_sector ( dev , CD_READ_RAW , raw_buffer , lba ) ;
2018-10-30 13:32:25 +01:00
cdrom_sector_size = 0 ;
2022-02-22 22:04:40 +01:00
if ( cdrom_sector_flags & 0x80 ) {
/* Sync */
cdrom_log ( " CD-ROM %i: [XA Mode 2 Form 1] Sync \n " , dev - > id ) ;
memcpy ( b , raw_buffer , 12 ) ;
cdrom_sector_size + = 12 ;
b + = 12 ;
2018-10-30 13:32:25 +01:00
}
2022-02-22 22:04:40 +01:00
if ( cdrom_sector_flags & 0x20 ) {
/* Header */
cdrom_log ( " CD-ROM %i: [XA Mode 2 Form 1] Header \n " , dev - > id ) ;
memcpy ( b , raw_buffer + 12 , 4 ) ;
cdrom_sector_size + = 4 ;
b + = 4 ;
2018-10-30 13:32:25 +01:00
}
2022-02-22 22:04:40 +01:00
if ( cdrom_sector_flags & 0x40 ) {
/* Sub-header */
cdrom_log ( " CD-ROM %i: [XA Mode 2 Form 1] Sub-header \n " , dev - > id ) ;
memcpy ( b , raw_buffer + 16 , 8 ) ;
cdrom_sector_size + = 8 ;
b + = 8 ;
2018-10-30 13:32:25 +01:00
}
2022-02-22 22:04:40 +01:00
if ( cdrom_sector_flags & 0x10 ) {
/* User data */
cdrom_log ( " CD-ROM %i: [XA Mode 2 Form 1] User data \n " , dev - > id ) ;
memcpy ( b , raw_buffer + 24 , 2048 ) ;
cdrom_sector_size + = 2048 ;
b + = 2048 ;
2018-10-30 13:32:25 +01:00
}
2022-02-22 22:04:40 +01:00
if ( cdrom_sector_flags & 0x08 ) {
/* EDC/ECC */
cdrom_log ( " CD-ROM %i: [XA Mode 2 Form 1] EDC/ECC \n " , dev - > id ) ;
memcpy ( b , raw_buffer + 2072 , 280 ) ;
cdrom_sector_size + = 280 ;
b + = 280 ;
2018-10-30 13:32:25 +01:00
}
}
static void
read_mode2_xa_form2 ( cdrom_t * dev , int cdrom_sector_flags , uint32_t lba , uint32_t msf , int mode2 , uint8_t * b )
{
if ( ( dev - > cd_status = = CD_STATUS_DATA_ONLY ) | | ( dev - > ops - > sector_size ( dev , lba ) = = 2324 ) )
2022-02-22 22:04:40 +01:00
read_sector_to_buffer ( dev , raw_buffer , msf , lba , mode2 , 2324 ) ;
2018-10-30 13:32:25 +01:00
else
2022-02-22 22:04:40 +01:00
dev - > ops - > read_sector ( dev , CD_READ_RAW , raw_buffer , lba ) ;
2018-10-30 13:32:25 +01:00
cdrom_sector_size = 0 ;
2022-02-22 22:04:40 +01:00
if ( cdrom_sector_flags & 0x80 ) {
/* Sync */
cdrom_log ( " CD-ROM %i: [XA Mode 2 Form 2] Sync \n " , dev - > id ) ;
memcpy ( b , raw_buffer , 12 ) ;
cdrom_sector_size + = 12 ;
b + = 12 ;
2018-10-30 13:32:25 +01:00
}
2022-02-22 22:04:40 +01:00
if ( cdrom_sector_flags & 0x20 ) {
/* Header */
cdrom_log ( " CD-ROM %i: [XA Mode 2 Form 2] Header \n " , dev - > id ) ;
memcpy ( b , raw_buffer + 12 , 4 ) ;
cdrom_sector_size + = 4 ;
b + = 4 ;
2018-10-30 13:32:25 +01:00
}
2022-02-22 22:04:40 +01:00
if ( cdrom_sector_flags & 0x40 ) {
/* Sub-header */
cdrom_log ( " CD-ROM %i: [XA Mode 2 Form 2] Sub-header \n " , dev - > id ) ;
memcpy ( b , raw_buffer + 16 , 8 ) ;
cdrom_sector_size + = 8 ;
b + = 8 ;
2018-10-30 13:32:25 +01:00
}
2022-02-22 22:04:40 +01:00
if ( cdrom_sector_flags & 0x10 ) {
/* User data */
cdrom_log ( " CD-ROM %i: [XA Mode 2 Form 2] User data \n " , dev - > id ) ;
memcpy ( b , raw_buffer + 24 , 2328 ) ;
cdrom_sector_size + = 2328 ;
b + = 2328 ;
2018-10-30 13:32:25 +01:00
}
}
int
cdrom_readsector_raw ( cdrom_t * dev , uint8_t * buffer , int sector , int ismsf , int cdrom_sector_type ,
2023-01-07 23:48:45 +01:00
int cdrom_sector_flags , int * len , uint8_t vendor_type )
2018-10-30 13:32:25 +01:00
{
2023-05-16 15:43:20 -04:00
uint8_t * b ;
uint8_t * temp_b ;
uint32_t msf ;
uint32_t lba ;
int audio = 0 ;
int mode2 = 0 ;
int m ;
int s ;
int f ;
2018-10-30 13:32:25 +01:00
if ( dev - > cd_status = = CD_STATUS_EMPTY )
2022-02-22 22:04:40 +01:00
return 0 ;
2018-10-30 13:32:25 +01:00
b = temp_b = buffer ;
* len = 0 ;
if ( ismsf ) {
2022-09-18 17:11:56 -04:00
m = ( sector > > 16 ) & 0xff ;
s = ( sector > > 8 ) & 0xff ;
f = sector & 0xff ;
2022-02-22 22:04:40 +01:00
lba = MSFtoLBA ( m , s , f ) - 150 ;
msf = sector ;
2018-10-30 13:32:25 +01:00
} else {
2023-01-07 23:48:45 +01:00
switch ( vendor_type ) {
case 0x00 :
lba = sector ;
msf = cdrom_lba_to_msf_accurate ( sector ) ;
break ;
case 0x40 :
m = bcd2bin ( ( sector > > 24 ) & 0xff ) ;
s = bcd2bin ( ( sector > > 16 ) & 0xff ) ;
f = bcd2bin ( ( sector > > 8 ) & 0xff ) ;
lba = MSFtoLBA ( m , s , f ) - 150 ;
msf = sector ;
break ;
case 0x80 :
lba = bcd2bin ( ( sector > > 24 ) & 0xff ) ;
msf = sector ;
break ;
2023-01-10 04:15:29 +01:00
/* Never used values but the compiler complains. */
default :
lba = msf = 0 ;
2023-01-07 23:48:45 +01:00
}
2018-10-30 13:32:25 +01:00
}
if ( dev - > ops - > track_type )
2022-02-22 22:04:40 +01:00
audio = dev - > ops - > track_type ( dev , lba ) ;
2018-10-30 13:32:25 +01:00
mode2 = audio & ~ CD_TRACK_AUDIO ;
audio & = CD_TRACK_AUDIO ;
memset ( raw_buffer , 0 , 2448 ) ;
memset ( extra_buffer , 0 , 296 ) ;
2022-02-22 22:04:40 +01:00
if ( ( cdrom_sector_flags & 0xf8 ) = = 0x08 ) {
/* 0x08 is an illegal mode */
cdrom_log ( " CD-ROM %i: [Mode 1] 0x08 is an illegal mode \n " , dev - > id ) ;
return 0 ;
2018-10-30 13:32:25 +01:00
}
if ( ! track_type_is_valid ( dev - > id , cdrom_sector_type , cdrom_sector_flags , audio , mode2 ) )
2022-02-22 22:04:40 +01:00
return 0 ;
2018-10-30 13:32:25 +01:00
if ( ( cdrom_sector_type > 5 ) & & ( cdrom_sector_type ! = 8 ) ) {
2022-02-22 22:04:40 +01:00
cdrom_log ( " CD-ROM %i: Attempting to read an unrecognized sector type from an image \n " , dev - > id ) ;
return 0 ;
2018-10-30 13:32:25 +01:00
} else if ( cdrom_sector_type = = 1 ) {
2022-02-22 22:04:40 +01:00
if ( ! audio | | ( dev - > cd_status = = CD_STATUS_DATA_ONLY ) ) {
cdrom_log ( " CD-ROM %i: [Audio] Attempting to read an audio sector from a data image \n " , dev - > id ) ;
return 0 ;
}
2018-10-30 13:32:25 +01:00
2022-02-22 22:04:40 +01:00
read_audio ( dev , lba , temp_b ) ;
2018-10-30 13:32:25 +01:00
} else if ( cdrom_sector_type = = 2 ) {
2022-02-22 22:04:40 +01:00
if ( audio | | mode2 ) {
cdrom_log ( " CD-ROM %i: [Mode 1] Attempting to read a sector of another type \n " , dev - > id ) ;
return 0 ;
}
2018-10-30 13:32:25 +01:00
2022-02-22 22:04:40 +01:00
read_mode1 ( dev , cdrom_sector_flags , lba , msf , mode2 , temp_b ) ;
2018-10-30 13:32:25 +01:00
} else if ( cdrom_sector_type = = 3 ) {
2022-02-22 22:04:40 +01:00
if ( audio | | ! mode2 | | ( mode2 & 0x03 ) ) {
cdrom_log ( " CD-ROM %i: [Mode 2 Formless] Attempting to read a sector of another type \n " , dev - > id ) ;
return 0 ;
}
2018-10-30 13:32:25 +01:00
2022-02-22 22:04:40 +01:00
read_mode2_non_xa ( dev , cdrom_sector_flags , lba , msf , mode2 , temp_b ) ;
2018-10-30 13:32:25 +01:00
} else if ( cdrom_sector_type = = 4 ) {
2022-02-22 22:04:40 +01:00
if ( audio | | ! mode2 | | ( ( mode2 & 0x03 ) ! = 1 ) ) {
cdrom_log ( " CD-ROM %i: [XA Mode 2 Form 1] Attempting to read a sector of another type \n " , dev - > id ) ;
return 0 ;
}
2018-10-30 13:32:25 +01:00
2022-02-22 22:04:40 +01:00
read_mode2_xa_form1 ( dev , cdrom_sector_flags , lba , msf , mode2 , temp_b ) ;
2018-10-30 13:32:25 +01:00
} else if ( cdrom_sector_type = = 5 ) {
2022-02-22 22:04:40 +01:00
if ( audio | | ! mode2 | | ( ( mode2 & 0x03 ) ! = 2 ) ) {
cdrom_log ( " CD-ROM %i: [XA Mode 2 Form 2] Attempting to read a sector of another type \n " , dev - > id ) ;
return 0 ;
}
2018-10-30 13:32:25 +01:00
2022-02-22 22:04:40 +01:00
read_mode2_xa_form2 ( dev , cdrom_sector_flags , lba , msf , mode2 , temp_b ) ;
2018-10-30 13:32:25 +01:00
} else if ( cdrom_sector_type = = 8 ) {
2022-02-22 22:04:40 +01:00
if ( audio ) {
cdrom_log ( " CD-ROM %i: [Any Data] Attempting to read a data sector from an audio track \n " , dev - > id ) ;
return 0 ;
}
if ( mode2 & & ( ( mode2 & 0x03 ) = = 1 ) )
read_mode2_xa_form1 ( dev , cdrom_sector_flags , lba , msf , mode2 , temp_b ) ;
else if ( ! mode2 )
read_mode1 ( dev , cdrom_sector_flags , lba , msf , mode2 , temp_b ) ;
else {
cdrom_log ( " CD-ROM %i: [Any Data] Attempting to read a data sector whose cooked size is not 2048 bytes \n " , dev - > id ) ;
return 0 ;
}
2018-10-30 13:32:25 +01:00
} else {
2022-02-22 22:04:40 +01:00
if ( mode2 ) {
if ( ( mode2 & 0x03 ) = = 0x01 )
read_mode2_xa_form1 ( dev , cdrom_sector_flags , lba , msf , mode2 , temp_b ) ;
else if ( ( mode2 & 0x03 ) = = 0x02 )
read_mode2_xa_form2 ( dev , cdrom_sector_flags , lba , msf , mode2 , temp_b ) ;
else
read_mode2_non_xa ( dev , cdrom_sector_flags , lba , msf , mode2 , temp_b ) ;
} else {
if ( audio )
read_audio ( dev , lba , temp_b ) ;
else
read_mode1 ( dev , cdrom_sector_flags , lba , msf , mode2 , temp_b ) ;
}
2018-10-30 13:32:25 +01:00
}
if ( ( cdrom_sector_flags & 0x06 ) = = 0x02 ) {
2022-02-22 22:04:40 +01:00
/* Add error flags. */
cdrom_log ( " CD-ROM %i: Error flags \n " , dev - > id ) ;
memcpy ( b + cdrom_sector_size , extra_buffer , 294 ) ;
cdrom_sector_size + = 294 ;
2018-10-30 13:32:25 +01:00
} else if ( ( cdrom_sector_flags & 0x06 ) = = 0x04 ) {
2022-02-22 22:04:40 +01:00
/* Add error flags. */
cdrom_log ( " CD-ROM %i: Full error flags \n " , dev - > id ) ;
memcpy ( b + cdrom_sector_size , extra_buffer , 296 ) ;
cdrom_sector_size + = 296 ;
2018-10-30 13:32:25 +01:00
}
if ( ( cdrom_sector_flags & 0x700 ) = = 0x100 ) {
2022-02-22 22:04:40 +01:00
cdrom_log ( " CD-ROM %i: Raw subchannel data \n " , dev - > id ) ;
memcpy ( b + cdrom_sector_size , raw_buffer + 2352 , 96 ) ;
cdrom_sector_size + = 96 ;
2018-10-30 13:32:25 +01:00
} else if ( ( cdrom_sector_flags & 0x700 ) = = 0x200 ) {
2022-02-22 22:04:40 +01:00
cdrom_log ( " CD-ROM %i: Q subchannel data \n " , dev - > id ) ;
memcpy ( b + cdrom_sector_size , raw_buffer + 2352 , 16 ) ;
cdrom_sector_size + = 16 ;
2018-10-30 13:32:25 +01:00
} else if ( ( cdrom_sector_flags & 0x700 ) = = 0x400 ) {
2022-02-22 22:04:40 +01:00
cdrom_log ( " CD-ROM %i: R/W subchannel data \n " , dev - > id ) ;
memcpy ( b + cdrom_sector_size , raw_buffer + 2352 , 96 ) ;
cdrom_sector_size + = 96 ;
2018-10-17 05:29:48 +02:00
}
2018-10-30 13:32:25 +01:00
* len = cdrom_sector_size ;
2018-10-17 05:29:48 +02:00
2018-10-30 13:32:25 +01:00
return 1 ;
2017-01-16 01:49:19 +01:00
}
2018-10-10 22:33:24 +02:00
/* Peform a master init on the entire module. */
void
cdrom_global_init ( void )
2018-04-25 23:51:13 +02:00
{
2018-10-10 22:33:24 +02:00
/* Clear the global data. */
2018-10-17 05:29:48 +02:00
memset ( cdrom , 0x00 , sizeof ( cdrom ) ) ;
2017-01-16 01:49:19 +01:00
}
2018-04-25 23:51:13 +02:00
static void
2018-10-17 05:29:48 +02:00
cdrom_drive_reset ( cdrom_t * dev )
2018-04-25 23:51:13 +02:00
{
2022-09-18 17:11:56 -04:00
dev - > priv = NULL ;
dev - > insert = NULL ;
dev - > close = NULL ;
dev - > get_volume = NULL ;
2018-10-17 05:29:48 +02:00
dev - > get_channel = NULL ;
2017-01-16 01:49:19 +01:00
}
2018-10-10 22:33:24 +02:00
void
cdrom_hard_reset ( void )
2018-04-25 23:51:13 +02:00
{
2018-10-17 05:29:48 +02:00
cdrom_t * dev ;
2023-05-16 15:43:20 -04:00
for ( uint8_t i = 0 ; i < CDROM_NUM ; i + + ) {
2022-02-22 22:04:40 +01:00
dev = & cdrom [ i ] ;
if ( dev - > bus_type ) {
cdrom_log ( " CD-ROM %i: Hard reset \n " , i ) ;
2018-10-17 05:29:48 +02:00
2022-02-22 22:04:40 +01:00
dev - > id = i ;
2018-03-17 20:32:20 +01:00
2022-02-22 22:04:40 +01:00
cdrom_drive_reset ( dev ) ;
2017-01-16 01:49:19 +01:00
2022-09-18 17:11:56 -04:00
switch ( dev - > bus_type ) {
2022-02-22 22:04:40 +01:00
case CDROM_BUS_ATAPI :
case CDROM_BUS_SCSI :
scsi_cdrom_drive_reset ( i ) ;
break ;
2018-04-25 23:51:13 +02:00
2022-02-22 22:04:40 +01:00
default :
break ;
}
2018-04-25 23:51:13 +02:00
2022-02-22 22:04:40 +01:00
dev - > cd_status = CD_STATUS_EMPTY ;
2018-04-25 23:51:13 +02:00
2024-01-14 21:31:46 +01:00
if ( dev - > host_drive = = 200 ) {
# ifdef _WIN32
if ( ( strlen ( dev - > image_path ) > = 1 ) & & ( dev - > image_path [ strlen ( dev - > image_path ) - 1 ] = = ' / ' ) )
dev - > image_path [ strlen ( dev - > image_path ) - 1 ] = ' \\ ' ;
# else
if ( ( strlen ( dev - > image_path ) > = 1 ) & &
( dev - > image_path [ strlen ( dev - > image_path ) - 1 ] = = ' \\ ' ) )
dev - > image_path [ strlen ( dev - > image_path ) - 1 ] = ' / ' ;
# endif
2024-05-19 21:17:57 +02:00
if ( ( strlen ( dev - > image_path ) ! = 0 ) & & ( strstr ( dev - > image_path , " ioctl:// " ) = = dev - > image_path ) )
cdrom_ioctl_open ( dev , dev - > image_path ) ;
else
cdrom_image_open ( dev , dev - > image_path ) ;
}
2022-02-22 22:04:40 +01:00
}
2018-04-25 23:51:13 +02:00
}
2017-10-24 04:15:05 +02:00
2018-10-10 22:33:24 +02:00
sound_cd_thread_reset ( ) ;
2017-01-16 01:49:19 +01:00
}
2018-10-10 22:33:24 +02:00
void
2018-10-17 05:29:48 +02:00
cdrom_close ( void )
2018-01-06 22:47:41 +01:00
{
2018-10-17 05:29:48 +02:00
cdrom_t * dev ;
2018-01-06 22:47:41 +01:00
2023-05-16 15:43:20 -04:00
for ( uint8_t i = 0 ; i < CDROM_NUM ; i + + ) {
2022-02-22 22:04:40 +01:00
dev = & cdrom [ i ] ;
2018-10-17 05:29:48 +02:00
2022-02-22 22:04:40 +01:00
if ( dev - > bus_type = = CDROM_BUS_SCSI )
memset ( & scsi_devices [ dev - > scsi_device_id ] , 0x00 , sizeof ( scsi_device_t ) ) ;
2020-06-14 21:59:45 +02:00
2022-02-22 22:04:40 +01:00
if ( dev - > close )
dev - > close ( dev - > priv ) ;
2018-10-30 13:32:25 +01:00
2022-02-22 22:04:40 +01:00
if ( dev - > ops & & dev - > ops - > exit )
dev - > ops - > exit ( dev ) ;
2018-10-17 05:29:48 +02:00
2022-09-18 17:11:56 -04:00
dev - > ops = NULL ;
2022-02-22 22:04:40 +01:00
dev - > priv = NULL ;
2018-10-26 04:47:21 +02:00
2022-02-22 22:04:40 +01:00
cdrom_drive_reset ( dev ) ;
2018-10-17 05:29:48 +02:00
}
}
/* Signal disc change to the emulated machine. */
void
cdrom_insert ( uint8_t id )
{
cdrom_t * dev = & cdrom [ id ] ;
2023-08-16 05:23:03 +02:00
if ( dev - > bus_type & & dev - > insert )
dev - > insert ( dev - > priv ) ;
2018-10-17 05:29:48 +02:00
}
/* The mechanics of ejecting a CD-ROM from a drive. */
void
cdrom_eject ( uint8_t id )
{
cdrom_t * dev = & cdrom [ id ] ;
/* This entire block should be in cdrom.c/cdrom_eject(dev*) ... */
if ( dev - > host_drive = = 0 ) {
2022-02-22 22:04:40 +01:00
/* Switch from empty to empty. Do nothing. */
return ;
2018-10-17 05:29:48 +02:00
}
2018-10-11 10:34:12 +02:00
2024-05-19 21:17:57 +02:00
if ( dev - > host_drive > = 200 )
2022-02-22 22:04:40 +01:00
strcpy ( dev - > prev_image_path , dev - > image_path ) ;
2018-10-17 05:29:48 +02:00
2024-05-18 19:42:00 +02:00
dev - > prev_host_drive = dev - > host_drive + ( dev - > host ? 1 : 0 ) ;
2022-09-18 17:11:56 -04:00
dev - > host_drive = 0 ;
2018-10-17 05:29:48 +02:00
dev - > ops - > exit ( dev ) ;
dev - > ops = NULL ;
memset ( dev - > image_path , 0 , sizeof ( dev - > image_path ) ) ;
cdrom_insert ( id ) ;
plat_cdrom_ui_update ( id , 0 ) ;
config_save ( ) ;
2018-01-06 22:47:41 +01:00
}
2018-10-17 05:29:48 +02:00
/* The mechanics of re-loading a CD-ROM drive. */
2018-10-10 22:33:24 +02:00
void
2018-10-17 05:29:48 +02:00
cdrom_reload ( uint8_t id )
2017-01-16 01:49:19 +01:00
{
2018-10-17 05:29:48 +02:00
cdrom_t * dev = & cdrom [ id ] ;
2017-01-16 01:49:19 +01:00
2024-05-18 22:37:49 +02:00
if ( ! dev - > host & & ( ( dev - > host_drive = = dev - > prev_host_drive ) | | ( dev - > prev_host_drive = = 0 ) | | ( dev - > host_drive ! = 0 ) ) ) {
2022-02-22 22:04:40 +01:00
/* Switch from empty to empty. Do nothing. */
return ;
2018-10-17 05:29:48 +02:00
}
if ( dev - > ops & & dev - > ops - > exit )
2022-02-22 22:04:40 +01:00
dev - > ops - > exit ( dev ) ;
2018-10-17 05:29:48 +02:00
dev - > ops = NULL ;
memset ( dev - > image_path , 0 , sizeof ( dev - > image_path ) ) ;
2017-01-18 21:51:03 +01:00
2024-05-18 19:42:00 +02:00
if ( dev - > prev_host_drive > = 200 ) {
2022-02-22 22:04:40 +01:00
/* Reload a previous image. */
2024-05-18 22:37:49 +02:00
if ( dev - > prev_host_drive = = 200 )
strcpy ( dev - > image_path , dev - > prev_image_path ) ;
2024-01-14 21:31:46 +01:00
# ifdef _WIN32
2024-05-18 19:42:00 +02:00
if ( dev - > prev_host_drive = = 200 ) {
if ( ( strlen ( dev - > image_path ) > = 1 ) & & ( dev - > image_path [ strlen ( dev - > image_path ) - 1 ] = = ' / ' ) )
dev - > image_path [ strlen ( dev - > image_path ) - 1 ] = ' \\ ' ;
}
2024-01-14 21:31:46 +01:00
# else
2024-05-18 19:42:00 +02:00
if ( dev - > prev_host_drive = = 200 ) {
if ( ( strlen ( dev - > image_path ) > = 1 ) & & ( dev - > image_path [ strlen ( dev - > image_path ) - 1 ] = = ' \\ ' ) )
dev - > image_path [ strlen ( dev - > image_path ) - 1 ] = ' / ' ;
}
2024-01-14 21:31:46 +01:00
# endif
2024-05-19 21:17:57 +02:00
if ( ( strlen ( dev - > image_path ) ! = 0 ) & & ( strstr ( dev - > image_path , " ioctl:// " ) = = dev - > image_path ) )
cdrom_ioctl_open ( dev , dev - > image_path ) ;
2024-05-18 19:42:00 +02:00
else
cdrom_image_open ( dev , dev - > image_path ) ;
2017-01-16 01:49:19 +01:00
2022-02-22 22:04:40 +01:00
cdrom_insert ( id ) ;
2018-10-17 05:29:48 +02:00
2024-05-19 21:17:57 +02:00
if ( strlen ( dev - > image_path ) = = 0 )
2022-02-22 22:04:40 +01:00
dev - > host_drive = 0 ;
else
2024-05-19 21:17:57 +02:00
dev - > host_drive = 200 ;
2018-04-25 23:51:13 +02:00
}
2018-10-17 05:29:48 +02:00
plat_cdrom_ui_update ( id , 1 ) ;
config_save ( ) ;
2018-04-25 23:51:13 +02:00
}