2024-05-20 03:52:53 +02: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 .
*
* This file is part of the 86 Box distribution .
*
* Win32 CD - ROM support via IOCTL .
*
*
*
* Authors : TheCollector1995 , < mariogplayer @ gmail . com > ,
* Miran Grca , < mgrca8 @ gmail . com >
*
* Copyright 2023 TheCollector1995 .
* Copyright 2023 Miran Grca .
*/
# include <inttypes.h>
2025-01-28 16:26:28 +01:00
# ifdef ENABLE_IOCTL_LOG
2024-05-20 03:52:53 +02:00
# include <stdarg.h>
2025-01-28 16:26:28 +01:00
# endif
2024-05-20 03:52:53 +02:00
# include <stdio.h>
# include <stdint.h>
# include <string.h>
# include <stdlib.h>
# include <wchar.h>
# define HAVE_STDARG_H
# include <86box/scsi_device.h>
# include <86box/cdrom.h>
2025-01-28 16:26:28 +01:00
# include <86box/log.h>
2024-05-20 03:52:53 +02:00
# include <86box/plat_unused.h>
# include <86box/plat_cdrom.h>
/* 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 . */
# define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f)
2025-01-28 16:26:28 +01:00
typedef struct ioctl_t {
cdrom_t * dev ;
void * log ;
2024-11-25 21:23:28 +01:00
int toc_valid ;
2025-01-28 16:26:28 +01:00
} ioctl_t ;
2024-05-20 03:52:53 +02:00
2025-01-28 16:26:28 +01:00
# ifdef ENABLE_IOCTL_LOG
int ioctl_do_log = ENABLE_IOCTL_LOG ;
2024-05-20 03:52:53 +02:00
void
2025-01-28 16:26:28 +01:00
ioctl_log ( void * priv , const char * fmt , . . . )
2024-05-20 03:52:53 +02:00
{
2025-01-28 16:26:28 +01:00
if ( ioctl_do_log ) {
va_list ap ;
2024-05-20 03:52:53 +02:00
va_start ( ap , fmt ) ;
2025-01-28 16:26:28 +01:00
log_out ( priv , fmt , ap ) ;
2024-05-20 03:52:53 +02:00
va_end ( ap ) ;
}
}
# else
2025-01-28 16:26:28 +01:00
# define ioctl_log(priv, fmt, ...)
2024-05-20 03:52:53 +02:00
# endif
2025-01-28 16:26:28 +01:00
/* Internal functions. */
static void
ioctl_close_handle ( UNUSED ( const ioctl_t * ioctl ) )
{
return 0 ;
}
2024-05-20 03:52:53 +02:00
static int
2025-01-28 16:26:28 +01:00
ioctl_open_handle ( UNUSED ( ioctl_t * ioctl ) )
2024-05-20 03:52:53 +02:00
{
return 0 ;
}
2025-01-28 16:26:28 +01:00
static void
ioctl_read_toc ( ioctl_t * ioctl )
{
if ( ! ioctl - > toc_valid ) {
ioctl - > toc_valid = 1 ;
}
}
/* Shared functions. */
2024-05-20 03:52:53 +02:00
static int
2025-01-28 16:26:28 +01:00
ioctl_get_track_info ( UNUSED ( const void * local ) , UNUSED ( const uint32_t track ) ,
UNUSED ( int end ) , UNUSED ( track_info_t * ti ) )
2024-05-20 03:52:53 +02:00
{
return 0 ;
}
static void
2025-01-28 16:26:28 +01:00
ioctl_get_raw_track_info ( const void * local , UNUSED ( int * num ) , UNUSED ( uint8_t * rti ) )
2024-05-20 03:52:53 +02:00
{
2025-01-28 16:26:28 +01:00
ioctl_t * ioctl = ( ioctl_t * ) local ;
2024-11-25 21:23:28 +01:00
if ( ! ioctl - > toc_valid )
ioctl - > toc_valid = 1 ;
}
2025-01-28 16:26:28 +01:00
static void
ioctl_get_raw_track_info ( UNUSED ( const void * local ) , int * num , uint8_t * rti )
2024-11-25 21:23:28 +01:00
{
* num = 1 ;
memset ( rti , 0x00 , 11 ) ;
2024-05-20 03:52:53 +02:00
}
2025-01-28 16:26:28 +01:00
static int
ioctl_is_track_pre ( const void * local , const uint32_t sector )
2024-05-20 03:52:53 +02:00
{
2025-01-28 16:26:28 +01:00
ioctl_t * ioctl = ( ioctl_t * ) local ;
2024-05-20 03:52:53 +02:00
2024-11-25 21:23:28 +01:00
plat_cdrom_read_toc ( ioctl ) ;
2025-01-28 16:26:28 +01:00
const int ret = 0 ;
2024-05-20 03:52:53 +02:00
2025-01-28 16:26:28 +01:00
ioctl_log ( " plat_cdrom_is_track_audio(%08X): %i \n " , sector , ret ) ;
2024-05-20 03:52:53 +02:00
return ret ;
}
2025-01-28 16:26:28 +01:00
static int
ioctl_read_sector ( const void * local , uint8_t * buffer , uint32_t const sector )
2024-05-20 03:52:53 +02:00
{
2025-01-28 16:26:28 +01:00
ioctl_t * ioctl = ( ioctl_t * ) local ;
2024-11-25 21:23:28 +01:00
2025-01-28 16:26:28 +01:00
plat_cdrom_open ( ioctl ) ;
2024-05-20 03:52:53 +02:00
2025-01-28 16:26:28 +01:00
/* Raw */
ioctl_log ( " Raw \n " ) ;
2024-05-20 03:52:53 +02:00
2025-01-28 16:26:28 +01:00
plat_cdrom_close ( ioctl ) ;
2024-05-20 03:52:53 +02:00
2025-01-28 16:26:28 +01:00
ioctl_log ( " ReadSector sector=%d. \n " , sector ) ;
return 0 ;
2024-05-20 03:52:53 +02:00
}
2025-01-28 16:26:28 +01:00
static uint8_t
ioctl_get_track_type ( UNUSED ( const void * local ) , UNUSED ( const uint32_t sector ) )
2024-05-20 03:52:53 +02:00
{
2025-01-28 16:26:28 +01:00
return 0x00 ;
2024-05-20 03:52:53 +02:00
}
2025-01-28 16:26:28 +01:00
static uint32_t
ioctl_get_last_block ( const void * local )
2024-05-20 03:52:53 +02:00
{
2025-01-28 16:26:28 +01:00
ioctl_t * ioctl = ( ioctl_t * ) local ;
2024-11-25 21:23:28 +01:00
2025-01-28 16:26:28 +01:00
ioctl_read_toc ( ioctl ) ;
2024-05-20 03:52:53 +02:00
return 0x00000000 ;
}
2025-01-28 16:26:28 +01:00
static int
ioctl_read_dvd_structure ( UNUSED ( const void * local ) , UNUSED ( const uint8_t layer ) , UNUSED ( const uint8_t format ) ,
UNUSED ( uint8_t * buffer ) , UNUSED ( uint32_t * info ) )
2024-05-20 03:52:53 +02:00
{
2025-01-28 16:26:28 +01:00
return - 0x00052100 ;
2024-05-20 03:52:53 +02:00
}
2025-01-28 16:26:28 +01:00
static int
ioctl_is_dvd ( UNUSED ( const void * local ) )
2024-05-20 03:52:53 +02:00
{
2025-01-28 16:26:28 +01:00
return 0 ;
2024-05-20 03:52:53 +02:00
}
2025-01-28 16:26:28 +01:00
static int
ioctl_has_audio ( UNUSED ( const void * local ) )
2024-05-20 03:52:53 +02:00
{
2025-01-28 16:26:28 +01:00
return 0 ;
2024-05-20 03:52:53 +02:00
}
2025-01-28 16:26:28 +01:00
static int
ioctl_ext_medium_changed ( UNUSED ( void * local ) )
2024-05-20 03:52:53 +02:00
{
2025-01-28 16:26:28 +01:00
#if 0
ioctl_t * ioctl = ( ioctl_t * ) local ;
# endif
int ret = 0 ;
ioctl_log ( " ioctl_ext_medium_changed(): %i \n " , ret ) ;
2024-05-20 03:52:53 +02:00
2025-01-28 16:26:28 +01:00
return ret ;
2024-05-20 03:52:53 +02:00
}
2025-01-28 16:26:28 +01:00
static void
ioctl_close ( void * local )
2024-05-20 03:52:53 +02:00
{
2025-01-28 16:26:28 +01:00
ioctl_t * ioctl = ( ioctl_t * ) local ;
2024-05-20 03:52:53 +02:00
2025-01-28 16:26:28 +01:00
ioctl_close_handle ( ioctl ) ;
ioctl - > handle = NULL ;
2024-11-25 21:23:28 +01:00
2025-01-28 16:26:28 +01:00
ioctl_log ( ioctl - > log , " Log closed \n " ) ;
2024-11-25 21:23:28 +01:00
2025-01-28 16:26:28 +01:00
log_close ( ioctl - > log ) ;
ioctl - > log = NULL ;
2024-05-20 03:52:53 +02:00
}
2025-01-28 16:26:28 +01:00
static const cdrom_ops_t ioctl_ops = {
ioctl_get_track_info ,
ioctl_get_raw_track_info ,
ioctl_is_track_pre ,
ioctl_read_sector ,
ioctl_get_track_type ,
ioctl_get_last_block ,
ioctl_read_dvd_structure ,
ioctl_is_dvd ,
ioctl_has_audio ,
ioctl_ext_medium_changed ,
ioctl_close
} ;
2024-05-20 03:52:53 +02:00
2025-01-28 16:26:28 +01:00
/* Public functions. */
void *
ioctl_open ( cdrom_t * dev , const char * drv )
2024-05-20 03:52:53 +02:00
{
2025-01-28 16:26:28 +01:00
ioctl_t * ioctl = ( ioctl_t * ) calloc ( 1 , sizeof ( ioctl_t ) ) ;
2024-05-20 03:52:53 +02:00
2025-01-28 16:26:28 +01:00
if ( ioctl ! = NULL ) {
char n [ 1024 ] = { 0 } ;
2024-11-25 21:23:28 +01:00
2025-01-28 16:26:28 +01:00
sprintf ( n , " CD-ROM %i IOCtl " , dev - > id + 1 ) ;
ioctl - > log = log_open ( n ) ;
2024-05-20 03:52:53 +02:00
2025-01-28 16:26:28 +01:00
memset ( ioctl - > path , 0x00 , sizeof ( ioctl - > path ) ) ;
2024-11-25 21:23:28 +01:00
2025-01-28 16:26:28 +01:00
wsprintf ( ioctl - > path , L " %S " , & ( drv [ 8 ] ) ) ;
ioctl_log ( ioctl - > log , " Path is %S \n " , ioctl - > path ) ;
2024-05-20 03:52:53 +02:00
2025-01-28 16:26:28 +01:00
ioctl - > dev = dev ;
ioctl - > toc_valid = 0 ;
2024-11-25 21:23:28 +01:00
2025-01-28 16:26:28 +01:00
dev - > ops = & ioctl_ops ;
}
return ioctl ;
2024-11-25 21:23:28 +01:00
}