diff --git a/src/Makefile.local b/src/Makefile.local index 1b57344..b969522 100644 --- a/src/Makefile.local +++ b/src/Makefile.local @@ -10,7 +10,7 @@ # settings, so we can avoid changing the main one for all of # our local setups. # -# Version: @(#)Makefile.local 1.0.9 2018/09/15 +# Version: @(#)Makefile.local 1.0.10 2018/10/16 # # Author: Fred N. van Kempen, # @@ -79,16 +79,18 @@ STUFF := # -DENABLE_ZIP_LOG=n enables logging for that module, sets level n # -DENABLE_CDROM_LOG=n enables logging for that module, sets level n # -DENABLE_CDROM_IMAGE_LOG=n enables logging for that module, sets level n -# -DENABLE_CDROM_IOCTL_LOG=n enables logging for that module, sets level n +# -DENABLE_CDROM_HOST_LOG=n enables logging for that module, sets level n # -DENABLE_SOUND_LOG=n enables logging for that module, sets level n # -DENABLE_SOUND_MIDI_LOG=n enables logging for that module, sets level n # -DENABLE_SOUND_DEV_LOG=n enables logging for that module, sets level n # -DENABLE_NETWORK_LOG=n enables logging for that module, sets level n # -DENABLE_NETWORK_DEV_LOG=n enables logging for that module, sets level n # -DENABLE_SCSI_LOG=n enables logging for that module, sets level n -# -DENABLE_SCSI_DISK_LOG=n enables logging for that module, sets level n # -DENABLE_SCSI_DEV_LOG=n enables logging for that module, sets level n +# -DENABLE_SCSI_CDROM_LOG=n enables logging for that module, sets level n +# -DENABLE_SCSI_DISK_LOG=n enables logging for that module, sets level n # -DENABLE_VIDEO_LOG=n enables logging for that module, sets level n +# -DENABLE_VIDEO_DEV_LOG=n enables logging for that module, sets level n EXTRAS := diff --git a/src/config.c b/src/config.c index 77f3cf6..86ab055 100644 --- a/src/config.c +++ b/src/config.c @@ -12,7 +12,7 @@ * it on Windows XP, and possibly also Vista. Use the * -DANSI_CFG for use on these systems. * - * Version: @(#)config.c 1.0.36 2018/10/14 + * Version: @(#)config.c 1.0.37 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -691,10 +691,10 @@ load_network(const char *cat) config_delete_var(cat, "net_pcap_device"); } if (p != NULL) { - if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) { + if ((network_card_to_id(p) == -1) || (network_ndev == 1)) { if ((network_ndev == 1) && strcmp(network_host, "none")) { ui_msgbox(MBX_ERROR, (wchar_t *)IDS_ERR_PCAP_NO); - } else if (network_dev_to_id(p) == -1) { + } else if (network_card_to_id(p) == -1) { ui_msgbox(MBX_ERROR, (wchar_t *)IDS_ERR_PCAP_DEV); } diff --git a/src/devices/cdrom/cdrom.c b/src/devices/cdrom/cdrom.c index deebefc..8742bcf 100644 --- a/src/devices/cdrom/cdrom.c +++ b/src/devices/cdrom/cdrom.c @@ -8,7 +8,7 @@ * * Generic interface for CD-ROM/DVD/BD implementations. * - * Version: @(#)cdrom.c 1.0.19 2018/10/16 + * Version: @(#)cdrom.c 1.0.21 2018/10/17 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -59,7 +59,7 @@ #ifdef ENABLE_CDROM_LOG -int cdrom_do_log = ENABLE_CDROM_LOG; +int cdrom_do_log = ENABLE_CDROM_LOG; #endif @@ -138,9 +138,13 @@ cdrom_playing_completed(cdrom_t *dev) { dev->prev_status = dev->cd_status; - dev->cd_status = dev->ops->status(dev); - if (((dev->prev_status == CD_STATUS_PLAYING) || (dev->prev_status == CD_STATUS_PAUSED)) && - ((dev->cd_status != CD_STATUS_PLAYING) && (dev->cd_status != CD_STATUS_PAUSED))) + if (dev->ops && dev->ops->status) + dev->cd_status = dev->ops->status(dev); + + if (((dev->prev_status == CD_STATUS_PLAYING) || + (dev->prev_status == CD_STATUS_PAUSED)) && + ((dev->cd_status != CD_STATUS_PLAYING) && + (dev->cd_status != CD_STATUS_PAUSED))) return 1; return 0; @@ -196,7 +200,9 @@ cdrom_hard_reset(void) if (dev->host_drive == 200) { cdrom_image_open(dev, dev->image_path); - cdrom_image_reset(dev); + + if (dev->reset) + dev->reset(dev); } else cdrom_null_open(dev); } @@ -206,28 +212,6 @@ cdrom_hard_reset(void) } -void -cdrom_close_handler(uint8_t id) -{ - cdrom_t *dev = &cdrom[id]; - - if (! dev) - return; - - switch (dev->host_drive) { - case 200: - cdrom_image_close(dev); - break; - - default: - null_close(dev); - break; - } - - dev->ops = NULL; -} - - void cdrom_close(void) { @@ -237,8 +221,8 @@ cdrom_close(void) for (i = 0; i < CDROM_NUM; i++) { dev = &cdrom[i]; - if (dev->ops) - cdrom_close_handler(i); + if (dev->ops && dev->ops->close) + dev->ops->close(dev); if (dev->close) dev->close(dev->p); @@ -291,9 +275,14 @@ cdrom_eject(uint8_t id) dev->prev_host_drive = dev->host_drive; dev->host_drive = 0; - dev->ops->exit(dev); - cdrom_close_handler(id); + if (dev->ops && dev->ops->eject) + dev->ops->eject(dev); + + if (dev->ops && dev->ops->close) + dev->ops->close(dev); + memset(dev->image_path, 0, sizeof(dev->image_path)); + cdrom_null_open(dev); cdrom_insert(id); @@ -305,7 +294,7 @@ void cdrom_reload(uint8_t id) { cdrom_t *dev = &cdrom[id]; -#ifdef USE_CDROM_IOCTL +#ifdef USE_HOST_CDROM int new_cdrom_drive; #endif @@ -315,7 +304,9 @@ cdrom_reload(uint8_t id) return; } - cdrom_close_handler(id); + if (dev->ops && dev->ops->close) + dev->ops->close(dev); + memset(dev->image_path, 0, sizeof(dev->image_path)); if (dev->prev_host_drive == 200) { @@ -331,22 +322,35 @@ cdrom_reload(uint8_t id) dev->host_drive = 0; else dev->host_drive = 200; -#ifdef USE_CDROM_IOCTL +#ifdef USE_HOST_CDROM } else { /* Reload the previous host drive. */ new_cdrom_drive = dev->prev_host_drive; - ioctl_open(id, new_cdrom_drive); + cdrom_host_open(dev, new_cdrom_drive); if (dev->bus_type) { /* Signal disc change to the emulated machine. */ - cdrom_insert(dev); + cdrom_insert(id); } - - dev->new_cdrom_drive; #endif } } +void +cdrom_reset_bus(int bus) +{ + cdrom_t *dev; + int i; + + for (i = 0; i < CDROM_NUM; i++) { + dev = &cdrom[i]; + + if (dev->bus_type == bus) + dev->reset(dev); + } +} + + int cdrom_string_to_bus(const char *str) { diff --git a/src/devices/cdrom/cdrom.h b/src/devices/cdrom/cdrom.h index 487c99c..c0a3a98 100644 --- a/src/devices/cdrom/cdrom.h +++ b/src/devices/cdrom/cdrom.h @@ -8,7 +8,7 @@ * * Definitions for the CDROM module.. * - * Version: @(#)cdrom.h 1.0.12 2018/10/15 + * Version: @(#)cdrom.h 1.0.14 2018/10/17 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -38,20 +38,34 @@ #define EMU_CDROM_H -#define CDROM_NUM 4 +#define CDROM_NUM 4 -#define CDROM_SPEED_DEFAULT 8 +#define CDROM_SPEED_DEFAULT 8 -#define CD_STATUS_EMPTY 0 -#define CD_STATUS_DATA_ONLY 1 -#define CD_STATUS_PLAYING 2 -#define CD_STATUS_PAUSED 3 -#define CD_STATUS_STOPPED 4 +#define CD_STATUS_EMPTY 0 +#define CD_STATUS_DATA_ONLY 1 +#define CD_STATUS_PLAYING 2 +#define CD_STATUS_PAUSED 3 +#define CD_STATUS_STOPPED 4 -#define BUF_SIZE 32768 +#define BUF_SIZE 32768 -#define CDROM_IMAGE 200 +#define CDROM_IMAGE 200 + + +/* + * The addresses sent from the guest are absolute, ie. a LBA of 0 + * corresponds to an MSF of 00:00:00, or else 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) #ifdef __cplusplus @@ -77,20 +91,27 @@ typedef struct { int (*medium_changed)(struct cdrom *dev); int (*media_type_id)(struct cdrom *dev); - int (*audio_callback)(struct cdrom *dev, int16_t *output, int len); - void (*audio_stop)(struct cdrom *dev); - int (*readtoc)(struct cdrom *dev, uint8_t *b, uint8_t starttrack, int msf, int maxlen, int single); - int (*readtoc_session)(struct cdrom *dev, uint8_t *b, int msf, int maxlen); - int (*readtoc_raw)(struct cdrom *dev, uint8_t *b, int maxlen); - uint8_t (*getcurrentsubchannel)(struct cdrom *dev, uint8_t *b, int msf); - int (*readsector_raw)(struct cdrom *dev, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len); - uint8_t (*playaudio)(struct cdrom *dev, uint32_t pos, uint32_t len, int ismsf); - void (*pause)(struct cdrom *dev); - void (*resume)(struct cdrom *dev); uint32_t (*size)(struct cdrom *dev); int (*status)(struct cdrom *dev); void (*stop)(struct cdrom *dev); - void (*exit)(struct cdrom *dev); + void (*close)(struct cdrom *dev); + + void (*eject)(struct cdrom *dev); + void (*load)(struct cdrom *dev); + + int (*readtoc)(struct cdrom *dev, uint8_t *b, uint8_t starttrack, int msf, int maxlen, int single); + int (*readtoc_session)(struct cdrom *dev, uint8_t *b, int msf, int maxlen); + int (*readtoc_raw)(struct cdrom *dev, uint8_t *b, int maxlen); + + uint8_t (*audio_play)(struct cdrom *dev, uint32_t pos, uint32_t len, int ismsf); + void (*audio_stop)(struct cdrom *dev); + void (*audio_pause)(struct cdrom *dev); + void (*audio_resume)(struct cdrom *dev); + int (*audio_callback)(struct cdrom *dev, int16_t *output, int len); + + uint8_t (*getcurrentsubchannel)(struct cdrom *dev, uint8_t *b, int msf); + + int (*readsector_raw)(struct cdrom *dev, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len); } cdrom_ops_t; /* Define the generic CD-ROM drive. */ @@ -125,10 +146,11 @@ typedef struct cdrom { const cdrom_ops_t *ops; /* device ops */ - void *image; /* opaque image data */ + void *local; /* local data for handler */ + + void (*reset)(struct cdrom *); void *p; - void (*insert)(void *p); void (*close)(void *p); uint32_t (*get_volume)(void *p, int channel); @@ -150,37 +172,42 @@ typedef struct { extern const cdrom_speed_t cdrom_speeds[]; extern cdrom_t cdrom[CDROM_NUM]; +#ifdef USE_HOST_CDROM +extern uint8_t cdrom_host_drive_available[26]; +extern uint8_t cdrom_host_drive_available_num; +#endif -extern void cdrom_log(int level, const char *fmt, ...); -extern int cdrom_speed_idx(int realspeed); +extern void cdrom_global_init(void); +extern void cdrom_global_reset(void); +extern void cdrom_hard_reset(void); +extern void cdrom_close(void); +extern void cdrom_reset_bus(int bus); extern int cdrom_string_to_bus(const char *str); extern const char *cdrom_bus_to_string(int bus); +extern void cdrom_log(int level, const char *fmt, ...); +extern int cdrom_speed_idx(int realspeed); + extern int cdrom_lba_to_msf_accurate(int lba); extern double cdrom_seek_time(cdrom_t *dev); extern void cdrom_seek(cdrom_t *dev, uint32_t pos); extern int cdrom_playing_completed(cdrom_t *dev); -extern void cdrom_close_handler(uint8_t id); extern void cdrom_insert(uint8_t id); extern void cdrom_eject(uint8_t id); extern void cdrom_reload(uint8_t id); extern int cdrom_image_open(cdrom_t *dev, const wchar_t *fn); -extern void cdrom_image_close(cdrom_t *dev); -extern void cdrom_image_reset(cdrom_t *dev); -extern void cdrom_update_cdb(uint8_t *cdb, int lba_pos, - int number_of_blocks); +#ifdef USE_HOST_CDROM +extern void cdrom_host_init(void); +extern int cdrom_host_open(cdrom_t *dev, char d); +#endif -extern int find_cdrom_for_scsi_id(uint8_t scsi_id); - -extern void cdrom_close(void); -extern void cdrom_global_init(void); -extern void cdrom_global_reset(void); -extern void cdrom_hard_reset(void); extern void scsi_cdrom_drive_reset(int c); +extern void scsi_cdrom_update_cdb(uint8_t *cdb, int lba_pos, + int number_of_blocks); #ifdef __cplusplus } diff --git a/src/devices/cdrom/cdrom_image.cpp b/src/devices/cdrom/cdrom_image.cpp index 63ac0e1..c592976 100644 --- a/src/devices/cdrom/cdrom_image.cpp +++ b/src/devices/cdrom/cdrom_image.cpp @@ -8,7 +8,7 @@ * * CD-ROM image support. * - * Version: @(#)cdrom_image.cpp 1.0.12 2018/10/16 + * Version: @(#)cdrom_image.cpp 1.0.13 2018/10/17 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -81,12 +81,6 @@ cdrom_image_log(UNUSED(int level), UNUSED(const char *fmt), ...) #define CD_STATUS_STOPPED 4 -/* 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) - - #pragma pack(push,1) typedef struct { uint8_t user_data[2048], @@ -145,7 +139,7 @@ static uint8_t extra_buffer[296]; static int audio_callback(cdrom_t *dev, int16_t *output, int len) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; int ret = 1; if (!dev->sound_on || (dev->cd_state != CD_PLAYING) || dev->img_is_iso) { @@ -197,7 +191,7 @@ audio_stop(cdrom_t *dev) /* audio_stop */ static uint8_t audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; int number; uint8_t attr; TMSF tmsf; @@ -256,7 +250,7 @@ audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int ismsf) static void audio_pause(cdrom_t *dev) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; if (!img || dev->img_is_iso) return; @@ -268,7 +262,7 @@ audio_pause(cdrom_t *dev) static void audio_resume(cdrom_t *dev) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; if (!img || dev->img_is_iso) return; @@ -280,7 +274,7 @@ audio_resume(cdrom_t *dev) static int image_ready(cdrom_t *dev) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; if (!img || (wcslen(dev->image_path) == 0)) return 0; @@ -292,7 +286,7 @@ image_ready(cdrom_t *dev) static int image_get_last_block(cdrom_t *dev) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; int first_track, last_track; int number, c; unsigned char attr; @@ -326,7 +320,7 @@ image_medium_changed(UNUSED(cdrom_t *dev)) static uint8_t image_getcurrentsubchannel(cdrom_t *dev, uint8_t *b, int msf) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; uint8_t attr, track, index, ret; TMSF relPos, absPos; uint32_t cdpos; @@ -384,7 +378,7 @@ image_getcurrentsubchannel(cdrom_t *dev, uint8_t *b, int msf) static int image_is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; uint8_t attr; TMSF tmsf; int m, s, f; @@ -459,7 +453,7 @@ is_legal(UNUSED(int id), int type, int flags, int audio, int mode2) static void read_sector_to_buffer(cdrom_t *dev, uint8_t *rbuf, uint32_t msf, uint32_t lba, int mode2, int len) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; uint8_t *bb = rbuf; img->ReadSector(rbuf + 16, false, lba); @@ -488,7 +482,7 @@ read_sector_to_buffer(cdrom_t *dev, uint8_t *rbuf, uint32_t msf, uint32_t lba, i static void read_audio(cdrom_t *dev, uint32_t lba, uint8_t *b) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; if (img->GetSectorSize(lba) == 2352) img->ReadSector(raw_buffer, true, lba); @@ -504,7 +498,7 @@ read_audio(cdrom_t *dev, uint32_t lba, uint8_t *b) static void read_mode1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; if ((dev->img_is_iso) || (img->GetSectorSize(lba) == 2048)) read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2048); @@ -557,7 +551,7 @@ read_mode1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int static void read_mode2_non_xa(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; if ((dev->img_is_iso) || (img->GetSectorSize(lba) == 2336)) read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2336); @@ -602,7 +596,7 @@ read_mode2_non_xa(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t m static void read_mode2_xa_form1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; if ((dev->img_is_iso) || (img->GetSectorSize(lba) == 2048)) read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2048); @@ -653,7 +647,7 @@ read_mode2_xa_form1(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t static void read_mode2_xa_form2(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t msf, int mode2, uint8_t *b) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; if ((dev->img_is_iso) || (img->GetSectorSize(lba) == 2324)) read_sector_to_buffer(dev, raw_buffer, msf, lba, mode2, 2324); @@ -695,10 +689,10 @@ read_mode2_xa_form2(cdrom_t *dev, int cdrom_sector_flags, uint32_t lba, uint32_t static int -image_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, - int cdrom_sector_flags, int *len) +image_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, + int cdrom_sector_type, int cdrom_sector_flags, int *len) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; uint8_t *b, *temp_b; uint32_t msf, lba; int audio, mode2; @@ -857,7 +851,7 @@ image_size(cdrom_t *dev) static int image_readtoc(cdrom_t *dev, unsigned char *b, unsigned char starttrack, int msf, UNUSED(int maxlen), int single) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; int number, len = 4; int c, d, first_track, last_track; uint32_t temp; @@ -920,7 +914,7 @@ image_readtoc(cdrom_t *dev, unsigned char *b, unsigned char starttrack, int msf, static int image_readtoc_session(cdrom_t *dev, unsigned char *b, int msf, int maxlen) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; int number, len = 4; uint8_t attr; uint32_t temp; @@ -961,7 +955,7 @@ image_readtoc_session(cdrom_t *dev, unsigned char *b, int msf, int maxlen) static int image_readtoc_raw(cdrom_t *dev, unsigned char *b, UNUSED(int maxlen)) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; int first_track, last_track; int number, track, len = 4; uint8_t attr; @@ -997,7 +991,7 @@ image_readtoc_raw(cdrom_t *dev, unsigned char *b, UNUSED(int maxlen)) static int image_status(cdrom_t *dev) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; if (!img) return CD_STATUS_EMPTY; @@ -1025,7 +1019,7 @@ image_status(cdrom_t *dev) static void image_stop(cdrom_t *dev) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; if (!img || dev->img_is_iso) return; @@ -1034,16 +1028,16 @@ image_stop(cdrom_t *dev) static void -image_exit(cdrom_t *dev) +image_close(cdrom_t *dev) { - CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image; + CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->local; -INFO("CDROM: image_exit(%ls)\n", dev->image_path); +INFO("CDROM: image_close(%ls)\n", dev->image_path); dev->cd_state = CD_STOPPED; if (img) { delete img; - dev->image = NULL; + dev->local = NULL; } dev->ops = NULL; @@ -1068,20 +1062,27 @@ static const cdrom_ops_t cdrom_image_ops = { image_ready, image_medium_changed, image_media_type_id, - audio_callback, - audio_stop, - image_readtoc, - image_readtoc_session, - image_readtoc_raw, - image_getcurrentsubchannel, - image_readsector_raw, - audio_play, - audio_pause, - audio_resume, + image_size, image_status, image_stop, - image_exit + image_close, + + NULL, + NULL, + + image_readtoc, + image_readtoc_session, + image_readtoc_raw, + + audio_play, + audio_stop, + audio_pause, + audio_resume, + audio_callback, + + image_getcurrentsubchannel, + image_readsector_raw }; @@ -1100,14 +1101,16 @@ cdrom_image_open(cdrom_t *dev, const wchar_t *fn) /* Create new instance of the CDROM_Image class. */ img = new CDROM_Interface_Image(); - dev->image = img; + dev->local = img; /* Convert filename and open the image. */ memset(temp, '\0', sizeof(temp)); wcstombs(temp, fn, sizeof(temp)); - if (!img->SetDevice(temp, false)) { - cdrom_image_close(dev); + if (! img->SetDevice(temp, false)) { + dev->ops->close(dev); + cdrom_set_null_handler(dev); + DEBUG("[f] image_open(): cdrom[%i]->ops = %08X\n", dev->id, dev->ops); return 1; } @@ -1119,24 +1122,8 @@ cdrom_image_open(cdrom_t *dev, const wchar_t *fn) dev->cdrom_capacity = image_get_last_block(dev) + 1; /* Attach this handler to the drive. */ + dev->reset = NULL; dev->ops = &cdrom_image_ops; return 0; } - - -void -cdrom_image_close(cdrom_t *dev) -{ -INFO("CDROM: image_close(%ls)\n", dev->image_path); - if (dev->ops->exit) - dev->ops->exit(dev); -} - - -void -cdrom_image_reset(UNUSED(cdrom_t *dev)) -{ -INFO("CDROM: image_reset(%ls)\n", dev->image_path); - /* Nothing to do. */ -} diff --git a/src/devices/cdrom/cdrom_image.h b/src/devices/cdrom/cdrom_image.h index d95e7a5..f2e7b89 100644 --- a/src/devices/cdrom/cdrom_image.h +++ b/src/devices/cdrom/cdrom_image.h @@ -8,7 +8,7 @@ * * Definitions for the CD-ROM image file handlers. * - * Version: @(#)cdrom_image.h 1.0.7 2018/10/16 + * Version: @(#)cdrom_image.h 1.0.7 2018/10/17 * * Authors: Miran Grca, * RichardG, @@ -48,12 +48,8 @@ extern int cdrom_image_do_log; extern void cdrom_image_log(int level, const char *fmt, ...); extern int image_open(cdrom_t *dev, wchar_t *fn); -extern void image_close(cdrom_t *dev); extern void image_reset(cdrom_t *dev); -extern int image_audio_callback(cdrom_t *dev, int16_t *output, int len); -extern void image_audio_stop(cdrom_t *dev); - #ifdef __cplusplus } #endif diff --git a/src/devices/cdrom/cdrom_null.c b/src/devices/cdrom/cdrom_null.c index 96ab94e..a009815 100644 --- a/src/devices/cdrom/cdrom_null.c +++ b/src/devices/cdrom/cdrom_null.c @@ -11,7 +11,7 @@ * * FIXME: TO BE REMOVED * - * Version: @(#)cdrom_null.c 1.0.5 2018/10/14 + * Version: @(#)cdrom_null.c 1.0.6 2018/10/17 * * Author: Miran Grca, * Sarah Walker, @@ -61,19 +61,31 @@ null_medium_changed(cdrom_t *dev) } -static uint8_t -null_getcurrentsubchannel(cdrom_t *dev, uint8_t *b, int msf) +static int +null_media_type_id(cdrom_t *dev) { - return(0x13); + return(0x70); +} + + +static uint32_t +null_size(cdrom_t *dev) +{ + return(0); } static int -null_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) +null_status(cdrom_t *dev) { - *len = 0; + return(CD_STATUS_EMPTY); +} - return(0); + +static void +null_close(cdrom_t *dev) +{ + dev->ops = NULL; } @@ -98,24 +110,48 @@ null_readtoc_raw(cdrom_t *dev, uint8_t *b, int maxlen) } -static uint32_t -null_size(cdrom_t *dev) +static uint8_t +null_getcurrentsubchannel(cdrom_t *dev, uint8_t *b, int msf) { - return(0); + return(0x13); } static int -null_status(cdrom_t *dev) +null_readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) { - return(CD_STATUS_EMPTY); + *len = 0; + + return(0); } -void -cdrom_null_reset(cdrom_t *dev) -{ -} +static cdrom_ops_t cdrom_null_ops = { + null_ready, + null_medium_changed, + null_media_type_id, + + null_size, + null_status, + NULL, + null_close, + + NULL, + NULL, + + null_readtoc, + null_readtoc_session, + null_readtoc_raw, + + NULL, + NULL, + NULL, + NULL, + NULL, + + null_getcurrentsubchannel, + null_readsector_raw +}; int @@ -128,45 +164,11 @@ cdrom_null_open(cdrom_t *dev) void -null_close(cdrom_t *dev) +cdrom_null_reset(cdrom_t *dev) { } -static -void null_exit(cdrom_t *dev) -{ -} - - -static int -null_media_type_id(cdrom_t *dev) -{ - return(0x70); -} - - -static cdrom_ops_t cdrom_null_ops = { - null_ready, - null_medium_changed, - null_media_type_id, - NULL, - NULL, - null_readtoc, - null_readtoc_session, - null_readtoc_raw, - null_getcurrentsubchannel, - null_readsector_raw, - NULL, - NULL, - NULL, - null_size, - null_status, - NULL, - null_exit -}; - - void cdrom_set_null_handler(cdrom_t *dev) { diff --git a/src/devices/cdrom/cdrom_null.h b/src/devices/cdrom/cdrom_null.h index 2dee939..c061f60 100644 --- a/src/devices/cdrom/cdrom_null.h +++ b/src/devices/cdrom/cdrom_null.h @@ -10,7 +10,7 @@ * * FIXME: TO BE REMOVED * - * Version: @(#)cdrom_null.h 1.0.3 2018/10/14 + * Version: @(#)cdrom_null.h 1.0.3 2018/10/17 * * Authors: Miran Grca, * Sarah Walker, @@ -45,8 +45,8 @@ extern "C" { #endif extern int cdrom_null_open(cdrom_t *dev); +//extern void null_close(cdrom_t *dev); extern void cdrom_null_reset(cdrom_t *dev); -extern void null_close(cdrom_t *dev); extern void cdrom_set_null_handler(cdrom_t *dev); diff --git a/src/devices/disk/hdc_ide_ata.c b/src/devices/disk/hdc_ide_ata.c index 65fff1a..5f7b96c 100644 --- a/src/devices/disk/hdc_ide_ata.c +++ b/src/devices/disk/hdc_ide_ata.c @@ -14,7 +14,7 @@ * Devices currently implemented are hard disk, CD-ROM and * ZIP IDE/ATAPI devices. * - * Version: @(#)hdc_ide_ata.c 1.0.24 2018/10/14 + * Version: @(#)hdc_ide_ata.c 1.0.25 2018/10/17 * * Authors: Miran Grca, * Sarah Walker, @@ -2438,7 +2438,7 @@ ide_init(const device_t *info) { DEBUG("Initializing IDE...\n"); - switch(info->local) { + switch(info->local & 255) { case 0: /* ISA, single-channel */ case 2: /* ISA, dual-channel */ case 3: /* ISA, dual-channel, optional 2nd channel */ diff --git a/src/devices/disk/zip.c b/src/devices/disk/zip.c index 764f5c9..5ccba6c 100644 --- a/src/devices/disk/zip.c +++ b/src/devices/disk/zip.c @@ -9,7 +9,7 @@ * Implementation of the Iomega ZIP drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)zip.c 1.0.17 2018/10/15 + * Version: @(#)zip.c 1.0.18 2018/10/17 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -2865,6 +2865,18 @@ zip_close(void) } +void +zip_reset_bus(int bus) +{ + int i; + + for (i = 0; i < ZIP_NUM; i++) { + if (zip_drives[i].bus_type == ZIP_BUS_ATAPI) + zip_reset(zip[i]); + } +} + + int zip_string_to_bus(const char *str) { diff --git a/src/devices/disk/zip.h b/src/devices/disk/zip.h index 036d097..2140ba9 100644 --- a/src/devices/disk/zip.h +++ b/src/devices/disk/zip.h @@ -9,7 +9,7 @@ * Implementation of the Iomega ZIP drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)zip.h 1.0.8 2018/10/14 + * Version: @(#)zip.h 1.0.9 2018/10/17 * * Author: Miran Grca, * @@ -135,6 +135,8 @@ extern void zip_insert(zip_t *dev); extern void zip_global_init(void); extern void zip_hard_reset(void); +extern void zip_reset_bus(int bus); + extern int zip_string_to_bus(const char *str); extern const char *zip_bus_to_string(int bus); diff --git a/src/devices/network/net_3c503.c b/src/devices/network/net_3c503.c index c3cf77d..3b8c791 100644 --- a/src/devices/network/net_3c503.c +++ b/src/devices/network/net_3c503.c @@ -8,7 +8,7 @@ * Implementation of the following network controllers: * - 3Com Etherlink II 3c503 (ISA 8-bit). * - * Version: @(#)net_3c503.c 1.0.2 2018/10/05 + * Version: @(#)net_3c503.c 1.0.3 2018/10/16 * * Based on @(#)3c503.cpp Carl (MAME) * @@ -46,7 +46,7 @@ #include #include #include -#define dbglog network_dev_log +#define dbglog network_card_log #include "../../emu.h" #include "../../io.h" #include "../../mem.h" diff --git a/src/devices/network/net_dp8390.c b/src/devices/network/net_dp8390.c index 7f8f9e4..10cbb50 100644 --- a/src/devices/network/net_dp8390.c +++ b/src/devices/network/net_dp8390.c @@ -8,7 +8,7 @@ * * Handling of the NatSemi DP8390 ethernet controller chip. * - * Version: @(#)net_dp8390.c 1.0.1 2018/09/14 + * Version: @(#)net_dp8390.c 1.0.2 2018/10/16 * * Authors: Fred N. van Kempen, * Peter Grehan, @@ -39,7 +39,7 @@ #include #include #include -#define dbglog network_dev_log +#define dbglog network_card_log #include "../../emu.h" #include "../../device.h" #include "../../ui/ui.h" diff --git a/src/devices/network/net_ne2000.c b/src/devices/network/net_ne2000.c index 10288a1..be93e4a 100644 --- a/src/devices/network/net_ne2000.c +++ b/src/devices/network/net_ne2000.c @@ -16,7 +16,7 @@ * * FIXME: move statbar calls to upper layer * - * Version: @(#)net_ne2000.c 1.0.12 2018/10/05 + * Version: @(#)net_ne2000.c 1.0.13 2018/10/16 * * Based on @(#)ne2k.cc v1.56.2.1 2004/02/02 22:37:22 cbothamy * @@ -53,7 +53,7 @@ #include #include #include -#define dbglog network_dev_log +#define dbglog network_card_log #include "../../emu.h" #include "../../io.h" #include "../../mem.h" diff --git a/src/devices/network/net_wd80x3.c b/src/devices/network/net_wd80x3.c index 6178eb2..b7f7b95 100644 --- a/src/devices/network/net_wd80x3.c +++ b/src/devices/network/net_wd80x3.c @@ -11,7 +11,7 @@ * - SMC/WD 8013EBT (ISA 16-bit); * - SMC/WD 8013EP/A (MCA). * - * Version: @(#)net_wd80x3.c 1.0.2 2018/10/05 + * Version: @(#)net_wd80x3.c 1.0.3 2018/10/16 * * Authors: Fred N. van Kempen, * TheCollector1995, @@ -44,7 +44,7 @@ #include #include #include -#define dbglog network_dev_log +#define dbglog network_card_log #include "../../emu.h" #include "../../io.h" #include "../../mem.h" diff --git a/src/devices/network/network.c b/src/devices/network/network.c index fbaca43..1dd21a4 100644 --- a/src/devices/network/network.c +++ b/src/devices/network/network.c @@ -12,7 +12,7 @@ * it should be malloc'ed and then linked to the NETCARD def. * Will be done later. * - * Version: @(#)network.c 1.0.12 2018/09/14 + * Version: @(#)network.c 1.0.13 2018/10/16 * * Author: Fred N. van Kempen, * @@ -96,7 +96,7 @@ netdev_t network_devs[32]; int network_do_log = ENABLE_NETWORK_LOG; #endif #ifdef ENABLE_NETWORK_DEV_LOG -int network_dev_do_log = ENABLE_NETWORK_DEV_LOG; +int network_card_do_log = ENABLE_NETWORK_DEV_LOG; #endif static mutex_t *network_mutex; static uint8_t *network_mac; @@ -172,12 +172,12 @@ network_log(int level, const char *fmt, ...) void -network_dev_log(int level, const char *fmt, ...) +network_card_log(int level, const char *fmt, ...) { #ifdef ENABLE_NETWORK_DEV_LOG va_list ap; - if (network_dev_do_log >= level) { + if (network_card_do_log >= level) { va_start(ap, fmt); pclog_ex(fmt, ap); va_end(ap); @@ -414,7 +414,7 @@ network_tx(uint8_t *bufp, int len) int -network_dev_to_id(const char *devname) +network_card_to_id(const char *devname) { int i = 0; diff --git a/src/devices/network/network.h b/src/devices/network/network.h index 6d8468d..7e42746 100644 --- a/src/devices/network/network.h +++ b/src/devices/network/network.h @@ -8,7 +8,7 @@ * * Definitions for the network module. * - * Version: @(#)network.h 1.0.5 2018/09/12 + * Version: @(#)network.h 1.0.6 2018/10/16 * * Author: Fred N. van Kempen, * @@ -79,8 +79,6 @@ extern "C" { #endif /* Global variables. */ -extern int network_do_log, /* config */ - network_dev_do_log; extern int network_ndev; extern netdev_t network_devs[32]; @@ -91,6 +89,7 @@ extern void network_poll(void); extern void network_busy(uint8_t set); extern void network_end(void); +extern void network_log(int level, const char *fmt, ...); extern void network_init(void); extern void network_attach(void *, uint8_t *, NETRXCB); extern void network_close(void); @@ -109,9 +108,8 @@ extern int net_slirp_reset(const netcard_t *, uint8_t *); extern void net_slirp_close(void); extern void net_slirp_in(uint8_t *, int); -extern void network_log(int lvl, const char *fmt, ...); -extern void network_dev_log(int lvl, const char *fmt, ...); -extern int network_dev_to_id(const char *); +extern void network_card_log(int level, const char *fmt, ...); +extern int network_card_to_id(const char *); extern int network_card_available(int); extern const char *network_card_getname(int); extern int network_card_has_config(int); diff --git a/src/devices/scsi/scsi.c b/src/devices/scsi/scsi.c index 9c03c66..d8c4ac5 100644 --- a/src/devices/scsi/scsi.c +++ b/src/devices/scsi/scsi.c @@ -8,7 +8,7 @@ * * Handling of the SCSI controllers. * - * Version: @(#)scsi.c 1.0.12 2018/10/14 + * Version: @(#)scsi.c 1.0.13 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -42,7 +42,7 @@ #include #include #define HAVE_STDARG_H -#define dbglog scsi_log +#define dbglog scsi_card_log #include "../../emu.h" #include "../../device.h" #include "../../plat.h" @@ -61,11 +61,8 @@ #endif -#ifdef ENABLE_SCSI_LOG -int scsi_do_log = ENABLE_SCSI_LOG; -#endif #ifdef ENABLE_SCSI_DEV_LOG -int scsi_dev_do_log = ENABLE_SCSI_DEV_LOG; +int scsi_card_do_log = ENABLE_SCSI_DEV_LOG; #endif @@ -151,27 +148,12 @@ scsi_card_has_config(int card) void -scsi_log(int level, const char *fmt, ...) -{ -#ifdef ENABLE_SCSI_LOG - va_list ap; - - if (scsi_do_log >= level) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } -#endif -} - - -void -scsi_dev_log(int level, const char *fmt, ...) +scsi_card_log(int level, const char *fmt, ...) { #ifdef ENABLE_SCSI_DEV_LOG va_list ap; - if (scsi_dev_do_log >= level) { + if (scsi_card_do_log >= level) { va_start(ap, fmt); pclog_ex(fmt, ap); va_end(ap); diff --git a/src/devices/scsi/scsi.h b/src/devices/scsi/scsi.h index 25d0ef0..0f55a1e 100644 --- a/src/devices/scsi/scsi.h +++ b/src/devices/scsi/scsi.h @@ -8,7 +8,7 @@ * * SCSI module definitions. * - * Version: @(#)scsi.h 1.0.8 2018/10/05 + * Version: @(#)scsi.h 1.0.9 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -39,7 +39,7 @@ #define EMU_SCSI_H -extern void scsi_log(int level, const char *fmt, ...); +extern void scsi_card_log(int level, const char *fmt, ...); extern int scsi_card_available(int card); extern const char *scsi_card_getname(int card); diff --git a/src/devices/scsi/scsi_aha154x.c b/src/devices/scsi/scsi_aha154x.c index 206eafb..e1e52fb 100644 --- a/src/devices/scsi/scsi_aha154x.c +++ b/src/devices/scsi/scsi_aha154x.c @@ -10,7 +10,7 @@ * made by Adaptec, Inc. These controllers were designed for * the ISA bus. * - * Version: @(#)scsi_aha154x.c 1.0.10 2018/10/05 + * Version: @(#)scsi_aha154x.c 1.0.11 2018/10/16 * * Based on original code from TheCollector1995 and Miran Grca. * @@ -44,7 +44,7 @@ #include #include #include -#define dbglog scsi_dev_log +#define dbglog scsi_card_log #include "../../emu.h" #include "../../io.h" #include "../../mem.h" @@ -56,8 +56,9 @@ #include "../system/dma.h" #include "../system/pic.h" #include "../system/mca.h" -#include "scsi_device.h" +#include "scsi.h" #include "scsi_aha154x.h" +#include "scsi_device.h" #include "scsi_x54x.h" diff --git a/src/devices/scsi/scsi_buslogic.c b/src/devices/scsi/scsi_buslogic.c index 934c054..47bfa95 100644 --- a/src/devices/scsi/scsi_buslogic.c +++ b/src/devices/scsi/scsi_buslogic.c @@ -13,7 +13,7 @@ * 1 - BT-545S ISA; * 2 - BT-958D PCI * - * Version: @(#)scsi_buslogic.c 1.0.12 2018/10/14 + * Version: @(#)scsi_buslogic.c 1.0.13 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -45,7 +45,7 @@ #include #include #include -#define dbglog scsi_dev_log +#define dbglog scsi_card_log #include "../../emu.h" #include "../../io.h" #include "../../mem.h" diff --git a/src/devices/scsi/scsi_cdrom.c b/src/devices/scsi/scsi_cdrom.c index 317f6a7..ceab118 100644 --- a/src/devices/scsi/scsi_cdrom.c +++ b/src/devices/scsi/scsi_cdrom.c @@ -8,7 +8,7 @@ * * Emulation of SCSI (and ATAPI) CD-ROM drives. * - * Version: @(#)scsi_cdrom.c 1.0.2 2018/10/16 + * Version: @(#)scsi_cdrom.c 1.0.2 2018/10/17 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -74,7 +74,7 @@ #define cdbufferb dev->buffer -scsi_cdrom_t *scsi_cdrom[CDROM_NUM] = { NULL, NULL, NULL, NULL }; +static scsi_cdrom_t *scsi_cdrom[CDROM_NUM] = { NULL, NULL, NULL, NULL }; #pragma pack(push,1) @@ -98,9 +98,16 @@ typedef struct { #pragma pack(pop) -/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ -const uint8_t scsi_cdrom_command_flags[0x100] = -{ +#ifdef ENABLE_SCSI_CDROM_LOG +int scsi_cdrom_do_log = ENABLE_SCSI_CDROM_LOG; +#endif + + +/* + * Table of all SCSI commands and their flags, + * needed for the new disc change / not ready handler. + */ +static const uint8_t command_flags[0x100] = { IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ 0, /* 0x02 */ @@ -187,14 +194,15 @@ const uint8_t scsi_cdrom_command_flags[0x100] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xF0-0xFF */ }; -static uint64_t scsi_cdrom_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE | - GPMODEP_CDROM_PAGE | - GPMODEP_CDROM_AUDIO_PAGE | - GPMODEP_CAPABILITIES_PAGE | - GPMODEP_ALL_PAGES); +static const uint64_t mode_sense_page_flags = + (GPMODEP_R_W_ERROR_PAGE | + GPMODEP_CDROM_PAGE | + GPMODEP_CDROM_AUDIO_PAGE | + GPMODEP_CAPABILITIES_PAGE | + GPMODEP_ALL_PAGES); -static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default = -{ { +static const mode_sense_pages_t mode_sense_pages_default = { + { { 0, 0 }, { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, { 0, 0 }, @@ -240,8 +248,8 @@ static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 2, 0xC2, 1, 0, 0, 0, 2, 0xC2, 0, 0, 0, 0 } } }; -static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default_scsi = -{ { +static const mode_sense_pages_t mode_sense_pages_default_scsi = { + { { 0, 0 }, { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, { 0, 0 }, @@ -287,8 +295,8 @@ static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_default_scsi = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 2, 0xC2, 1, 0, 0, 0, 2, 0xC2, 0, 0, 0, 0 } } }; -static const mode_sense_pages_t scsi_cdrom_mode_sense_pages_changeable = -{ { +static const mode_sense_pages_t mode_sense_pages_changeable = { + { { 0, 0 }, { GPMODE_R_W_ERROR_PAGE, 6, 0xFF, 0xFF, 0, 0, 0, 0 }, { 0, 0 }, @@ -340,20 +348,11 @@ static gesn_cdb_t *gesn_cdb; static gesn_event_header_t *gesn_event_header; -static void scsi_cdrom_command_complete(scsi_cdrom_t *dev); - -static void scsi_cdrom_mode_sense_load(scsi_cdrom_t *dev); - -static void scsi_cdrom_init(scsi_cdrom_t *dev); - +static void command_complete(scsi_cdrom_t *dev); +static void mode_sense_load(scsi_cdrom_t *dev); static void scsi_cdrom_callback(void *p); -#ifdef ENABLE_SCSI_CDROM_LOG -int scsi_cdrom_do_log = ENABLE_SCSI_CDROM_LOG; -#endif - - void scsi_cdrom_log(int level, const char *fmt, ...) { @@ -370,7 +369,7 @@ scsi_cdrom_log(int level, const char *fmt, ...) static void -scsi_cdrom_set_callback(scsi_cdrom_t *dev) +set_callback(scsi_cdrom_t *dev) { if (dev && dev->drv && (dev->drv->bus_type != CDROM_BUS_SCSI)) ide_set_callback(dev->drv->bus_id.ide_channel >> 1, dev->callback); @@ -378,7 +377,7 @@ scsi_cdrom_set_callback(scsi_cdrom_t *dev) static void -scsi_cdrom_set_signature(void *p) +set_signature(void *p) { scsi_cdrom_t *dev = (scsi_cdrom_t *) p; @@ -389,43 +388,9 @@ scsi_cdrom_set_signature(void *p) } -static void -scsi_cdrom_init(scsi_cdrom_t *dev) -{ - if (!dev) - return; - - /* Tell the scsi_cdrom_t struct what cdrom_drives element corresponds to it. */ - dev->drv = &cdrom[dev->id]; - - /* Do a reset (which will also rezero it). */ - scsi_cdrom_reset(dev); - - /* Configure the drive. */ - dev->requested_blocks = 1; - - dev->drv->bus_mode = 0; - if (dev->drv->bus_type >= CDROM_BUS_ATAPI) - dev->drv->bus_mode |= 2; - if (dev->drv->bus_type < CDROM_BUS_SCSI) - dev->drv->bus_mode |= 1; - DEBUG("CD-ROM %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode); - - dev->sense[0] = 0xf0; - dev->sense[7] = 10; - dev->status = READY_STAT | DSC_STAT; - dev->pos = 0; - dev->packet_status = 0xff; - scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = dev->unit_attention = 0; - dev->drv->cur_speed = dev->drv->speed_idx; - - scsi_cdrom_mode_sense_load(dev); -} - - /* Returns: 0 for none, 1 for PIO, 2 for DMA. */ static int -scsi_cdrom_current_mode(scsi_cdrom_t *dev) +current_mode(scsi_cdrom_t *dev) { if (dev->drv->bus_type == CDROM_BUS_SCSI) return 2; @@ -441,8 +406,8 @@ scsi_cdrom_current_mode(scsi_cdrom_t *dev) /* Translates ATAPI status (ERR_STAT flag) to SCSI status. */ -int -scsi_cdrom_err_stat_to_scsi(void *p) +static int +err_stat_to_scsi(void *p) { scsi_cdrom_t *dev = (scsi_cdrom_t *) p; @@ -454,8 +419,8 @@ scsi_cdrom_err_stat_to_scsi(void *p) /* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */ -int -scsi_cdrom_atapi_phase_to_scsi(scsi_cdrom_t *dev) +static int +atapi_phase_to_scsi(scsi_cdrom_t *dev) { if (dev->status & 8) { switch (dev->phase & 3) { @@ -480,7 +445,7 @@ scsi_cdrom_atapi_phase_to_scsi(scsi_cdrom_t *dev) static uint32_t -scsi_cdrom_get_channel(void *p, int channel) +get_channel(void *p, int channel) { scsi_cdrom_t *dev = (scsi_cdrom_t *) p; @@ -492,7 +457,7 @@ scsi_cdrom_get_channel(void *p, int channel) static uint32_t -scsi_cdrom_get_volume(void *p, int channel) +get_volume(void *p, int channel) { scsi_cdrom_t *dev = (scsi_cdrom_t *) p; @@ -504,7 +469,7 @@ scsi_cdrom_get_volume(void *p, int channel) static void -scsi_cdrom_mode_sense_load(scsi_cdrom_t *dev) +mode_sense_load(scsi_cdrom_t *dev) { wchar_t file_name[512]; FILE *f; @@ -512,15 +477,15 @@ scsi_cdrom_mode_sense_load(scsi_cdrom_t *dev) memset(&dev->ms_pages_saved, 0, sizeof(mode_sense_pages_t)); for (i = 0; i < 0x3f; i++) { - if (scsi_cdrom_mode_sense_pages_default.pages[i][1] != 0) { + if (mode_sense_pages_default.pages[i][1] != 0) { if (dev->drv->bus_type == CDROM_BUS_SCSI) memcpy(dev->ms_pages_saved.pages[i], - scsi_cdrom_mode_sense_pages_default_scsi.pages[i], - scsi_cdrom_mode_sense_pages_default_scsi.pages[i][1] + 2); + mode_sense_pages_default_scsi.pages[i], + mode_sense_pages_default_scsi.pages[i][1] + 2); else memcpy(dev->ms_pages_saved.pages[i], - scsi_cdrom_mode_sense_pages_default.pages[i], - scsi_cdrom_mode_sense_pages_default.pages[i][1] + 2); + mode_sense_pages_default.pages[i], + mode_sense_pages_default.pages[i][1] + 2); } } memset(file_name, 0, 512 * sizeof(wchar_t)); @@ -537,7 +502,7 @@ scsi_cdrom_mode_sense_load(scsi_cdrom_t *dev) static void -scsi_cdrom_mode_sense_save(scsi_cdrom_t *dev) +mode_sense_save(scsi_cdrom_t *dev) { FILE *f; wchar_t file_name[512]; @@ -555,8 +520,8 @@ scsi_cdrom_mode_sense_save(scsi_cdrom_t *dev) } -int -scsi_cdrom_read_capacity(void *p, uint8_t *cdb, uint8_t *buffer, uint32_t *len) +static int +read_capacity(void *p, uint8_t *cdb, uint8_t *buffer, uint32_t *len) { scsi_cdrom_t *dev = (scsi_cdrom_t *) p; int size = 0; @@ -576,7 +541,7 @@ scsi_cdrom_read_capacity(void *p, uint8_t *cdb, uint8_t *buffer, uint32_t *len) /*SCSI Mode Sense 6/10*/ static uint8_t -scsi_cdrom_mode_sense_read(scsi_cdrom_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) +mode_sense_read(scsi_cdrom_t *dev, uint8_t page_control, uint8_t page, uint8_t pos) { switch (page_control) { case 0: @@ -584,13 +549,13 @@ scsi_cdrom_mode_sense_read(scsi_cdrom_t *dev, uint8_t page_control, uint8_t page return dev->ms_pages_saved.pages[page][pos]; break; case 1: - return scsi_cdrom_mode_sense_pages_changeable.pages[page][pos]; + return mode_sense_pages_changeable.pages[page][pos]; break; case 2: if (dev->drv->bus_type == CDROM_BUS_SCSI) - return scsi_cdrom_mode_sense_pages_default_scsi.pages[page][pos]; + return mode_sense_pages_default_scsi.pages[page][pos]; else - return scsi_cdrom_mode_sense_pages_default.pages[page][pos]; + return mode_sense_pages_default.pages[page][pos]; break; } @@ -599,7 +564,7 @@ scsi_cdrom_mode_sense_read(scsi_cdrom_t *dev, uint8_t page_control, uint8_t page static uint32_t -scsi_cdrom_mode_sense(scsi_cdrom_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block_descriptor_len) +mode_sense(scsi_cdrom_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block_descriptor_len) { uint8_t page_control = (page >> 6) & 3; int i = 0, j = 0; @@ -620,9 +585,9 @@ scsi_cdrom_mode_sense(scsi_cdrom_t *dev, uint8_t *buf, uint32_t pos, uint8_t pag for (i = 0; i < 0x40; i++) { if ((page == GPMODE_ALL_PAGES) || (page == i)) { - if (scsi_cdrom_mode_sense_page_flags & (1LL << ((uint64_t) (page & 0x3f)))) { - buf[pos++] = scsi_cdrom_mode_sense_read(dev, page_control, i, 0); - msplen = scsi_cdrom_mode_sense_read(dev, page_control, i, 1); + if (mode_sense_page_flags & (1LL << ((uint64_t) (page & 0x3f)))) { + buf[pos++] = mode_sense_read(dev, page_control, i, 0); + msplen = mode_sense_read(dev, page_control, i, 1); buf[pos++] = msplen; DEBUG("CD-ROM %i: MODE SENSE: Page [%02X] length %i\n", dev->id, i, msplen); for (j = 0; j < msplen; j++) { @@ -637,7 +602,7 @@ scsi_cdrom_mode_sense(scsi_cdrom_t *dev, uint8_t *buf, uint32_t pos, uint8_t pag else buf[pos++] = ((dev->drv->cur_speed * 176) >> 8); } else - buf[pos++] = scsi_cdrom_mode_sense_read(dev, page_control, i, 2 + j); + buf[pos++] = mode_sense_read(dev, page_control, i, 2 + j); } } } @@ -648,7 +613,7 @@ scsi_cdrom_mode_sense(scsi_cdrom_t *dev, uint8_t *buf, uint32_t pos, uint8_t pag static void -scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) +update_request_length(scsi_cdrom_t *dev, int len, int block_len) { int32_t bt, min_len = 0; @@ -701,14 +666,14 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) static double -scsi_cdrom_bus_speed(scsi_cdrom_t *dev) +bus_speed(scsi_cdrom_t *dev) { if (dev->drv->bus_type == CDROM_BUS_SCSI) { dev->callback = -1LL; /* Speed depends on SCSI controller */ return 0.0; } else { /* TODO: Get the actual selected speed from IDE. */ - if (scsi_cdrom_current_mode(dev) == 2) + if (current_mode(dev) == 2) return 66666666.666666666666666; /* 66 MB/s MDMA-2 speed */ else return 8333333.333333333333333; /* 8.3 MB/s PIO-2 speed */ @@ -717,19 +682,19 @@ scsi_cdrom_bus_speed(scsi_cdrom_t *dev) static void -scsi_cdrom_command_bus(scsi_cdrom_t *dev) +command_bus(scsi_cdrom_t *dev) { dev->status = BUSY_STAT; dev->phase = 1; dev->pos = 0; dev->callback = 1LL * CDROM_TIME; - scsi_cdrom_set_callback(dev); + set_callback(dev); } static void -scsi_cdrom_command_common(scsi_cdrom_t *dev) +command_common(scsi_cdrom_t *dev) { double bytes_per_second, period; double dusec; @@ -755,7 +720,7 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) dev->id, (int64_t)period); period = period * ((double) TIMER_USEC); dev->callback += ((int64_t) period); - scsi_cdrom_set_callback(dev); + set_callback(dev); return; case 0x08: case 0x28: @@ -783,7 +748,7 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) bytes_per_second *= (double) dev->drv->cur_speed; break; default: - bytes_per_second = scsi_cdrom_bus_speed(dev); + bytes_per_second = bus_speed(dev); if (bytes_per_second == 0.0) { dev->callback = -1LL; /* Speed depends on SCSI controller */ return; @@ -799,49 +764,56 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) dev->callback += ((int64_t) dusec); } - scsi_cdrom_set_callback(dev); + set_callback(dev); } static void -scsi_cdrom_command_complete(scsi_cdrom_t *dev) +command_complete(scsi_cdrom_t *dev) { dev->packet_status = PHASE_COMPLETE; - scsi_cdrom_command_common(dev); + + command_common(dev); } static void -scsi_cdrom_command_read(scsi_cdrom_t *dev) +command_read(scsi_cdrom_t *dev) { dev->packet_status = PHASE_DATA_IN; - scsi_cdrom_command_common(dev); + + command_common(dev); + dev->total_read = 0; } static void -scsi_cdrom_command_read_dma(scsi_cdrom_t *dev) +command_read_dma(scsi_cdrom_t *dev) { dev->packet_status = PHASE_DATA_IN_DMA; - scsi_cdrom_command_common(dev); + + command_common(dev); + dev->total_read = 0; } static void -scsi_cdrom_command_write(scsi_cdrom_t *dev) +command_write(scsi_cdrom_t *dev) { dev->packet_status = PHASE_DATA_OUT; - scsi_cdrom_command_common(dev); + + command_common(dev); } static void -scsi_cdrom_command_write_dma(scsi_cdrom_t *dev) +command_write_dma(scsi_cdrom_t *dev) { dev->packet_status = PHASE_DATA_OUT_DMA; - scsi_cdrom_command_common(dev); + + command_common(dev); } @@ -849,38 +821,40 @@ scsi_cdrom_command_write_dma(scsi_cdrom_t *dev) len = Total transfer length; block_len = Length of a single block (it matters because media access commands on ATAPI); alloc_len = Allocated transfer length; - direction = Transfer direction (0 = read from host, 1 = write to host). */ + direction = Transfer direction (0 = read from host, 1 = write to host). +*/ static void -scsi_cdrom_data_command_finish(scsi_cdrom_t *dev, int len, int block_len, int alloc_len, int direction) +data_command_finish(scsi_cdrom_t *dev, int len, int block_len, int alloc_len, int direction) { DEBUG("CD-ROM %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", dev->id, dev->current_cdb[0], len, block_len, alloc_len, direction, dev->request_length); dev->pos = 0; + if (alloc_len >= 0) { if (alloc_len < len) len = alloc_len; } - if ((len == 0) || (scsi_cdrom_current_mode(dev) == 0)) { + if ((len == 0) || (current_mode(dev) == 0)) { if (dev->drv->bus_type != CDROM_BUS_SCSI) dev->packet_len = 0; - scsi_cdrom_command_complete(dev); + command_complete(dev); } else { - if (scsi_cdrom_current_mode(dev) == 2) { + if (current_mode(dev) == 2) { if (dev->drv->bus_type != CDROM_BUS_SCSI) dev->packet_len = alloc_len; if (direction == 0) - scsi_cdrom_command_read_dma(dev); + command_read_dma(dev); else - scsi_cdrom_command_write_dma(dev); + command_write_dma(dev); } else { - scsi_cdrom_update_request_length(dev, len, block_len); + update_request_length(dev, len, block_len); if (direction == 0) - scsi_cdrom_command_read(dev); + command_read(dev); else - scsi_cdrom_command_write(dev); + command_write(dev); } } @@ -890,15 +864,16 @@ scsi_cdrom_data_command_finish(scsi_cdrom_t *dev, int len, int block_len, int al static void -scsi_cdrom_sense_clear(scsi_cdrom_t *dev, int command) +sense_clear(scsi_cdrom_t *dev, int command) { dev->previous_command = command; + scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = 0; } static void -scsi_cdrom_set_phase(scsi_cdrom_t *dev, uint8_t phase) +set_phase(scsi_cdrom_t *dev, uint8_t phase) { if (dev->drv->bus_type != CDROM_BUS_SCSI) return; @@ -908,9 +883,10 @@ scsi_cdrom_set_phase(scsi_cdrom_t *dev, uint8_t phase) static void -scsi_cdrom_cmd_error(scsi_cdrom_t *dev) +cmd_error(scsi_cdrom_t *dev) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + set_phase(dev, SCSI_PHASE_STATUS); + dev->error = ((scsi_cdrom_sense_key & 0xf) << 4) | ABRT_ERR; if (dev->unit_attention) dev->error |= MCR_ERR; @@ -920,16 +896,17 @@ scsi_cdrom_cmd_error(scsi_cdrom_t *dev) dev->packet_status = 0x80; dev->callback = 50LL * CDROM_TIME; - scsi_cdrom_set_callback(dev); + set_callback(dev); - DEBUG("CD-ROM %i: ERROR: %02X/%02X/%02X\n", dev->id, scsi_cdrom_sense_key, scsi_cdrom_asc, scsi_cdrom_ascq); + DEBUG("CD-ROM %i: ERROR: %02X/%02X/%02X\n", + dev->id, scsi_cdrom_sense_key, scsi_cdrom_asc, scsi_cdrom_ascq); } static void -scsi_cdrom_unit_attention(scsi_cdrom_t *dev) +unit_attention(scsi_cdrom_t *dev) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + set_phase(dev, SCSI_PHASE_STATUS); dev->error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; if (dev->unit_attention) @@ -940,122 +917,122 @@ scsi_cdrom_unit_attention(scsi_cdrom_t *dev) dev->packet_status = 0x80; dev->callback = 50LL * CDROM_TIME; - scsi_cdrom_set_callback(dev); + set_callback(dev); DEBUG("CD-ROM %i: UNIT ATTENTION\n", dev->id); } static void -scsi_cdrom_bus_master_error(scsi_cdrom_t *dev) +bus_master_error(scsi_cdrom_t *dev) { scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = 0; - scsi_cdrom_cmd_error(dev); + cmd_error(dev); } static void -scsi_cdrom_not_ready(scsi_cdrom_t *dev) +not_ready(scsi_cdrom_t *dev) { scsi_cdrom_sense_key = SENSE_NOT_READY; scsi_cdrom_asc = ASC_MEDIUM_NOT_PRESENT; scsi_cdrom_ascq = 0; - scsi_cdrom_cmd_error(dev); + cmd_error(dev); } static void -scsi_cdrom_invalid_lun(scsi_cdrom_t *dev) +invalid_lun(scsi_cdrom_t *dev) { scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_INV_LUN; scsi_cdrom_ascq = 0; - scsi_cdrom_cmd_error(dev); + cmd_error(dev); } static void -scsi_cdrom_illegal_opcode(scsi_cdrom_t *dev) +illegal_opcode(scsi_cdrom_t *dev) { scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_ILLEGAL_OPCODE; scsi_cdrom_ascq = 0; - scsi_cdrom_cmd_error(dev); + cmd_error(dev); } static void -scsi_cdrom_lba_out_of_range(scsi_cdrom_t *dev) +lba_out_of_range(scsi_cdrom_t *dev) { scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_LBA_OUT_OF_RANGE; scsi_cdrom_ascq = 0; - scsi_cdrom_cmd_error(dev); + cmd_error(dev); } static void -scsi_cdrom_invalid_field(scsi_cdrom_t *dev) +invalid_field(scsi_cdrom_t *dev) { scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_INV_FIELD_IN_CMD_PACKET; scsi_cdrom_ascq = 0; - scsi_cdrom_cmd_error(dev); + cmd_error(dev); dev->status = 0x53; } static void -scsi_cdrom_invalid_field_pl(scsi_cdrom_t *dev) +invalid_field_pl(scsi_cdrom_t *dev) { scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; scsi_cdrom_ascq = 0; - scsi_cdrom_cmd_error(dev); + cmd_error(dev); dev->status = 0x53; } static void -scsi_cdrom_illegal_mode(scsi_cdrom_t *dev) +illegal_mode(scsi_cdrom_t *dev) { scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_ILLEGAL_MODE_FOR_THIS_TRACK; scsi_cdrom_ascq = 0; - scsi_cdrom_cmd_error(dev); + cmd_error(dev); } static void -scsi_cdrom_incompatible_format(scsi_cdrom_t *dev) +incompatible_format(scsi_cdrom_t *dev) { scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_INCOMPATIBLE_FORMAT; scsi_cdrom_ascq = 2; - scsi_cdrom_cmd_error(dev); + cmd_error(dev); } static void -scsi_cdrom_data_phase_error(scsi_cdrom_t *dev) +data_phase_error(scsi_cdrom_t *dev) { scsi_cdrom_sense_key = SENSE_ILLEGAL_REQUEST; scsi_cdrom_asc = ASC_DATA_PHASE_ERROR; scsi_cdrom_ascq = 0; - scsi_cdrom_cmd_error(dev); + cmd_error(dev); } @@ -1117,7 +1094,7 @@ scsi_cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks) static int -scsi_cdrom_read_data(scsi_cdrom_t *dev, int msf, int type, int flags, int32_t *len) +read_data(scsi_cdrom_t *dev, int msf, int type, int flags, int32_t *len) { int ret = 0; uint32_t cdsize = 0; @@ -1129,14 +1106,14 @@ scsi_cdrom_read_data(scsi_cdrom_t *dev, int msf, int type, int flags, int32_t *l if (dev->sector_pos >= cdsize) { DEBUG("CD-ROM %i: Trying to read from beyond the end of disc (%i >= %i)\n", dev->id, dev->sector_pos, cdsize); - scsi_cdrom_lba_out_of_range(dev); + lba_out_of_range(dev); return 0; } if ((dev->sector_pos + dev->sector_len - 1) >= cdsize) { DEBUG("CD-ROM %i: Trying to read to beyond the end of disc (%i >= %i)\n", dev->id, (dev->sector_pos + dev->sector_len - 1), cdsize); - scsi_cdrom_lba_out_of_range(dev); + lba_out_of_range(dev); return 0; } @@ -1144,8 +1121,9 @@ scsi_cdrom_read_data(scsi_cdrom_t *dev, int msf, int type, int flags, int32_t *l *len = 0; for (i = 0; i < dev->requested_blocks; i++) { - ret = dev->drv->ops->readsector_raw(dev->drv, cdbufferb + dev->data_pos, dev->sector_pos + i, - msf, type, flags, &temp_len); + ret = dev->drv->ops->readsector_raw(dev->drv, cdbufferb + dev->data_pos, + dev->sector_pos + i, msf, + type, flags, &temp_len); dev->data_pos += temp_len; dev->old_len += temp_len; @@ -1153,7 +1131,7 @@ scsi_cdrom_read_data(scsi_cdrom_t *dev, int msf, int type, int flags, int32_t *l *len += temp_len; if (!ret) { - scsi_cdrom_illegal_mode(dev); + illegal_mode(dev); return 0; } } @@ -1163,7 +1141,7 @@ scsi_cdrom_read_data(scsi_cdrom_t *dev, int msf, int type, int flags, int32_t *l static int -scsi_cdrom_read_blocks(scsi_cdrom_t *dev, int32_t *len, int first_batch) +read_blocks(scsi_cdrom_t *dev, int32_t *len, int first_batch) { int ret = 0, msf = 0; int type = 0, flags = 0; @@ -1182,7 +1160,7 @@ scsi_cdrom_read_blocks(scsi_cdrom_t *dev, int32_t *len, int first_batch) dev->data_pos = 0; if (!dev->sector_len) { - scsi_cdrom_command_complete(dev); + command_complete(dev); return -1; } @@ -1190,13 +1168,13 @@ scsi_cdrom_read_blocks(scsi_cdrom_t *dev, int32_t *len, int first_batch) scsi_cdrom_update_cdb(dev->current_cdb, dev->sector_pos, dev->requested_blocks); - ret = scsi_cdrom_read_data(dev, msf, type, flags, len); + ret = read_data(dev, msf, type, flags, len); DEBUG("Read %i bytes of blocks...\n", *len); if (!ret || ((dev->old_len != *len) && !first_batch)) { if ((dev->old_len != *len) && !first_batch) - scsi_cdrom_illegal_mode(dev); + illegal_mode(dev); return 0; } @@ -1210,7 +1188,7 @@ scsi_cdrom_read_blocks(scsi_cdrom_t *dev, int32_t *len, int first_batch) /*SCSI Read DVD Structure*/ static int -scsi_cdrom_read_dvd_structure(scsi_cdrom_t *dev, int format, const uint8_t *packet, uint8_t *buf) +read_dvd_structure(scsi_cdrom_t *dev, int format, const uint8_t *packet, uint8_t *buf) { int layer = packet[6]; uint64_t total_sectors; @@ -1220,14 +1198,14 @@ scsi_cdrom_read_dvd_structure(scsi_cdrom_t *dev, int format, const uint8_t *pack total_sectors = (uint64_t) dev->drv->ops->size(dev->drv); if (layer != 0) { - scsi_cdrom_invalid_field(dev); + invalid_field(dev); return 0; } total_sectors >>= 2; if (total_sectors == 0) { /* return -ASC_MEDIUM_NOT_PRESENT; */ - scsi_cdrom_not_ready(dev); + not_ready(dev); return 0; } @@ -1267,7 +1245,7 @@ scsi_cdrom_read_dvd_structure(scsi_cdrom_t *dev, int format, const uint8_t *pack return (4 + 4); case 0x03: /* BCA information - invalid field for no BCA info */ - scsi_cdrom_invalid_field(dev); + invalid_field(dev); return 0; case 0x04: /* DVD disc manufacturing information */ @@ -1312,7 +1290,7 @@ scsi_cdrom_read_dvd_structure(scsi_cdrom_t *dev, int format, const uint8_t *pack return (16 + 4); default: /* TODO: formats beyond DVD-ROM requires */ - scsi_cdrom_invalid_field(dev); + invalid_field(dev); return 0; } } @@ -1332,7 +1310,7 @@ scsi_cdrom_insert(void *p) static int -scsi_cdrom_pre_execution_check(scsi_cdrom_t *dev, uint8_t *cdb) +pre_execution_check(scsi_cdrom_t *dev, uint8_t *cdb) { int ready = 0, status = 0; @@ -1340,28 +1318,28 @@ scsi_cdrom_pre_execution_check(scsi_cdrom_t *dev, uint8_t *cdb) if ((cdb[0] != GPCMD_REQUEST_SENSE) && (cdb[1] & 0xe0)) { DEBUG("CD-ROM %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", dev->id, ((dev->request_length >> 5) & 7)); - scsi_cdrom_invalid_lun(dev); + invalid_lun(dev); return 0; } } - if (!(scsi_cdrom_command_flags[cdb[0]] & IMPLEMENTED)) { + if (!(command_flags[cdb[0]] & IMPLEMENTED)) { DEBUG("CD-ROM %i: Attempting to execute unknown command %02X over %s\n", dev->id, cdb[0], (dev->drv->bus_type == CDROM_BUS_SCSI) ? "SCSI" : "ATAPI"); - scsi_cdrom_illegal_opcode(dev); + illegal_opcode(dev); return 0; } - if ((dev->drv->bus_type < CDROM_BUS_SCSI) && (scsi_cdrom_command_flags[cdb[0]] & SCSI_ONLY)) { + if ((dev->drv->bus_type < CDROM_BUS_SCSI) && (command_flags[cdb[0]] & SCSI_ONLY)) { DEBUG("CD-ROM %i: Attempting to execute SCSI-only command %02X over ATAPI\n", dev->id, cdb[0]); - scsi_cdrom_illegal_opcode(dev); + illegal_opcode(dev); return 0; } - if ((dev->drv->bus_type == CDROM_BUS_SCSI) && (scsi_cdrom_command_flags[cdb[0]] & ATAPI_ONLY)) { + if ((dev->drv->bus_type == CDROM_BUS_SCSI) && (command_flags[cdb[0]] & ATAPI_ONLY)) { DEBUG("CD-ROM %i: Attempting to execute ATAPI-only command %02X over SCSI\n", dev->id, cdb[0]); - scsi_cdrom_illegal_opcode(dev); + illegal_opcode(dev); return 0; } @@ -1388,12 +1366,12 @@ skip_ready_check: execution under it, error out and report the condition. */ if (dev->unit_attention == 1) { /* Only increment the unit attention phase if the command can not pass through it. */ - if (!(scsi_cdrom_command_flags[cdb[0]] & ALLOW_UA)) { + if (!(command_flags[cdb[0]] & ALLOW_UA)) { DBGLOG(1, "CD-ROM %i: Unit attention now 2\n", dev->id); dev->unit_attention++; DEBUG("CD-ROM %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", dev->id, cdb[0]); - scsi_cdrom_unit_attention(dev); + unit_attention(dev); return 0; } } else if (dev->unit_attention == 2) { @@ -1406,7 +1384,7 @@ skip_ready_check: /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* the UNIT ATTENTION condition if it's set. */ if (cdb[0] != GPCMD_REQUEST_SENSE) - scsi_cdrom_sense_clear(dev, cdb[0]); + sense_clear(dev, cdb[0]); /* Next it's time for NOT READY. */ if (!ready) @@ -1414,9 +1392,9 @@ skip_ready_check: else dev->media_status = (dev->unit_attention) ? MEC_NEW_MEDIA : MEC_NO_CHANGE; - if ((scsi_cdrom_command_flags[cdb[0]] & CHECK_READY) && !ready) { + if ((command_flags[cdb[0]] & CHECK_READY) && !ready) { DEBUG("CD-ROM %i: Not ready (%02X)\n", dev->id, cdb[0]); - scsi_cdrom_not_ready(dev); + not_ready(dev); return 0; } @@ -1435,7 +1413,7 @@ scsi_cdrom_rezero(scsi_cdrom_t *dev) } -void +static void scsi_cdrom_reset(void *p) { scsi_cdrom_t *dev = (scsi_cdrom_t *) p; @@ -1448,7 +1426,7 @@ scsi_cdrom_reset(void *p) dev->status = 0; dev->callback = 0LL; - scsi_cdrom_set_callback(dev); + set_callback(dev); dev->packet_status = 0xff; dev->unit_attention = 0xff; @@ -1456,7 +1434,7 @@ scsi_cdrom_reset(void *p) static void -scsi_cdrom_request_sense(scsi_cdrom_t *dev, uint8_t *buffer, uint8_t alloc_length) +request_sense(scsi_cdrom_t *dev, uint8_t *buffer, uint8_t alloc_length) { int status = dev->drv->cd_status; @@ -1495,12 +1473,12 @@ scsi_cdrom_request_sense(scsi_cdrom_t *dev, uint8_t *buffer, uint8_t alloc_lengt } /* Clear the sense stuff as per the spec. */ - scsi_cdrom_sense_clear(dev, GPCMD_REQUEST_SENSE); + sense_clear(dev, GPCMD_REQUEST_SENSE); } -void -scsi_cdrom_request_sense_for_scsi(void *p, uint8_t *buffer, uint8_t alloc_length) +static void +request_sense_for_scsi(void *p, uint8_t *buffer, uint8_t alloc_length) { scsi_cdrom_t *dev = (scsi_cdrom_t *) p; int ready = 0; @@ -1518,12 +1496,12 @@ scsi_cdrom_request_sense_for_scsi(void *p, uint8_t *buffer, uint8_t alloc_length } /* Do *NOT* advance the unit attention phase. */ - scsi_cdrom_request_sense(dev, buffer, alloc_length); + request_sense(dev, buffer, alloc_length); } static void -scsi_cdrom_set_buf_len(scsi_cdrom_t *dev, int32_t *BufLen, int32_t *src_len) +set_buf_len(scsi_cdrom_t *dev, int32_t *BufLen, int32_t *src_len) { if (dev->drv->bus_type == CDROM_BUS_SCSI) { if (*BufLen == -1) @@ -1538,16 +1516,16 @@ scsi_cdrom_set_buf_len(scsi_cdrom_t *dev, int32_t *BufLen, int32_t *src_len) static void -scsi_cdrom_buf_alloc(scsi_cdrom_t *dev, uint32_t len) +buf_alloc(scsi_cdrom_t *dev, uint32_t len) { DEBUG("CD-ROM %i: Allocated buffer length: %i\n", dev->id, len); - cdbufferb = (uint8_t *) malloc(len); + cdbufferb = (uint8_t *)mem_alloc(len); } static void -scsi_cdrom_buf_free(scsi_cdrom_t *dev) +buf_free(scsi_cdrom_t *dev) { if (cdbufferb) { DEBUG("CD-ROM %i: Freeing buffer...\n", dev->id); @@ -1611,16 +1589,16 @@ scsi_cdrom_command(void *p, uint8_t *cdb) msf = cdb[1] & 2; dev->sector_len = 0; - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + set_phase(dev, SCSI_PHASE_STATUS); /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ - if (scsi_cdrom_pre_execution_check(dev, cdb) == 0) + if (pre_execution_check(dev, cdb) == 0) return; switch (cdb[0]) { case GPCMD_TEST_UNIT_READY: - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_command_complete(dev); + set_phase(dev, SCSI_PHASE_STATUS); + command_complete(dev); break; case GPCMD_REZERO_UNIT: @@ -1629,27 +1607,27 @@ scsi_cdrom_command(void *p, uint8_t *cdb) dev->sector_pos = dev->sector_len = 0; dev->drv->seek_diff = dev->drv->seek_pos; cdrom_seek(dev->drv, 0); - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + set_phase(dev, SCSI_PHASE_STATUS); break; case GPCMD_REQUEST_SENSE: /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE should forget about the not ready, and report unit attention straight away. */ - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + set_phase(dev, SCSI_PHASE_DATA_IN); max_len = cdb[4]; if (!max_len) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + set_phase(dev, SCSI_PHASE_STATUS); dev->packet_status = PHASE_COMPLETE; dev->callback = 20LL * CDROM_TIME; - scsi_cdrom_set_callback(dev); + set_callback(dev); break; } - scsi_cdrom_buf_alloc(dev, 256); - scsi_cdrom_set_buf_len(dev, BufLen, &max_len); - scsi_cdrom_request_sense(dev, cdbufferb, max_len); - scsi_cdrom_data_command_finish(dev, 18, 18, cdb[4], 0); + buf_alloc(dev, 256); + set_buf_len(dev, BufLen, &max_len); + request_sense(dev, cdbufferb, max_len); + data_command_finish(dev, 18, 18, cdb[4], 0); break; case GPCMD_SET_SPEED: @@ -1659,32 +1637,31 @@ scsi_cdrom_command(void *p, uint8_t *cdb) dev->drv->cur_speed = 1; else if (dev->drv->cur_speed > dev->drv->speed_idx) dev->drv->cur_speed = dev->drv->speed_idx; - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_command_complete(dev); + set_phase(dev, SCSI_PHASE_STATUS); + command_complete(dev); break; case GPCMD_MECHANISM_STATUS: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + set_phase(dev, SCSI_PHASE_DATA_IN); len = (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; - scsi_cdrom_buf_alloc(dev, 8); - - scsi_cdrom_set_buf_len(dev, BufLen, &len); + buf_alloc(dev, 8); + set_buf_len(dev, BufLen, &len); memset(cdbufferb, 0, 8); cdbufferb[5] = 1; - scsi_cdrom_data_command_finish(dev, 8, 8, len, 0); + data_command_finish(dev, 8, 8, len, 0); break; case GPCMD_READ_TOC_PMA_ATIP: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + set_phase(dev, SCSI_PHASE_DATA_IN); max_len = cdb[7]; max_len <<= 8; max_len |= cdb[8]; - scsi_cdrom_buf_alloc(dev, 65536); + buf_alloc(dev, 65536); toc_format = cdb[2] & 0xf; @@ -1704,8 +1681,8 @@ scsi_cdrom_command(void *p, uint8_t *cdb) len = dev->drv->ops->readtoc_raw(dev->drv, cdbufferb, max_len); break; default: - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); + invalid_field(dev); + buf_free(dev); return; } @@ -1716,13 +1693,9 @@ scsi_cdrom_command(void *p, uint8_t *cdb) cdbufferb[1] = (len - 2) & 0xff; } - scsi_cdrom_set_buf_len(dev, BufLen, &len); + set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); -#if 0 - DBGLOG(1, "CD-ROM %i: READ_TOC_PMA_ATIP format %02X, length %i (%i)\n", dev->id, - toc_format, ide->cylinder, cdbufferb[1]); -#endif + data_command_finish(dev, len, len, len, 0); return; case GPCMD_READ_CD_OLD: @@ -1734,7 +1707,7 @@ scsi_cdrom_command(void *p, uint8_t *cdb) case GPCMD_READ_12: case GPCMD_READ_CD: case GPCMD_READ_CD_MSF: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + set_phase(dev, SCSI_PHASE_DATA_IN); alloc_length = 2048; switch(cdb[0]) { @@ -1780,11 +1753,11 @@ scsi_cdrom_command(void *p, uint8_t *cdb) dev->drv->seek_pos = dev->sector_pos; if (!dev->sector_len) { - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + set_phase(dev, SCSI_PHASE_STATUS); DBGLOG(1, "CD-ROM %i: All done - callback set\n", dev->id); dev->packet_status = PHASE_COMPLETE; dev->callback = 20LL * CDROM_TIME; - scsi_cdrom_set_callback(dev); + set_callback(dev); break; } @@ -1794,21 +1767,22 @@ scsi_cdrom_command(void *p, uint8_t *cdb) transferred to the host should be different. */ dev->packet_len = max_len * alloc_length; - scsi_cdrom_buf_alloc(dev, dev->packet_len); + buf_alloc(dev, dev->packet_len); - ret = scsi_cdrom_read_blocks(dev, &alloc_length, 1); + ret = read_blocks(dev, &alloc_length, 1); if (ret <= 0) { - scsi_cdrom_buf_free(dev); + buf_free(dev); return; } dev->requested_blocks = max_len; dev->packet_len = alloc_length; - scsi_cdrom_set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); + set_buf_len(dev, BufLen, (int32_t *) &dev->packet_len); - scsi_cdrom_data_command_finish(dev, alloc_length, alloc_length / dev->requested_blocks, - alloc_length, 0); + data_command_finish(dev, alloc_length, + alloc_length / dev->requested_blocks, + alloc_length, 0); if (dev->packet_status != PHASE_COMPLETE) ui_sb_icon_update(SB_CDROM | dev->id, 1); @@ -1817,10 +1791,10 @@ scsi_cdrom_command(void *p, uint8_t *cdb) return; case GPCMD_READ_HEADER: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + set_phase(dev, SCSI_PHASE_DATA_IN); alloc_length = ((cdb[7] << 8) | cdb[8]); - scsi_cdrom_buf_alloc(dev, 8); + buf_alloc(dev, 8); dev->sector_len = 1; dev->sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4]<<8) | cdb[5]; @@ -1838,14 +1812,14 @@ scsi_cdrom_command(void *p, uint8_t *cdb) len = 8; len = MIN(len, alloc_length); - scsi_cdrom_set_buf_len(dev, BufLen, &len); + set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); + data_command_finish(dev, len, len, len, 0); return; case GPCMD_MODE_SENSE_6: case GPCMD_MODE_SENSE_10: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + set_phase(dev, SCSI_PHASE_DATA_IN); if (dev->drv->bus_type == CDROM_BUS_SCSI) block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; @@ -1854,15 +1828,15 @@ scsi_cdrom_command(void *p, uint8_t *cdb) if (cdb[0] == GPCMD_MODE_SENSE_6) { len = cdb[4]; - scsi_cdrom_buf_alloc(dev, 256); + buf_alloc(dev, 256); } else { len = (cdb[8] | (cdb[7] << 8)); - scsi_cdrom_buf_alloc(dev, 65536); + buf_alloc(dev, 65536); } - if (!(scsi_cdrom_mode_sense_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); + if (!(mode_sense_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) { + invalid_field(dev); + buf_free(dev); return; } @@ -1870,14 +1844,14 @@ scsi_cdrom_command(void *p, uint8_t *cdb) alloc_length = len; if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = scsi_cdrom_mode_sense(dev, cdbufferb, 4, cdb[2], block_desc); + len = mode_sense(dev, cdbufferb, 4, cdb[2], block_desc); len = MIN(len, alloc_length); cdbufferb[0] = len - 1; cdbufferb[1] = dev->drv->ops->media_type_id(dev->drv); if (block_desc) cdbufferb[3] = 8; } else { - len = scsi_cdrom_mode_sense(dev, cdbufferb, 8, cdb[2], block_desc); + len = mode_sense(dev, cdbufferb, 8, cdb[2], block_desc); len = MIN(len, alloc_length); cdbufferb[0]=(len - 2) >> 8; cdbufferb[1]=(len - 2) & 255; @@ -1888,35 +1862,35 @@ scsi_cdrom_command(void *p, uint8_t *cdb) } } - scsi_cdrom_set_buf_len(dev, BufLen, &len); + set_buf_len(dev, BufLen, &len); DEBUG("CD-ROM %i: Reading mode page: %02X...\n", dev->id, cdb[2]); - scsi_cdrom_data_command_finish(dev, len, len, alloc_length, 0); + data_command_finish(dev, len, len, alloc_length, 0); return; case GPCMD_MODE_SELECT_6: case GPCMD_MODE_SELECT_10: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_OUT); + set_phase(dev, SCSI_PHASE_DATA_OUT); if (cdb[0] == GPCMD_MODE_SELECT_6) { len = cdb[4]; - scsi_cdrom_buf_alloc(dev, 256); + buf_alloc(dev, 256); } else { len = (cdb[7] << 8) | cdb[8]; - scsi_cdrom_buf_alloc(dev, 65536); + buf_alloc(dev, 65536); } - scsi_cdrom_set_buf_len(dev, BufLen, &len); + set_buf_len(dev, BufLen, &len); dev->total_length = len; dev->do_page_save = cdb[1] & 1; - scsi_cdrom_data_command_finish(dev, len, len, len, 1); + data_command_finish(dev, len, len, len, 1); return; case GPCMD_GET_CONFIGURATION: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + set_phase(dev, SCSI_PHASE_DATA_IN); /* XXX: could result in alignment problems in some architectures */ feature = (cdb[2] << 8) | cdb[3]; @@ -1924,12 +1898,12 @@ scsi_cdrom_command(void *p, uint8_t *cdb) /* only feature 0 is supported */ if ((cdb[2] != 0) || (cdb[3] > 2)) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); + invalid_field(dev); + buf_free(dev); return; } - scsi_cdrom_buf_alloc(dev, 65536); + buf_alloc(dev, 65536); memset(cdbufferb, 0, max_len); alloc_length = 0; @@ -2006,15 +1980,15 @@ scsi_cdrom_command(void *p, uint8_t *cdb) alloc_length = MIN(alloc_length, max_len); - scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); + set_buf_len(dev, BufLen, &alloc_length); - scsi_cdrom_data_command_finish(dev, alloc_length, alloc_length, alloc_length, 0); + data_command_finish(dev, alloc_length, alloc_length, alloc_length, 0); break; case GPCMD_GET_EVENT_STATUS_NOTIFICATION: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + set_phase(dev, SCSI_PHASE_DATA_IN); - scsi_cdrom_buf_alloc(dev, 8 + sizeof(gesn_event_header_t)); + buf_alloc(dev, 8 + sizeof(gesn_event_header_t)); gesn_cdb = (void *) cdb; gesn_event_header = (void *) cdbufferb; @@ -2023,8 +1997,8 @@ scsi_cdrom_command(void *p, uint8_t *cdb) if (!(gesn_cdb->polled & 0x01)) { /* asynchronous mode */ /* Only polling is supported, asynchronous mode is not. */ - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); + invalid_field(dev); + buf_free(dev); return; } @@ -2066,19 +2040,19 @@ scsi_cdrom_command(void *p, uint8_t *cdb) memcpy(cdbufferb, gesn_event_header, 4); - scsi_cdrom_set_buf_len(dev, BufLen, &used_len); + set_buf_len(dev, BufLen, &used_len); - scsi_cdrom_data_command_finish(dev, used_len, used_len, used_len, 0); + data_command_finish(dev, used_len, used_len, used_len, 0); break; case GPCMD_READ_DISC_INFORMATION: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + set_phase(dev, SCSI_PHASE_DATA_IN); max_len = cdb[7]; max_len <<= 8; max_len |= cdb[8]; - scsi_cdrom_buf_alloc(dev, 65536); + buf_alloc(dev, 65536); memset(cdbufferb, 0, 34); memset(cdbufferb, 1, 9); @@ -2091,19 +2065,19 @@ scsi_cdrom_command(void *p, uint8_t *cdb) len=34; len = MIN(len, max_len); - scsi_cdrom_set_buf_len(dev, BufLen, &len); + set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); + data_command_finish(dev, len, len, len, 0); break; case GPCMD_READ_TRACK_INFORMATION: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + set_phase(dev, SCSI_PHASE_DATA_IN); max_len = cdb[7]; max_len <<= 8; max_len |= cdb[8]; - scsi_cdrom_buf_alloc(dev, 65536); + buf_alloc(dev, 65536); track = ((uint32_t) cdb[2]) << 24; track |= ((uint32_t) cdb[3]) << 16; @@ -2111,8 +2085,8 @@ scsi_cdrom_command(void *p, uint8_t *cdb) track |= (uint32_t) cdb[5]; if (((cdb[1] & 0x03) != 1) || (track != 1)) { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); + invalid_field(dev); + buf_free(dev); return; } @@ -2137,16 +2111,16 @@ scsi_cdrom_command(void *p, uint8_t *cdb) cdbufferb[1] = (max_len - 2) & 0xff; } - scsi_cdrom_set_buf_len(dev, BufLen, &len); + set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, max_len, 0); + data_command_finish(dev, len, len, max_len, 0); break; case GPCMD_PLAY_AUDIO_10: case GPCMD_PLAY_AUDIO_12: case GPCMD_PLAY_AUDIO_MSF: case GPCMD_PLAY_AUDIO_TRACK_INDEX: - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + set_phase(dev, SCSI_PHASE_STATUS); switch(cdb[0]) { case GPCMD_PLAY_AUDIO_10: @@ -2174,38 +2148,38 @@ scsi_cdrom_command(void *p, uint8_t *cdb) } if ((dev->drv->host_drive < 1) || (dev->drv->cd_status <= CD_STATUS_DATA_ONLY)) { - scsi_cdrom_illegal_mode(dev); + illegal_mode(dev); break; } - if (dev->drv->ops->playaudio) - ret = dev->drv->ops->playaudio(dev->drv, pos, len, msf); + if (dev->drv->ops->audio_play) + ret = dev->drv->ops->audio_play(dev->drv, pos, len, msf); else ret = 0; if (ret) - scsi_cdrom_command_complete(dev); + command_complete(dev); else - scsi_cdrom_illegal_mode(dev); + illegal_mode(dev); break; case GPCMD_READ_SUBCHANNEL: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + set_phase(dev, SCSI_PHASE_DATA_IN); max_len = cdb[7]; max_len <<= 8; max_len |= cdb[8]; msf = (cdb[1] >> 1) & 1; - scsi_cdrom_buf_alloc(dev, 32); + buf_alloc(dev, 32); DEBUG("CD-ROM %i: Getting page %i (%s)\n", dev->id, cdb[3], msf ? "MSF" : "LBA"); if (cdb[3] > 3) { DBGLOG(1, "CD-ROM %i: Read subchannel check condition %02X\n", dev->id, cdb[3]); - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); + invalid_field(dev); + buf_free(dev); return; } @@ -2251,23 +2225,23 @@ scsi_cdrom_command(void *p, uint8_t *cdb) len = alloc_length; len = MIN(len, max_len); - scsi_cdrom_set_buf_len(dev, BufLen, &len); + set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); + data_command_finish(dev, len, len, len, 0); break; case GPCMD_READ_DVD_STRUCTURE: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + set_phase(dev, SCSI_PHASE_DATA_IN); alloc_length = (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - scsi_cdrom_buf_alloc(dev, alloc_length); + buf_alloc(dev, alloc_length); len = dev->drv->ops->size(dev->drv); if ((cdb[7] < 0xc0) && (len <= CD_MAX_SECTORS)) { - scsi_cdrom_incompatible_format(dev); - scsi_cdrom_buf_free(dev); + incompatible_format(dev); + buf_free(dev); return; } @@ -2275,24 +2249,24 @@ scsi_cdrom_command(void *p, uint8_t *cdb) if ((cdb[7] <= 0x7f) || (cdb[7] == 0xff)) { if (cdb[1] == 0) { - ret = scsi_cdrom_read_dvd_structure(dev, format, cdb, cdbufferb); - if (ret) { - scsi_cdrom_set_buf_len(dev, BufLen, &alloc_length); - scsi_cdrom_data_command_finish(dev, alloc_length, alloc_length, + ret = read_dvd_structure(dev, format, cdb, cdbufferb); + if (ret) { + set_buf_len(dev, BufLen, &alloc_length); + data_command_finish(dev, alloc_length, alloc_length, len, 0); } else - scsi_cdrom_buf_free(dev); + buf_free(dev); return; } } else { - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); + invalid_field(dev); + buf_free(dev); return; } break; case GPCMD_START_STOP_UNIT: - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + set_phase(dev, SCSI_PHASE_STATUS); switch(cdb[4] & 3) { case 0: /* Stop the disc. */ @@ -2312,17 +2286,17 @@ scsi_cdrom_command(void *p, uint8_t *cdb) break; } - scsi_cdrom_command_complete(dev); + command_complete(dev); break; case GPCMD_INQUIRY: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + set_phase(dev, SCSI_PHASE_DATA_IN); max_len = cdb[3]; max_len <<= 8; max_len |= cdb[4]; - scsi_cdrom_buf_alloc(dev, 65536); + buf_alloc(dev, 65536); if (cdb[1] & 1) { preamble_len = 4; @@ -2341,8 +2315,8 @@ scsi_cdrom_command(void *p, uint8_t *cdb) break; case 0x83: if (idx + 24 > max_len) { - scsi_cdrom_data_phase_error(dev); - scsi_cdrom_buf_free(dev); + data_phase_error(dev); + buf_free(dev); return; } @@ -2368,8 +2342,8 @@ scsi_cdrom_command(void *p, uint8_t *cdb) break; default: DEBUG("INQUIRY: Invalid page: %02X\n", cdb[2]); - scsi_cdrom_invalid_field(dev); - scsi_cdrom_buf_free(dev); + invalid_field(dev); + buf_free(dev); return; } } else { @@ -2403,41 +2377,41 @@ atapi_out: len=idx; len = MIN(len, max_len); - scsi_cdrom_set_buf_len(dev, BufLen, &len); + set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, max_len, 0); + data_command_finish(dev, len, len, max_len, 0); break; case GPCMD_PREVENT_REMOVAL: - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); - scsi_cdrom_command_complete(dev); + set_phase(dev, SCSI_PHASE_STATUS); + command_complete(dev); break; case GPCMD_PAUSE_RESUME_ALT: case GPCMD_PAUSE_RESUME: - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + set_phase(dev, SCSI_PHASE_STATUS); if (cdb[8] & 1) { - if (dev->drv->ops->resume) - dev->drv->ops->resume(dev->drv); + if (dev->drv->ops->audio_resume) + dev->drv->ops->audio_resume(dev->drv); else { - scsi_cdrom_illegal_mode(dev); + illegal_mode(dev); break; } } else { - if (dev->drv->ops->pause) - dev->drv->ops->pause(dev->drv); + if (dev->drv->ops->audio_pause) + dev->drv->ops->audio_pause(dev->drv); else { - scsi_cdrom_illegal_mode(dev); + illegal_mode(dev); break; } } - scsi_cdrom_command_complete(dev); + command_complete(dev); break; case GPCMD_SEEK_6: case GPCMD_SEEK_10: - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + set_phase(dev, SCSI_PHASE_STATUS); switch(cdb[0]) { case GPCMD_SEEK_6: @@ -2449,51 +2423,51 @@ atapi_out: } dev->drv->seek_diff = ABS((int) (pos - dev->drv->seek_pos)); cdrom_seek(dev->drv, pos); - scsi_cdrom_command_complete(dev); + command_complete(dev); break; case GPCMD_READ_CDROM_CAPACITY: - scsi_cdrom_set_phase(dev, SCSI_PHASE_DATA_IN); + set_phase(dev, SCSI_PHASE_DATA_IN); - scsi_cdrom_buf_alloc(dev, 8); + buf_alloc(dev, 8); - if (scsi_cdrom_read_capacity(dev, dev->current_cdb, cdbufferb, (uint32_t *) &len) == 0) { - scsi_cdrom_buf_free(dev); + if (read_capacity(dev, dev->current_cdb, cdbufferb, (uint32_t *) &len) == 0) { + buf_free(dev); return; } - scsi_cdrom_set_buf_len(dev, BufLen, &len); + set_buf_len(dev, BufLen, &len); - scsi_cdrom_data_command_finish(dev, len, len, len, 0); + data_command_finish(dev, len, len, len, 0); break; case GPCMD_STOP_PLAY_SCAN: - scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); + set_phase(dev, SCSI_PHASE_STATUS); if (dev->drv->ops->stop) dev->drv->ops->stop(dev->drv); else { - scsi_cdrom_illegal_mode(dev); + illegal_mode(dev); break; } - scsi_cdrom_command_complete(dev); + command_complete(dev); break; default: - scsi_cdrom_illegal_opcode(dev); + illegal_opcode(dev); break; } DBGLOG(1, "CD-ROM %i: Phase: %02X, request length: %i\n", dev->phase, dev->request_length); - if (scsi_cdrom_atapi_phase_to_scsi(dev) == SCSI_PHASE_STATUS) - scsi_cdrom_buf_free(dev); + if (atapi_phase_to_scsi(dev) == SCSI_PHASE_STATUS) + buf_free(dev); } /* The command second phase function, needed for Mode Select. */ static uint8_t -scsi_cdrom_phase_data_out(scsi_cdrom_t *dev) +phase_data_out(scsi_cdrom_t *dev) { uint16_t block_desc_len, pos; uint16_t i = 0; @@ -2530,12 +2504,12 @@ scsi_cdrom_phase_data_out(scsi_cdrom_t *dev) pos += 2; - if (!(scsi_cdrom_mode_sense_page_flags & (1LL << ((uint64_t) page)))) { + if (!(mode_sense_page_flags & (1LL << ((uint64_t) page)))) { DEBUG("Unimplemented page %02X\n", page); error |= 1; } else { for (i = 0; i < page_len; i++) { - ch = scsi_cdrom_mode_sense_pages_changeable.pages[page][i + 2]; + ch = mode_sense_pages_changeable.pages[page][i + 2]; val = cdbufferb[pos + i]; old_val = dev->ms_pages_saved.pages[page][i + 2]; if (val != old_val) { @@ -2552,19 +2526,19 @@ scsi_cdrom_phase_data_out(scsi_cdrom_t *dev) pos += page_len; if (dev->drv->bus_type == CDROM_BUS_SCSI) - val = scsi_cdrom_mode_sense_pages_default_scsi.pages[page][0] & 0x80; + val = mode_sense_pages_default_scsi.pages[page][0] & 0x80; else - val = scsi_cdrom_mode_sense_pages_default.pages[page][0] & 0x80; + val = mode_sense_pages_default.pages[page][0] & 0x80; if (dev->do_page_save && val) - scsi_cdrom_mode_sense_save(dev); + mode_sense_save(dev); if (pos >= dev->total_length) break; } if (error) { - scsi_cdrom_invalid_field_pl(dev); + invalid_field_pl(dev); return 0; } break; @@ -2576,7 +2550,7 @@ scsi_cdrom_phase_data_out(scsi_cdrom_t *dev) /* This is the general ATAPI PIO request function. */ static void -scsi_cdrom_pio_request(scsi_cdrom_t *dev, uint8_t out) +pio_request(scsi_cdrom_t *dev, uint8_t out) { int ret = 0; @@ -2592,15 +2566,15 @@ scsi_cdrom_pio_request(scsi_cdrom_t *dev, uint8_t out) dev->pos = dev->request_pos = 0; if (out) { - ret = scsi_cdrom_phase_data_out(dev); + ret = phase_data_out(dev); /* If ret = 0 (phase 1 error), then we do not do anything else other than free the buffer, as the phase and callback have already been set by the error function. */ if (ret) - scsi_cdrom_command_complete(dev); + command_complete(dev); } else - scsi_cdrom_command_complete(dev); - scsi_cdrom_buf_free(dev); + command_complete(dev); + buf_free(dev); } else { DEBUG("CD-ROM %i: %i bytes %s, %i bytes are still left\n", dev->id, dev->pos, out ? "written" : "read", dev->packet_len - dev->pos); @@ -2618,7 +2592,7 @@ scsi_cdrom_pio_request(scsi_cdrom_t *dev, uint8_t out) dev->phase = 1; scsi_cdrom_callback(dev); dev->callback = 0LL; - scsi_cdrom_set_callback(dev); + set_callback(dev); dev->request_pos = 0; } @@ -2626,7 +2600,7 @@ scsi_cdrom_pio_request(scsi_cdrom_t *dev, uint8_t out) static int -scsi_cdrom_read_from_ide_dma(scsi_cdrom_t *dev) +read_from_ide_dma(scsi_cdrom_t *dev) { int ret; @@ -2640,7 +2614,7 @@ scsi_cdrom_read_from_ide_dma(scsi_cdrom_t *dev) if (ret == 2) /* DMA not enabled, wait for it to be enabled. */ return 2; else if (ret == 1) { /* DMA error. */ - scsi_cdrom_bus_master_error(dev); + bus_master_error(dev); return 0; } else return 1; @@ -2651,7 +2625,7 @@ scsi_cdrom_read_from_ide_dma(scsi_cdrom_t *dev) static int -scsi_cdrom_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) +read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) { scsi_cdrom_t *dev = scsi_devices[scsi_id][scsi_lun].p; int32_t *BufLen = &scsi_devices[scsi_id][scsi_lun].buffer_length; @@ -2667,7 +2641,7 @@ scsi_cdrom_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) static void -scsi_cdrom_irq_raise(scsi_cdrom_t *dev) +irq_raise(scsi_cdrom_t *dev) { if (dev->drv->bus_type < CDROM_BUS_SCSI) ide_irq_raise(ide_drives[dev->drv->bus_id.ide_channel]); @@ -2675,15 +2649,15 @@ scsi_cdrom_irq_raise(scsi_cdrom_t *dev) static int -scsi_cdrom_read_from_dma(scsi_cdrom_t *dev) +read_from_dma(scsi_cdrom_t *dev) { int32_t *BufLen = &scsi_devices[dev->drv->bus_id.scsi.id][dev->drv->bus_id.scsi.lun].buffer_length; int ret = 0; if (dev->drv->bus_type == CDROM_BUS_SCSI) - ret = scsi_cdrom_read_from_scsi_dma(dev->drv->bus_id.scsi.id, dev->drv->bus_id.scsi.lun); + ret = read_from_scsi_dma(dev->drv->bus_id.scsi.id, dev->drv->bus_id.scsi.lun); else - ret = scsi_cdrom_read_from_ide_dma(dev); + ret = read_from_ide_dma(dev); if (ret != 1) return ret; @@ -2693,7 +2667,7 @@ scsi_cdrom_read_from_dma(scsi_cdrom_t *dev) else DEBUG("CD-ROM %i: ATAPI Input data length: %i\n", dev->id, dev->packet_len); - ret = scsi_cdrom_phase_data_out(dev); + ret = phase_data_out(dev); if (ret) return 1; @@ -2702,7 +2676,7 @@ scsi_cdrom_read_from_dma(scsi_cdrom_t *dev) static int -scsi_cdrom_write_to_ide_dma(scsi_cdrom_t *dev) +write_to_ide_dma(scsi_cdrom_t *dev) { int ret; @@ -2716,7 +2690,7 @@ scsi_cdrom_write_to_ide_dma(scsi_cdrom_t *dev) if (ret == 2) /* DMA not enabled, wait for it to be enabled. */ return 2; else if (ret == 1) { /* DMA error. */ - scsi_cdrom_bus_master_error(dev); + bus_master_error(dev); return 0; } else return 1; @@ -2727,7 +2701,7 @@ scsi_cdrom_write_to_ide_dma(scsi_cdrom_t *dev) static int -scsi_cdrom_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) +write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) { scsi_cdrom_t *dev = scsi_devices[scsi_id][scsi_lun].p; int32_t *BufLen = &scsi_devices[scsi_id][scsi_lun].buffer_length; @@ -2746,7 +2720,7 @@ scsi_cdrom_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) static int -scsi_cdrom_write_to_dma(scsi_cdrom_t *dev) +write_to_dma(scsi_cdrom_t *dev) { scsi_device_t *sd = &scsi_devices[dev->drv->bus_id.scsi.id][dev->drv->bus_id.scsi.lun]; int32_t *BufLen = &sd->buffer_length; @@ -2754,9 +2728,9 @@ scsi_cdrom_write_to_dma(scsi_cdrom_t *dev) if (dev->drv->bus_type == CDROM_BUS_SCSI) { DEBUG("Write to SCSI DMA: (ID %02X)\n", dev->drv->bus_id.scsi.id); - ret = scsi_cdrom_write_to_scsi_dma(dev->drv->bus_id.scsi.id, dev->drv->bus_id.scsi.lun); + ret = write_to_scsi_dma(dev->drv->bus_id.scsi.id, dev->drv->bus_id.scsi.lun); } else - ret = scsi_cdrom_write_to_ide_dma(dev); + ret = write_to_ide_dma(dev); if (dev->drv->bus_type == CDROM_BUS_SCSI) DEBUG("CD-ROM %i: SCSI Output data length: %i\n", dev->id, *BufLen); @@ -2780,69 +2754,76 @@ scsi_cdrom_callback(void *p) dev->phase = 1; dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); return; + case PHASE_COMMAND: DEBUG("CD-ROM %i: PHASE_COMMAND\n", dev->id); dev->status = BUSY_STAT | (dev->status & ERR_STAT); memcpy(dev->atapi_cdb, cdbufferb, 12); scsi_cdrom_command(dev, dev->atapi_cdb); return; + case PHASE_COMPLETE: DEBUG("CD-ROM %i: PHASE_COMPLETE\n", dev->id); dev->status = READY_STAT; dev->phase = 3; dev->packet_status = 0xFF; ui_sb_icon_update(SB_CDROM | dev->id, 0); - scsi_cdrom_irq_raise(dev); + irq_raise(dev); return; + case PHASE_DATA_OUT: DEBUG("CD-ROM %i: PHASE_DATA_OUT\n", dev->id); dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); dev->phase = 0; - scsi_cdrom_irq_raise(dev); + irq_raise(dev); return; + case PHASE_DATA_OUT_DMA: DEBUG("CD-ROM %i: PHASE_DATA_OUT_DMA\n", dev->id); - ret = scsi_cdrom_read_from_dma(dev); + ret = read_from_dma(dev); if ((ret == 1) || (dev->drv->bus_type == CDROM_BUS_SCSI)) { DEBUG("CD-ROM %i: DMA data out phase done\n"); - scsi_cdrom_buf_free(dev); - scsi_cdrom_command_complete(dev); + buf_free(dev); + command_complete(dev); } else if (ret == 2) { DEBUG("CD-ROM %i: DMA out not enabled, wait\n"); - scsi_cdrom_command_bus(dev); + command_bus(dev); } else { DEBUG("CD-ROM %i: DMA data out phase failure\n"); - scsi_cdrom_buf_free(dev); + buf_free(dev); } return; + case PHASE_DATA_IN: DEBUG("CD-ROM %i: PHASE_DATA_IN\n", dev->id); dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT); dev->phase = 2; - scsi_cdrom_irq_raise(dev); + irq_raise(dev); return; + case PHASE_DATA_IN_DMA: DEBUG("CD-ROM %i: PHASE_DATA_IN_DMA\n", dev->id); - ret = scsi_cdrom_write_to_dma(dev); + ret = write_to_dma(dev); if ((ret == 1) || (dev->drv->bus_type == CDROM_BUS_SCSI)) { DEBUG("CD-ROM %i: DMA data in phase done\n", dev->id); - scsi_cdrom_buf_free(dev); - scsi_cdrom_command_complete(dev); + buf_free(dev); + command_complete(dev); } else if (ret == 2) { DEBUG("CD-ROM %i: DMA in not enabled, wait\n", dev->id); - scsi_cdrom_command_bus(dev); + command_bus(dev); } else { DEBUG("CD-ROM %i: DMA data in phase failure\n", dev->id); - scsi_cdrom_buf_free(dev); + buf_free(dev); } return; + case PHASE_ERROR: DEBUG("CD-ROM %i: PHASE_ERROR\n", dev->id); dev->status = READY_STAT | ERR_STAT; dev->phase = 3; - scsi_cdrom_irq_raise(dev); + irq_raise(dev); ui_sb_icon_update(SB_CDROM | dev->id, 0); return; } @@ -2850,13 +2831,11 @@ scsi_cdrom_callback(void *p) static uint32_t -scsi_cdrom_packet_read(void *p, int length) +packet_read(void *p, int length) { scsi_cdrom_t *dev = (scsi_cdrom_t *) p; - uint16_t *cdbufferw; uint32_t *cdbufferl; - uint32_t temp = 0; if (!dev) @@ -2877,16 +2856,19 @@ scsi_cdrom_packet_read(void *p, int length) dev->pos++; dev->request_pos++; break; + case 2: temp = (dev->pos < dev->packet_len) ? cdbufferw[dev->pos >> 1] : 0; dev->pos += 2; dev->request_pos += 2; break; + case 4: temp = (dev->pos < dev->packet_len) ? cdbufferl[dev->pos >> 2] : 0; dev->pos += 4; dev->request_pos += 4; break; + default: return 0; } @@ -2894,19 +2876,19 @@ scsi_cdrom_packet_read(void *p, int length) if (dev->packet_status == PHASE_DATA_IN) { if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) { /* Time for a DRQ. */ - scsi_cdrom_pio_request(dev, 0); + pio_request(dev, 0); } return temp; - } else - return 0; + } + + return 0; } static void -scsi_cdrom_packet_write(void *p, uint32_t val, int length) +packet_write(void *p, uint32_t val, int length) { scsi_cdrom_t *dev = (scsi_cdrom_t *) p; - uint16_t *cdbufferw; uint32_t *cdbufferl; @@ -2914,7 +2896,7 @@ scsi_cdrom_packet_write(void *p, uint32_t val, int length) return; if ((dev->packet_status == PHASE_IDLE) && !cdbufferb) - scsi_cdrom_buf_alloc(dev, 12); + buf_alloc(dev, 12); cdbufferw = (uint16_t *) cdbufferb; cdbufferl = (uint32_t *) cdbufferb; @@ -2928,16 +2910,19 @@ scsi_cdrom_packet_write(void *p, uint32_t val, int length) dev->pos++; dev->request_pos++; break; + case 2: cdbufferw[dev->pos >> 1] = val & 0xffff; dev->pos += 2; dev->request_pos += 2; break; + case 4: cdbufferl[dev->pos >> 2] = val; dev->pos += 4; dev->request_pos += 4; break; + default: return; } @@ -2945,10 +2930,12 @@ scsi_cdrom_packet_write(void *p, uint32_t val, int length) if (dev->packet_status == PHASE_DATA_OUT) { if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) { /* Time for a DRQ. */ - scsi_cdrom_pio_request(dev, 1); + pio_request(dev, 1); } return; - } else if (dev->packet_status == PHASE_IDLE) { + } + + if (dev->packet_status == PHASE_IDLE) { if (dev->pos >= 12) { dev->pos = 0; dev->status = BUSY_STAT; @@ -2957,7 +2944,6 @@ scsi_cdrom_packet_write(void *p, uint32_t val, int length) scsi_cdrom_callback(dev); timer_update_outstanding(); } - return; } } @@ -2985,7 +2971,7 @@ scsi_cdrom_stop(void *p) static int -scsi_cdrom_get_max(int ide_has_dma, int type) +get_max(int ide_has_dma, int type) { int ret; @@ -2993,15 +2979,19 @@ scsi_cdrom_get_max(int ide_has_dma, int type) case TYPE_PIO: ret = ide_has_dma ? 4 : 0; break; + case TYPE_SDMA: ret = ide_has_dma ? -1 : 2; break; + case TYPE_MDMA: ret = ide_has_dma ? -1 : 2; break; + case TYPE_UDMA: ret = ide_has_dma ? -1 : 2; break; + default: ret = -1; break; @@ -3012,7 +3002,7 @@ scsi_cdrom_get_max(int ide_has_dma, int type) static int -scsi_cdrom_get_timings(int ide_has_dma, int type) +get_timings(int ide_has_dma, int type) { int ret; @@ -3020,12 +3010,15 @@ scsi_cdrom_get_timings(int ide_has_dma, int type) case TIMINGS_DMA: ret = ide_has_dma ? 120 : 0; break; + case TIMINGS_PIO: ret = ide_has_dma ? 120 : 0; break; + case TIMINGS_PIO_FC: ret = 0; break; + default: ret = 0; break; @@ -3069,6 +3062,39 @@ scsi_cdrom_identify(void *p, int ide_has_dma) } +static void +scsi_cdrom_init(scsi_cdrom_t *dev) +{ + if (!dev) + return; + + dev->drv = &cdrom[dev->id]; + + /* Do a reset (which will also rezero it). */ + scsi_cdrom_reset(dev); + + /* Configure the drive. */ + dev->requested_blocks = 1; + + dev->drv->bus_mode = 0; + if (dev->drv->bus_type >= CDROM_BUS_ATAPI) + dev->drv->bus_mode |= 2; + if (dev->drv->bus_type < CDROM_BUS_SCSI) + dev->drv->bus_mode |= 1; + DEBUG("CD-ROM %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode); + + dev->sense[0] = 0xf0; + dev->sense[7] = 10; + dev->status = READY_STAT | DSC_STAT; + dev->pos = 0; + dev->packet_status = 0xff; + scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = dev->unit_attention = 0; + dev->drv->cur_speed = dev->drv->speed_idx; + + mode_sense_load(dev); +} + + void scsi_cdrom_drive_reset(int c) { @@ -3093,8 +3119,8 @@ scsi_cdrom_drive_reset(int c) scsi_cdrom[c]->drv = drv; drv->p = scsi_cdrom[c]; drv->insert = scsi_cdrom_insert; - drv->get_volume = scsi_cdrom_get_volume; - drv->get_channel = scsi_cdrom_get_channel; + drv->get_volume = get_volume; + drv->get_channel = get_channel; drv->close = scsi_cdrom_close; scsi_cdrom_init(scsi_cdrom[c]); @@ -3106,10 +3132,10 @@ scsi_cdrom_drive_reset(int c) sd->p = scsi_cdrom[c]; sd->command = scsi_cdrom_command; sd->callback = scsi_cdrom_callback; - sd->err_stat_to_scsi = scsi_cdrom_err_stat_to_scsi; - sd->request_sense = scsi_cdrom_request_sense_for_scsi; + sd->err_stat_to_scsi = err_stat_to_scsi; + sd->request_sense = request_sense_for_scsi; sd->reset = scsi_cdrom_reset; - sd->read_capacity = scsi_cdrom_read_capacity; + sd->read_capacity = read_capacity; sd->type = SCSI_REMOVABLE_CDROM; DEBUG("SCSI CD-ROM drive %i attached to SCSI ID %i LUN %i\n", c, cdrom[c].bus_id.scsi.id, cdrom[c].bus_id.scsi.lun); @@ -3121,12 +3147,12 @@ scsi_cdrom_drive_reset(int c) that's not attached to anything. */ if (id) { id->p = scsi_cdrom[c]; - id->get_max = scsi_cdrom_get_max; - id->get_timings = scsi_cdrom_get_timings; + id->get_max = get_max; + id->get_timings = get_timings; id->identify = scsi_cdrom_identify; - id->set_signature = scsi_cdrom_set_signature; - id->packet_write = scsi_cdrom_packet_write; - id->packet_read = scsi_cdrom_packet_read; + id->set_signature = set_signature; + id->packet_write = packet_write; + id->packet_read = packet_read; id->stop = scsi_cdrom_stop; id->packet_callback = scsi_cdrom_callback; id->device_reset = scsi_cdrom_reset; diff --git a/src/devices/scsi/scsi_cdrom.h b/src/devices/scsi/scsi_cdrom.h index fcdecec..90c6252 100644 --- a/src/devices/scsi/scsi_cdrom.h +++ b/src/devices/scsi/scsi_cdrom.h @@ -8,7 +8,7 @@ * * Definitions for the SCSI CD-ROM module. * - * Version: @(#)scsi_cdrom.h 1.0.1 2018/10/14 + * Version: @(#)scsi_cdrom.h 1.0.2 2018/10/17 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -75,21 +75,17 @@ typedef struct { uint8_t previous_command, pad3, pad4, pad5; } scsi_cdrom_t; - - -extern scsi_cdrom_t *scsi_cdrom[CDROM_NUM]; #endif #define scsi_cdrom_sense_error dev->sense[0] #define scsi_cdrom_sense_key dev->sense[2] #define scsi_cdrom_asc dev->sense[12] #define scsi_cdrom_ascq dev->sense[13] -#define scsi_cdrom_drive cdrom[id].host_drive extern void scsi_cdrom_log(int level, const char *fmt, ...); -extern void scsi_cdrom_reset(void *p); +//extern void scsi_cdrom_reset(void *p); #endif /*EMU_SCSI_CDROM_H*/ diff --git a/src/devices/scsi/scsi_device.c b/src/devices/scsi/scsi_device.c index 2a709ae..779213c 100644 --- a/src/devices/scsi/scsi_device.c +++ b/src/devices/scsi/scsi_device.c @@ -8,7 +8,7 @@ * * The generic SCSI device command handler. * - * Version: @(#)scsi_device.c 1.0.9 2018/10/16 + * Version: @(#)scsi_device.c 1.0.11 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -38,6 +38,8 @@ #include #include #include +#include +#define HAVE_STDARG_H #define dbglog scsi_log #include "../../emu.h" #include "../../device.h" @@ -46,8 +48,13 @@ #include "scsi_device.h" +#ifdef ENABLE_SCSI_LOG +int scsi_do_log = ENABLE_SCSI_LOG; +#endif scsi_device_t scsi_devices[SCSI_ID_MAX][SCSI_LUN_MAX]; -const uint8_t scsi_null_device_sense[18] = { + + +static const uint8_t scsi_null_device_sense[18] = { 0x70,0,SENSE_ILLEGAL_REQUEST,0,0,0,0,0,0,0,0,0,ASC_INV_LUN,0,0,0,0,0 }; @@ -193,3 +200,18 @@ scsi_device_get_buf_len(scsi_device_t *dev) { return &dev->buffer_length; } + + +void +scsi_log(int level, const char *fmt, ...) +{ +#ifdef ENABLE_SCSI_LOG + va_list ap; + + if (scsi_do_log >= level) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +#endif +} diff --git a/src/devices/scsi/scsi_device.h b/src/devices/scsi/scsi_device.h index 94adf4f..5360b5b 100644 --- a/src/devices/scsi/scsi_device.h +++ b/src/devices/scsi/scsi_device.h @@ -8,7 +8,7 @@ * * Definitions for the generic SCSI device command handler. * - * Version: @(#)scsi_device.h 1.0.5 2018/10/16 + * Version: @(#)scsi_device.h 1.0.6 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -292,18 +292,6 @@ #define SCSI_REMOVABLE_CDROM 0x8005 -#if 0 -typedef struct { - uint8_t command[20]; - int state, new_state, - clear_req, dev_id, - command_pos, data_pos, - change_state_delay, - new_req_delay; - uint32_t bus_in, bus_out; -} scsi_bus_t; -#endif - typedef struct { uint8_t id, lun; uint16_t type; @@ -362,7 +350,7 @@ typedef struct { extern scsi_device_t scsi_devices[SCSI_ID_MAX][SCSI_LUN_MAX]; -extern void scsi_dev_log(int level, const char *fmt, ...); +extern void scsi_log(int level, const char *fmt, ...); extern int cdrom_add_error_and_subchannel(uint8_t *b, int real_sector_type); extern int cdrom_LBAtoMSF_accurate(void); diff --git a/src/devices/scsi/scsi_ncr5380.c b/src/devices/scsi/scsi_ncr5380.c index e731c58..85a30ae 100644 --- a/src/devices/scsi/scsi_ncr5380.c +++ b/src/devices/scsi/scsi_ncr5380.c @@ -11,7 +11,7 @@ * * NOTE: This code now only supports targets at LUN=0 !! * - * Version: @(#)scsi_ncr5380.c 1.0.11 2018/10/14 + * Version: @(#)scsi_ncr5380.c 1.0.12 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -46,7 +46,7 @@ #include #include #include -#define dbglog scsi_dev_log +#define dbglog scsi_card_log #include "../../emu.h" #include "../../io.h" #include "../../mem.h" diff --git a/src/devices/scsi/scsi_ncr53c810.c b/src/devices/scsi/scsi_ncr53c810.c index f330060..4bb6a9b 100644 --- a/src/devices/scsi/scsi_ncr53c810.c +++ b/src/devices/scsi/scsi_ncr53c810.c @@ -10,7 +10,7 @@ * NCR and later Symbios and LSI. This controller was designed * for the PCI bus. * - * Version: @(#)scsi_ncr53c810.c 1.0.11 2018/10/14 + * Version: @(#)scsi_ncr53c810.c 1.0.12 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -46,7 +46,7 @@ #include #include #include -#define dbglog scsi_dev_log +#define dbglog scsi_card_log #include "../../emu.h" #include "../../io.h" #include "../../mem.h" diff --git a/src/devices/scsi/scsi_x54x.c b/src/devices/scsi/scsi_x54x.c index 1c06854..bd3a377 100644 --- a/src/devices/scsi/scsi_x54x.c +++ b/src/devices/scsi/scsi_x54x.c @@ -12,7 +12,7 @@ * * These controllers were designed for various buses. * - * Version: @(#)scsi_x54x.c 1.0.14 2018/10/16 + * Version: @(#)scsi_x54x.c 1.0.15 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -45,7 +45,7 @@ #include #include #include -#define dbglog scsi_dev_log +#define dbglog scsi_card_log #include "../../emu.h" #include "../../io.h" #include "../../mem.h" diff --git a/src/devices/sound/snd_ad1848.c b/src/devices/sound/snd_ad1848.c index 266ad92..a318011 100644 --- a/src/devices/sound/snd_ad1848.c +++ b/src/devices/sound/snd_ad1848.c @@ -8,7 +8,7 @@ * * Emulation of the AD1848 (Windows Sound System) CODEC. * - * Version: @(#)snd_ad1848.c 1.0.5 2018/09/15 + * Version: @(#)snd_ad1848.c 1.0.6 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -41,7 +41,7 @@ #include #include #include -#define dbglog sound_dev_log +#define dbglog sound_card_log #include "../../emu.h" #include "../../timer.h" #include "../system/dma.h" diff --git a/src/devices/sound/snd_adlib.c b/src/devices/sound/snd_adlib.c index ecce028..c17b00d 100644 --- a/src/devices/sound/snd_adlib.c +++ b/src/devices/sound/snd_adlib.c @@ -8,7 +8,7 @@ * * Implementation of the ADLIB sound device. * - * Version: @(#)snd_adlib.c 1.0.5 2018/09/22 + * Version: @(#)snd_adlib.c 1.0.7 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -41,7 +41,7 @@ #include #include #include -#define dbglog sound_dev_log +#define dbglog sound_card_log #include "../../emu.h" #include "../../io.h" #include "../../device.h" diff --git a/src/devices/sound/snd_adlibgold.c b/src/devices/sound/snd_adlibgold.c index 3d6554a..9a52000 100644 --- a/src/devices/sound/snd_adlibgold.c +++ b/src/devices/sound/snd_adlibgold.c @@ -10,7 +10,7 @@ * * TODO: Stack allocation of big buffers (line 688 et al.) * - * Version: @(#)snd_adlibgold.c 1.0.9 2018/10/05 + * Version: @(#)snd_adlibgold.c 1.0.10 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -43,7 +43,7 @@ #include #include #include -#define dbglog sound_dev_log +#define dbglog sound_card_log #include "../../emu.h" #include "../../io.h" #include "../../timer.h" diff --git a/src/devices/sound/snd_audiopci.c b/src/devices/sound/snd_audiopci.c index e8963fb..60f5eb3 100644 --- a/src/devices/sound/snd_audiopci.c +++ b/src/devices/sound/snd_audiopci.c @@ -8,7 +8,7 @@ * * Implementation of the AudioPCI sound device. * - * Version: @(#)snd_audiopci.c 1.0.13 2018/09/22 + * Version: @(#)snd_audiopci.c 1.0.14 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -41,7 +41,7 @@ #include #include #include -#define dbglog sound_dev_log +#define dbglog sound_card_log #include "../../emu.h" #include "../../cpu/cpu.h" /* for the debugging stuff */ #include "../../io.h" diff --git a/src/devices/sound/snd_cms.c b/src/devices/sound/snd_cms.c index 2dcca72..212df79 100644 --- a/src/devices/sound/snd_cms.c +++ b/src/devices/sound/snd_cms.c @@ -8,7 +8,7 @@ * * Implementation of the Creative CMS/GameBlaster sound device. * - * Version: @(#)snd_cms.c 1.0.6 2018/09/22 + * Version: @(#)snd_cms.c 1.0.7 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -41,7 +41,7 @@ #include #include #include -#define dbglog sound_dev_log +#define dbglog sound_card_log #include "../../emu.h" #include "../../io.h" #include "../../device.h" diff --git a/src/devices/sound/snd_emu8k.c b/src/devices/sound/snd_emu8k.c index 667f36b..4b65ba0 100644 --- a/src/devices/sound/snd_emu8k.c +++ b/src/devices/sound/snd_emu8k.c @@ -8,7 +8,7 @@ * * Implementation of Emu8000 emulator. * - * Version: @(#)snd_emu8k.c 1.0.12 2018/09/22 + * Version: @(#)snd_emu8k.c 1.0.13 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -44,7 +44,7 @@ #include #include #include -#define dbglog sound_dev_log +#define dbglog sound_card_log #include "../../emu.h" #include "../../io.h" #include "../../mem.h" diff --git a/src/devices/sound/snd_gus.c b/src/devices/sound/snd_gus.c index a107334..30f922e 100644 --- a/src/devices/sound/snd_gus.c +++ b/src/devices/sound/snd_gus.c @@ -8,7 +8,7 @@ * * Implementation of the Gravis UltraSound sound device. * - * Version: @(#)snd_gus.c 1.0.6 2018/09/22 + * Version: @(#)snd_gus.c 1.0.7 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -41,7 +41,7 @@ #include #include #include -#define dbglog sound_dev_log +#define dbglog sound_card_log #include "../../emu.h" #include "../../io.h" #include "../../timer.h" diff --git a/src/devices/sound/snd_lpt_dac.c b/src/devices/sound/snd_lpt_dac.c index e403cf1..18b8dc1 100644 --- a/src/devices/sound/snd_lpt_dac.c +++ b/src/devices/sound/snd_lpt_dac.c @@ -8,7 +8,7 @@ * * Implemantation of LPT-based sound devices. * - * Version: @(#)snd_lpt_dac.c 1.0.8 2018/09/22 + * Version: @(#)snd_lpt_dac.c 1.0.9 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -41,7 +41,7 @@ #include #include #include -#define dbglog sound_dev_log +#define dbglog sound_card_log #include "../../emu.h" #include "../../cpu/cpu.h" #include "../../machines/machine.h" diff --git a/src/devices/sound/snd_lpt_dss.c b/src/devices/sound/snd_lpt_dss.c index bbe3e64..d901ee0 100644 --- a/src/devices/sound/snd_lpt_dss.c +++ b/src/devices/sound/snd_lpt_dss.c @@ -8,7 +8,7 @@ * * Implementation of the LPT-based DSS sound device. * - * Version: @(#)snd_lpt_dss.c 1.0.8 2018/09/22 + * Version: @(#)snd_lpt_dss.c 1.0.9 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -41,7 +41,7 @@ #include #include #include -#define dbglog sound_dev_log +#define dbglog sound_card_log #include "../../emu.h" #include "../../cpu/cpu.h" #include "../../machines/machine.h" diff --git a/src/devices/sound/snd_opl.c b/src/devices/sound/snd_opl.c index dc5878d..4dfbd33 100644 --- a/src/devices/sound/snd_opl.c +++ b/src/devices/sound/snd_opl.c @@ -8,7 +8,7 @@ * * Interface to the actual OPL emulator. * - * Version: @(#)snd_opl.c 1.0.3 2018/09/15 + * Version: @(#)snd_opl.c 1.0.4 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -42,7 +42,7 @@ #include #include #include -#define dbglog sound_dev_log +#define dbglog sound_card_log #include "../../emu.h" #include "../../cpu/cpu.h" #include "../../io.h" diff --git a/src/devices/sound/snd_pas16.c b/src/devices/sound/snd_pas16.c index c7d8d7c..f3c6f73 100644 --- a/src/devices/sound/snd_pas16.c +++ b/src/devices/sound/snd_pas16.c @@ -79,7 +79,7 @@ * FF88 - board model * 3 = PAS16 * - * Version: @(#)snd_pas16.c 1.0.7 2018/09/22 + * Version: @(#)snd_pas16.c 1.0.8 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -112,7 +112,7 @@ #include #include #include -#define dbglog sound_dev_log +#define dbglog sound_card_log #include "../../emu.h" #include "../../cpu/cpu.h" #include "../../io.h" diff --git a/src/devices/sound/snd_sb.c b/src/devices/sound/snd_sb.c index d9665e7..9f9108b 100644 --- a/src/devices/sound/snd_sb.c +++ b/src/devices/sound/snd_sb.c @@ -8,7 +8,7 @@ * * Sound Blaster emulation. * - * Version: @(#)snd_sb.c 1.0.7 2018/09/25 + * Version: @(#)snd_sb.c 1.0.8 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -42,7 +42,7 @@ #include #include #include -#define dbglog sound_dev_log +#define dbglog sound_card_log #include "../../emu.h" #include "../../io.h" #include "../../mem.h" diff --git a/src/devices/sound/snd_sb_dsp.c b/src/devices/sound/snd_sb_dsp.c index 1108fc7..60aba38 100644 --- a/src/devices/sound/snd_sb_dsp.c +++ b/src/devices/sound/snd_sb_dsp.c @@ -14,7 +14,7 @@ * 486-50 - 32kHz * Pentium - 45kHz * - * Version: @(#)snd_sb_dsp.c 1.0.7 2018/09/25 + * Version: @(#)snd_sb_dsp.c 1.0.8 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -48,7 +48,7 @@ #include #include #include -#define dbglog sound_dev_log +#define dbglog sound_card_log #include "../../emu.h" #include "../../io.h" #include "../../timer.h" diff --git a/src/devices/sound/snd_sn76489.c b/src/devices/sound/snd_sn76489.c index fd59408..da00c77 100644 --- a/src/devices/sound/snd_sn76489.c +++ b/src/devices/sound/snd_sn76489.c @@ -8,7 +8,7 @@ * * Implementation of the TI SN74689 PSG sound devices. * - * Version: @(#)snd_sn76489.c 1.0.5 2018/09/22 + * Version: @(#)snd_sn76489.c 1.0.6 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -42,7 +42,7 @@ #include #include #include -#define dbglog sound_dev_log +#define dbglog sound_card_log #include "../../emu.h" #include "../../io.h" #include "../../device.h" diff --git a/src/devices/sound/snd_speaker.c b/src/devices/sound/snd_speaker.c index f2c513e..9ad42ef 100644 --- a/src/devices/sound/snd_speaker.c +++ b/src/devices/sound/snd_speaker.c @@ -8,7 +8,7 @@ * * Implementation of the PC-Speaker device. * - * Version: @(#)snd_speaker.c 1.0.3 2018/09/22 + * Version: @(#)snd_speaker.c 1.0.4 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ #include #include #include -#define dbglog sound_dev_log +#define dbglog sound_card_log #include "../../emu.h" #include "../system/pit.h" #include "sound.h" diff --git a/src/devices/sound/snd_ssi2001.c b/src/devices/sound/snd_ssi2001.c index bf58b79..125c0c3 100644 --- a/src/devices/sound/snd_ssi2001.c +++ b/src/devices/sound/snd_ssi2001.c @@ -8,7 +8,7 @@ * * Implementation of the SSI2001 sound device. * - * Version: @(#)snd_ssi2001.c 1.0.6 2018/09/22 + * Version: @(#)snd_ssi2001.c 1.0.7 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -41,7 +41,7 @@ #include #include #include -#define dbglog sound_dev_log +#define dbglog sound_card_log #include "../../emu.h" #include "../../io.h" #include "../../device.h" diff --git a/src/devices/sound/snd_wss.c b/src/devices/sound/snd_wss.c index 8a87cb0..3b910fc 100644 --- a/src/devices/sound/snd_wss.c +++ b/src/devices/sound/snd_wss.c @@ -8,7 +8,7 @@ * * Implementation of the Windows Sound System sound device. * - * Version: @(#)snd_wss.c 1.0.5 2018/09/22 + * Version: @(#)snd_wss.c 1.0.6 2018/10/16 * * Authors: Fred N. van Kempen, * TheCollector1995, @@ -44,7 +44,7 @@ #include #include #include -#define dbglog sound_dev_log +#define dbglog sound_card_log #include "../../emu.h" #include "../../io.h" #include "../../device.h" diff --git a/src/devices/sound/snd_ym7128.c b/src/devices/sound/snd_ym7128.c index 0f00a12..b43dcbe 100644 --- a/src/devices/sound/snd_ym7128.c +++ b/src/devices/sound/snd_ym7128.c @@ -8,7 +8,7 @@ * * Implementation of the Yamaha YM7128 sound device. * - * Version: @(#)snd_ym7128.c 1.0.3 2018/09/15 + * Version: @(#)snd_ym7128.c 1.0.4 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -40,7 +40,7 @@ #include #include #include -#define dbglog sound_dev_log +#define dbglog sound_card_log #include "../../emu.h" #include "snd_ym7128.h" diff --git a/src/devices/sound/sound.h b/src/devices/sound/sound.h index 0950b65..40f0cd0 100644 --- a/src/devices/sound/sound.h +++ b/src/devices/sound/sound.h @@ -8,7 +8,7 @@ * * Definitions for the Sound Emulation core. * - * Version: @(#)sound.h 1.0.9 2018/09/22 + * Version: @(#)sound.h 1.0.10 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -53,19 +53,16 @@ extern "C" { #endif -extern int sound_do_log, - sound_dev_do_log; - extern int sound_pos_global; extern volatile int soundon; extern void sound_log(int level, const char *fmt, ...); -extern void sound_dev_log(int level, const char *fmt, ...); extern void sound_add_handler(void (*get_buffer)(int32_t *buffer, \ int len, void *p), void *p); +extern void sound_card_log(int level, const char *fmt, ...); extern int sound_card_available(int card); extern const char *sound_card_getname(int card); #ifdef EMU_DEVICE_H diff --git a/src/devices/sound/sound_dev.c b/src/devices/sound/sound_dev.c index 5508318..ce9b5a3 100644 --- a/src/devices/sound/sound_dev.c +++ b/src/devices/sound/sound_dev.c @@ -8,7 +8,7 @@ * * Sound devices support module. * - * Version: @(#)sound_dev.c 1.0.7 2018/09/22 + * Version: @(#)sound_dev.c 1.0.8 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -43,7 +43,7 @@ #include #include #define HAVE_STDARG_H -#define dbglog sound_dev_log +#define dbglog sound_card_log #include "../../emu.h" #include "../../device.h" #include "../../plat.h" @@ -51,7 +51,7 @@ #ifdef ENABLE_SOUND_DEV_LOG -int sound_dev_do_log = ENABLE_SOUND_DEV_LOG; +int sound_card_do_log = ENABLE_SOUND_DEV_LOG; #endif @@ -116,12 +116,12 @@ static struct { void -sound_dev_log(int level, const char *fmt, ...) +sound_card_log(int level, const char *fmt, ...) { #ifdef ENABLE_SOUND_DEV_LOG va_list ap; - if (sound_dev_do_log >= level) { + if (sound_card_do_log >= level) { va_start(ap, fmt); pclog_ex(fmt, ap); va_end(ap); diff --git a/src/devices/system/intel_piix.c b/src/devices/system/intel_piix.c index d351535..0ee1c0f 100644 --- a/src/devices/system/intel_piix.c +++ b/src/devices/system/intel_piix.c @@ -823,19 +823,9 @@ piix_reset_hard(void *priv) static void piix_reset(void *p) { - int i; - - //FIXME: cdrom_reset_bus(CDROM_BUS_ATAPI); --FvK - for (i = 0; i < CDROM_NUM; i++) { - if (cdrom[i].bus_type == CDROM_BUS_ATAPI) - scsi_cdrom_reset(scsi_cdrom[i]); - } - - //FIXME: zip_reset_bus(ZIP_BUS_ATAPI); --FvK - for (i = 0; i < ZIP_NUM; i++) { - if (zip_drives[i].bus_type == ZIP_BUS_ATAPI) - zip_reset(zip[i]); - } + //FIXME: this should be ide_reset() ... + cdrom_reset_bus(CDROM_BUS_ATAPI); + zip_reset_bus(CDROM_BUS_ATAPI); } diff --git a/src/devices/video/video.h b/src/devices/video/video.h index 1152590..cd5756a 100644 --- a/src/devices/video/video.h +++ b/src/devices/video/video.h @@ -8,7 +8,7 @@ * * Definitions for the video controller module. * - * Version: @(#)video.h 1.0.18 2018/09/30 + * Version: @(#)video.h 1.0.19 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -296,6 +296,7 @@ extern const device_t wy700_device; /* Table functions. */ +extern void video_card_log(int level, const char *fmt, ...); extern int video_card_available(int card); extern const char *video_card_getname(int card); extern const char *video_get_internal_name(int card); diff --git a/src/devices/video/video_dev.c b/src/devices/video/video_dev.c index 094a612..3c10763 100644 --- a/src/devices/video/video_dev.c +++ b/src/devices/video/video_dev.c @@ -12,7 +12,7 @@ * "extern" reference to its device into the video.h file, * and add an entry for it into the table here. * - * Version: @(#)video_dev.c 1.0.22 2018/10/05 + * Version: @(#)video_dev.c 1.0.23 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -42,7 +42,9 @@ #include #include #include +#include #include +#define HAVE_STDARG_H #include "../../emu.h" #include "../../machines/machine.h" #include "../../mem.h" @@ -51,7 +53,12 @@ #include "video.h" -static struct { +#ifdef ENABLE_VIDEO_DEV_LOG +int video_card_do_log = ENABLE_VIDEO_DEV_LOG; +#endif + + +static const struct { const char *internal_name; const device_t *device; } video_cards[] = { @@ -153,6 +160,21 @@ static struct { }; +void +video_card_log(int level, const char *fmt, ...) +{ +#ifdef ENABLE_VIDEO_DEV_LOG + va_list ap; + + if (video_card_do_log >= level) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +#endif +} + + void video_reset(void) { diff --git a/src/emu.h b/src/emu.h index 894f442..965b378 100644 --- a/src/emu.h +++ b/src/emu.h @@ -8,7 +8,7 @@ * * Main include file for the application. * - * Version: @(#)emu.h 1.0.32 2018/10/05 + * Version: @(#)emu.h 1.0.33 2018/10/16 * * Author: Fred N. van Kempen, * @@ -254,16 +254,18 @@ extern int hdd_do_log; extern int zip_do_log; extern int cdrom_do_log; extern int cdrom_image_do_log; -extern int cdrom_ioctl_do_log; +extern int cdrom_host_do_log; extern int sound_do_log; extern int sound_midi_do_log; -extern int sound_dev_do_log; +extern int sound_card_do_log; extern int network_do_log; -extern int network_dev_do_log; +extern int network_card_do_log; extern int scsi_do_log; +extern int scsi_card_do_log; +extern int scsi_cdrom_do_log; extern int scsi_disk_do_log; -extern int scsi_dev_do_log; extern int video_do_log; +extern int video_card_do_log; #endif diff --git a/src/plat.h b/src/plat.h index f816b23..05f4fb4 100644 --- a/src/plat.h +++ b/src/plat.h @@ -8,7 +8,7 @@ * * Define the various platform support functions. * - * Version: @(#)plat.h 1.0.18 2018/09/29 + * Version: @(#)plat.h 1.0.19 2018/10/16 * * Author: Fred N. van Kempen, * @@ -180,18 +180,6 @@ extern void dynld_close(void *); extern void plat_start(void); extern void plat_stop(void); - -/* Platform-specific device support. */ -extern uint8_t host_cdrom_drive_available[26]; -extern uint8_t host_cdrom_drive_available_num; - -#ifdef USE_IOCTL -extern void cdrom_init_host_drives(void); -extern int ioctl_open(uint8_t id, char d); -extern void ioctl_reset(uint8_t id); -extern void ioctl_close(uint8_t id); -#endif - extern void plat_midi_init(void); extern void plat_midi_close(void); extern void plat_midi_play_msg(uint8_t *msg); diff --git a/src/ui/ui_main.c b/src/ui/ui_main.c index ea4c5c4..edd5230 100644 --- a/src/ui/ui_main.c +++ b/src/ui/ui_main.c @@ -11,10 +11,7 @@ * This code is called by the UI frontend modules, and, also, * depends on those same modules for lower-level functions. * - * FIXME: Still have to figure out how cleanly set initial logging - * levels for modules, and how to toggle/update those... - * - * Version: @(#)ui_main.c 1.0.18 2018/10/01 + * Version: @(#)ui_main.c 1.0.19 2018/10/16 * * Author: Fred N. van Kempen, * @@ -153,19 +150,15 @@ set_logging_item(int idm, int val) ptr = (val != -3) ? &cdrom_do_log : (void *)"CD-ROM"; break; # endif - # ifdef ENABLE_CDROM_IMAGE_LOG case IDM_LOG_CDROM_IMAGE: ptr = (val != -3) ? &cdrom_image_do_log : (void *)"CD-ROM (image)"; break; # endif - -# ifdef USE_CDROM_IOCTL -# ifdef ENABLE_CDROM_IOCTL_LOG - case IDM_LOG_CDROM_IOCTL: - ptr = (val != -3) ? &cdrom_ioctl_do_log : (void *)"CD-ROM (ioctl)"; +# ifdef ENABLE_CDROM_HOST_LOG + case IDM_LOG_CDROM_HOST: + ptr = (val != -3) ? &cdrom_host_do_log : (void *)"CD-ROM (host)"; break; -# endif # endif # ifdef ENABLE_NETWORK_LOG @@ -173,10 +166,9 @@ set_logging_item(int idm, int val) ptr = (val != -3) ? &network_do_log : (void *)"Network"; break; # endif - # ifdef ENABLE_NETWORK_DEV_LOG case IDM_LOG_NETWORK_DEV: - ptr = (val != -3) ? &network_dev_do_log : (void *)"Network Device"; + ptr = (val != -3) ? &network_card_do_log : (void *)"Network Device"; break; # endif @@ -185,41 +177,47 @@ set_logging_item(int idm, int val) ptr = (val != -3) ? &sound_do_log : (void *)"Sound"; break; # endif - +# ifdef ENABLE_SOUND_DEV_LOG + case IDM_LOG_SOUND_DEV: + ptr = (val != -3) ? &sound_card_do_log : (void *)"Sound Device"; + break; +# endif # ifdef ENABLE_SOUND_MIDI_LOG case IDM_LOG_SOUND_MIDI: ptr = (val != -3) ? &sound_midi_do_log : (void *)"Sound (MIDI)"; break; # endif -# ifdef ENABLE_SOUND_DEV_LOG - case IDM_LOG_SOUND_DEV: - ptr = (val != -3) ? &sound_dev_do_log : (void *)"Sound Device"; - break; -# endif - # ifdef ENABLE_SCSI_LOG case IDM_LOG_SCSI: ptr = (val != -3) ? &scsi_do_log : (void *)"SCSI"; break; # endif - +# ifdef ENABLE_SCSI_DEV_LOG + case IDM_LOG_SCSI_DEV: + ptr = (val != -3) ? &scsi_card_do_log : (void *)"SCSI Device"; + break; +# endif +# ifdef ENABLE_SCSI_CDROM_LOG + case IDM_LOG_SCSI_CDROM: + ptr = (val != -3) ? &scsi_cdrom_do_log : (void *)"SCSI (CD-ROM)"; + break; +# endif # ifdef ENABLE_SCSI_DISK_LOG case IDM_LOG_SCSI_DISK: ptr = (val != -3) ? &scsi_disk_do_log : (void *)"SCSI (Disk)"; break; # endif -# ifdef ENABLE_SCSI_DEV_LOG - case IDM_LOG_SCSI_DEV: - ptr = (val != -3) ? &scsi_dev_do_log : (void *)"SCSI Device"; - break; -# endif - # ifdef ENABLE_VIDEO_LOG case IDM_LOG_VIDEO: ptr = (val != -3) ? &video_do_log : (void *)"Video"; break; +# endif +# ifdef ENABLE_VIDEO_DEV_LOG + case IDM_LOG_VIDEO_DEV: + ptr = (val != -3) ? &video_card_do_log : (void *)"Video Device"; + break; # endif } diff --git a/src/ui/ui_resource.h b/src/ui/ui_resource.h index 9d5f35f..4d6651e 100644 --- a/src/ui/ui_resource.h +++ b/src/ui/ui_resource.h @@ -12,7 +12,7 @@ * those are not used by the platform code. This is easier to * maintain. * - * Version: @(#)ui_resource.h 1.0.16 2018/10/01 + * Version: @(#)ui_resource.h 1.0.17 2018/10/16 * * Author: Fred N. van Kempen, * @@ -135,17 +135,19 @@ # define IDM_LOG_ZIP (IDM_LOG_BEGIN+11) # define IDM_LOG_CDROM (IDM_LOG_BEGIN+12) # define IDM_LOG_CDROM_IMAGE (IDM_LOG_BEGIN+13) -# define IDM_LOG_CDROM_IOCTL (IDM_LOG_BEGIN+14) +# define IDM_LOG_CDROM_HOST (IDM_LOG_BEGIN+14) # define IDM_LOG_NETWORK (IDM_LOG_BEGIN+15) # define IDM_LOG_NETWORK_DEV (IDM_LOG_BEGIN+16) # define IDM_LOG_SOUND (IDM_LOG_BEGIN+17) # define IDM_LOG_SOUND_MIDI (IDM_LOG_BEGIN+18) # define IDM_LOG_SOUND_DEV (IDM_LOG_BEGIN+19) # define IDM_LOG_SCSI (IDM_LOG_BEGIN+20) -# define IDM_LOG_SCSI_DISK (IDM_LOG_BEGIN+21) -# define IDM_LOG_SCSI_DEV (IDM_LOG_BEGIN+22) -# define IDM_LOG_VIDEO (IDM_LOG_BEGIN+23) -# define IDM_LOG_END (IDM_LOG_BEGIN+24) +# define IDM_LOG_SCSI_DEV (IDM_LOG_BEGIN+21) +# define IDM_LOG_SCSI_CDROM (IDM_LOG_BEGIN+22) +# define IDM_LOG_SCSI_DISK (IDM_LOG_BEGIN+23) +# define IDM_LOG_VIDEO (IDM_LOG_BEGIN+28) +# define IDM_LOG_VIDEO_DEV (IDM_LOG_BEGIN+29) +# define IDM_LOG_END (IDM_LOG_BEGIN+30) #define IDM_LOAD (IDM_TOOLS+90) #define IDM_SAVE (IDM_TOOLS+91) #define IDM_SCREENSHOT (IDM_TOOLS+92) diff --git a/src/ui/ui_stbar.c b/src/ui/ui_stbar.c index e4af1a7..cb64d87 100644 --- a/src/ui/ui_stbar.c +++ b/src/ui/ui_stbar.c @@ -8,7 +8,7 @@ * * Common UI support functions for the Status Bar module. * - * Version: @(#)ui_stbar.c 1.0.11 2018/10/15 + * Version: @(#)ui_stbar.c 1.0.13 2018/10/17 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -350,8 +350,10 @@ menu_floppy(int part, int drive) static void menu_cdrom(int part, int drive) { +#ifdef USE_HOST_CDROM wchar_t temp[64]; int i; +#endif sb_menu_add_item(part, IDM_CDROM_MUTE | drive, get_string(IDS_3923)); sb_menu_add_item(part, -1, NULL); @@ -360,17 +362,19 @@ menu_cdrom(int part, int drive) sb_menu_add_item(part, -1, NULL); sb_menu_add_item(part, IDM_CDROM_EMPTY | drive, get_string(IDS_3906)); - if (host_cdrom_drive_available_num == 0) { +#ifdef USE_HOST_CDROM + if (cdrom_host_drive_available_num == 0) { +#endif if ((cdrom[drive].host_drive >= 'A') && - (cdrom[drive].host_drive <= 'Z')) { + (cdrom[drive].host_drive <= 'Z')) cdrom[drive].host_drive = 0; - } +#ifdef USE_HOST_CDROM goto check_items; } else { if ((cdrom[drive].host_drive >= 'A') && (cdrom[drive].host_drive <= 'Z')) { - if (! host_cdrom_drive_available[cdrom[drive].host_drive - 'A']) { + if (! cdrom_host_drive_available[cdrom[drive].host_drive - 'A']) { cdrom[drive].host_drive = 0; } } @@ -380,11 +384,12 @@ menu_cdrom(int part, int drive) for (i = 3; i < 26; i++) { swprintf(temp, sizeof_w(temp), get_string(IDS_3921), i+'A'); - if (host_cdrom_drive_available[i]) + if (cdrom_host_drive_available[i]) sb_menu_add_item(part, IDM_CDROM_HOST_DRIVE | (i << 3)|drive, temp); } check_items: +#endif if (! cdrom[drive].sound_on) sb_menu_set_item(part, IDM_CDROM_MUTE | drive, 1); @@ -831,8 +836,7 @@ ui_sb_menu_command(int idm, uint8_t tag) wcscpy(cdrom[drive].prev_image_path, str); /* Close the current drive/pathname. */ - cdrom[drive].ops->exit(&cdrom[drive]); - cdrom_close_handler(drive); + cdrom[drive].ops->close(&cdrom[drive]); memset(cdrom[drive].image_path, 0, sizeof(cdrom[drive].image_path)); /* Now open new image. */ @@ -877,12 +881,11 @@ ui_sb_menu_command(int idm, uint8_t tag) cdrom[drive].prev_host_drive = cdrom[drive].host_drive; /* Close the current drive/pathname. */ - cdrom[drive].ops->exit(&cdrom[drive]); - cdrom_close_handler(drive); + cdrom[drive].ops->close(&cdrom[drive]); memset(cdrom[drive].image_path, 0, sizeof(cdrom[drive].image_path)); -#ifdef USE_CDROM_IOCTL - ioctl_open(drive, new_cdrom_drive); +#ifdef USE_HOST_CDROM + cdrom_host_open(&cdrom[drive], new_cdrom_drive); #endif /* Signal media change to the emulated machine. */ diff --git a/src/win/VARCem.rc b/src/win/VARCem.rc index 449469d..3417dfb 100644 --- a/src/win/VARCem.rc +++ b/src/win/VARCem.rc @@ -8,7 +8,7 @@ * * Application resource script for Windows. * - * Version: @(#)VARCem.rc 1.0.33 2018/09/27 + * Version: @(#)VARCem.rc 1.0.34 2018/10/16 * * Author: Fred N. van Kempen, * @@ -103,8 +103,8 @@ BEGIN # ifdef ENABLE_CDROM_IMAGE_LOG VK_F2, IDM_LOG_CDROM_IMAGE, VIRTKEY, CONTROL # endif -# ifdef ENABLE_CDROM_IOCTL_LOG - VK_F3, IDM_LOG_CDROM_IOCTL, VIRTKEY, CONTROL +# ifdef ENABLE_CDROM_HOST_LOG + VK_F3, IDM_LOG_CDROM_HOST, VIRTKEY, CONTROL # endif # ifdef ENABLE_NETWORK_LOG VK_F4, IDM_LOG_NETWORK, VIRTKEY, CONTROL @@ -115,20 +115,20 @@ BEGIN # ifdef ENABLE_SOUND_LOG VK_F6, IDM_LOG_SOUND, VIRTKEY, CONTROL, ALT # endif -# ifdef ENABLE_SOUND_MIDI_LOG - VK_F7, IDM_LOG_SOUND_MIDI, VIRTKEY, CONTROL, ALT -# endif # ifdef ENABLE_SOUND_DEV_LOG - VK_F8, IDM_LOG_SOUND_DEV, VIRTKEY, CONTROL, ALT + VK_F7, IDM_LOG_SOUND_DEV, VIRTKEY, CONTROL, ALT +# endif +# ifdef ENABLE_SOUND_MIDI_LOG + VK_F8, IDM_LOG_SOUND_MIDI, VIRTKEY, CONTROL, ALT # endif # ifdef ENABLE_SCSI_LOG VK_F9, IDM_LOG_SCSI, VIRTKEY, CONTROL, ALT # endif -# ifdef ENABLE_SCSI_DISK_LOG - VK_F10, IDM_LOG_SCSI_DISK, VIRTKEY, CONTROL, ALT -# endif # ifdef ENABLE_SCSI_DEV_LOG - VK_F11, IDM_LOG_SCSI_DEV, VIRTKEY, CONTROL, ALT + VK_F10, IDM_LOG_SCSI_DEV, VIRTKEY, CONTROL, ALT +# endif +# ifdef ENABLE_SCSI_DISK_LOG + VK_F11, IDM_LOG_SCSI_DISK, VIRTKEY, CONTROL, ALT # endif # ifdef ENABLE_VIDEO_LOG VK_F12, IDM_LOG_VIDEO, VIRTKEY, CONTROL, ALT diff --git a/src/win/mingw/Makefile.MinGW b/src/win/mingw/Makefile.MinGW index aeacb83..5a29591 100644 --- a/src/win/mingw/Makefile.MinGW +++ b/src/win/mingw/Makefile.MinGW @@ -8,7 +8,7 @@ # # Makefile for Windows systems using the MinGW32 environment. # -# Version: @(#)Makefile.mingw 1.0.61 2018/10/14 +# Version: @(#)Makefile.mingw 1.0.62 2018/10/17 # # Author: Fred N. van Kempen, # @@ -146,6 +146,9 @@ endif ifndef PRINTER PRINTER := n endif +ifndef HOSTCD + HOSTCD := n +endif # Name of the executable. @@ -179,6 +182,7 @@ ifeq ($(DEV_BUILD), y) PAS16 := y XL24 := y WONDER := y + HOSTCD := y endif @@ -556,6 +560,10 @@ ifeq ($(DEV_BRANCH), y) DEVBROBJ += prt_parallel.o endif + ifeq ($(HOSTCD), y) + OPTS += -DUSE_HOST_CDROM + endif + endif diff --git a/src/win/msvc/Makefile.VC b/src/win/msvc/Makefile.VC index 08762aa..47a4a61 100644 --- a/src/win/msvc/Makefile.VC +++ b/src/win/msvc/Makefile.VC @@ -8,7 +8,7 @@ # # Makefile for Windows using Visual Studio 2015. # -# Version: @(#)Makefile.VC 1.0.47 2018/10/14 +# Version: @(#)Makefile.VC 1.0.48 2018/10/17 # # Author: Fred N. van Kempen, # @@ -144,6 +144,9 @@ endif ifndef WONDER WONDER := n endif +ifndef HOSTCD + HOSTCD := n +endif ifndef PRINTER PRINTER := n endif @@ -180,6 +183,8 @@ ifeq ($(DEV_BUILD), y) PAS16 := y XL24 := y WONDER := y + HOSTCD := y + PRINTER := y endif @@ -524,6 +529,10 @@ ifeq ($(DEV_BRANCH), y) OPTS += -DUSE_WONDER endif + ifeq ($(HOSTCD), y) + OPTS += -DUSE_HOST_CDROM + endif + ifeq ($(PRINTER), y) OPTS += -DUSE_PRINTER DEVBROBJ += prt_parallel.obj diff --git a/src/win/win.c b/src/win/win.c index 0bc0d45..4b0c9c0 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -8,7 +8,7 @@ * * Platform main support module for Windows. * - * Version: @(#)win.c 1.0.21 2018/10/07 + * Version: @(#)win.c 1.0.23 2018/10/17 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -66,6 +66,7 @@ #ifdef USE_RDP # include #endif +#include "../devices/cdrom/cdrom.h" #include "../devices/input/mouse.h" #include "../devices/video/video.h" #ifdef USE_WX @@ -255,6 +256,10 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow) (void)ui_lang_set(lang); } +#ifdef USE_HOST_CDROM + cdrom_host_init(); +#endif + /* Create a mutex for the video handler. */ hBlitMutex = CreateMutex(NULL, FALSE, MUTEX_NAME); diff --git a/src/win/win_cdrom.c b/src/win/win_cdrom.c index d6dfd57..2175378 100644 --- a/src/win/win_cdrom.c +++ b/src/win/win_cdrom.c @@ -10,7 +10,7 @@ * Implementation of the CD-ROM host drive IOCTL interface for * Windows using SCSI Passthrough Direct. * - * Version: @(#)win_cdrom.c 1.0.10 2018/10/05 + * Version: @(#)win_cdrom.c 1.0.11 2018/10/17 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -46,46 +46,20 @@ #include #include #include +#include #include +#define HAVE_STDARG_H +#define dbglog cdrom_host_log #include "../emu.h" #include "../config.h" #include "../ui/ui.h" #include "../plat.h" -#include "../devices/scsi/scsi_device.h" #include "../devices/cdrom/cdrom.h" +#include "../devices/scsi/scsi_device.h" +#include "../devices/scsi/scsi_cdrom.h" #include "win.h" -uint8_t host_cdrom_drive_available_num = 0; -uint8_t host_cdrom_drive_available[26]; - - -void -cdrom_init_host_drives(void) -{ - WCHAR temp[16]; - int i = 0; - - host_cdrom_drive_available_num = 0; - for (i = 'A'; i <= 'Z'; i++) { - swprintf(temp, sizeof_w(temp), L"%c:\\", i); - - if (GetDriveType(temp) == DRIVE_CDROM) { - host_cdrom_drive_available[i - 'A'] = 1; - - host_cdrom_drive_available_num++; - } else - host_cdrom_drive_available[i - 'A'] = 0; - } -} - - -#ifdef USE_CDROM_IOCTL - - -#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) - - enum { CD_STOPPED = 0, CD_PLAYING, @@ -94,1318 +68,1534 @@ enum { typedef struct { - HANDLE hIOCTL; - CDROM_TOC toc; - int is_playing; -} cdrom_ioctl_windows_t; + HANDLE hIOCTL; + + int is_playing; + int disc_changed; + int capacity_read; + int requested_blocks, + actual_requested_blocks; + int last_subchannel_pos; + int last_track_nr; + uint32_t last_track_pos; + uint32_t sector_pos; + + CDROM_TOC toc; + + uint8_t sub_q_data_format[16]; + uint8_t sub_q_channel_data[256]; + uint8_t sense[256]; + uint8_t rcbuf[16]; + wchar_t path[128]; +} cdrom_host_t; + +#define cdrom_sense_error hdev->sense[0] +#define cdrom_sense_key hdev->sense[2] +#define cdrom_asc hdev->sense[12] +#define cdrom_ascq hdev->sense[13] -cdrom_ioctl_windows_t cdrom_ioctl_windows[CDROM_NUM]; - -#ifdef ENABLE_CDROM_IOCTL_LOG -int cdrom_ioctl_do_log = ENABLE_CDROM_IOCTL_LOG; +#ifdef ENABLE_CDROM_HOST_LOG +int cdrom_host_do_log = ENABLE_CDROM_HOST_LOG; #endif -static CDROM ioctl_cdrom; - - -static void -cdrom_ioctl_log(const char *format, ...) +void +cdrom_host_log(int level, const char *fmt, ...) { -#ifdef ENABLE_CDROM_IOCTL_LOG +#ifdef ENABLE_CDROM_HOST_LOG va_list ap; - if (cdrom_ioctl_do_log) { - va_start(ap, format); - pclog_ex(format, ap); + if (cdrom_host_do_log >= level) { + va_start(ap, fmt); + pclog_ex(fmt, ap); va_end(ap); } #endif } -static int ioctl_hopen(uint8_t id); -void ioctl_audio_callback(uint8_t id, int16_t *output, int len) +#ifdef USE_HOST_CDROM +uint8_t cdrom_host_drive_available_num = 0; +uint8_t cdrom_host_drive_available[26]; + + +#ifdef _DEBUG +static void +toc_dump(CDROM_TOC *toc, int start) { - cdrom_t *dev = cdrom[id]; - RAW_READ_INFO in; - DWORD count; + uint32_t addr, lba; + int c; - if (!cdrom_drives[id].sound_on || (dev->cd_state != CD_PLAYING)) - { - if (dev->cd_state == CD_PLAYING) - { - dev->seek_pos += (len >> 11); - cdrom_ioctl_log("ioctl_audio_callback(): playing but mute\n"); - } else - cdrom_ioctl_log("ioctl_audio_callback(): not playing\n"); - cdrom_ioctl_windows[id].is_playing = 0; - memset(output, 0, len * 2); - return; - } - cdrom_ioctl_log("ioctl_audio_callback(): dev->cd_buflen = %i, len = %i\n", dev->cd_buflen, len); - while (dev->cd_buflen < len) - { - if (dev->seek_pos < dev->cd_end) - { - in.DiskOffset.LowPart = dev->seek_pos * 2048; - in.DiskOffset.HighPart = 0; - in.SectorCount = 1; - in.TrackMode = CDDA; - if (!DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(in), &(dev->cd_buffer[dev->cd_buflen]), 2352, &count, NULL)) - { - memset(&(dev->cd_buffer[dev->cd_buflen]), 0, (BUF_SIZE - dev->cd_buflen) * 2); - cdrom_ioctl_windows[id].is_playing = 0; - ioctl_close(id); - dev->cd_state = CD_STOPPED; - dev->cd_buflen = len; - cdrom_ioctl_log("ioctl_audio_callback(): read sector error, stopped\n"); - } - else - { - dev->seek_pos++; - dev->cd_buflen += (2352 / 2); - cdrom_ioctl_log("ioctl_audio_callback(): dev->seek_pos = %i\n", dev->seek_pos); - } - } - else - { - memset(&(dev->cd_buffer[dev->cd_buflen]), 0, (BUF_SIZE - dev->cd_buflen) * 2); - cdrom_ioctl_windows[id].is_playing = 0; - ioctl_close(id); - dev->cd_state = CD_STOPPED; - dev->cd_buflen = len; - cdrom_ioctl_log("ioctl_audio_callback(): reached the end\n"); - } - } - memcpy(output, dev->cd_buffer, len * 2); - memcpy(&dev->cd_buffer[0], &(dev->cd_buffer[len]), (BUF_SIZE - len) * 2); - dev->cd_buflen -= len; + DEBUG("IOCTL TOC:\n"); + + for (c = start; c <= toc->LastTrack; c++) { + addr = MSFtoLBA(toc->TrackData[c].Address[1], + toc->TrackData[c].Address[2], + toc->TrackData[c].Address[3]); + + lba = MSFtoLBA(toc->TrackData[c].Address[1], + toc->TrackData[c].Address[2], + toc->TrackData[c].Address[3]) - 150; + + DEBUG(" %02X %02x msf=%08lx lba=%08i\n", + toc->TrackData[c].TrackNumber, toc->TrackData[c].Control, addr, lba); + } + DEBUG("\n"); +} +#endif + + +/* Read the TOC from the current media in the drive. */ +static int +get_toc(cdrom_t *dev, CDROM_TOC *toc) +{ + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + DWORD size; + int ret; + + DEBUG("IOCTL get_toc(%c)\n", dev->host_drive); + + ret = DeviceIoControl(hdev->hIOCTL, IOCTL_CDROM_READ_TOC, + NULL, 0, toc, sizeof(CDROM_TOC), &size, NULL); + if (! ret) return(0); + + DEBUG(">> current toc:\n"); +#ifdef _DEBUG + toc_dump(toc, 0); +#endif + + return(1); } -void ioctl_audio_stop(uint8_t id) -{ - cdrom_t *dev = cdrom[id]; - cdrom_ioctl_windows[id].is_playing = 0; - ioctl_close(id); - dev->cd_state = CD_STOPPED; +/* Compare two copies of the TOC. */ +static int +cmp_toc(CDROM_TOC *a, CDROM_TOC *b) +{ + if ((a->TrackData[a->LastTrack].Address[1] == + b->TrackData[b->LastTrack].Address[1]) && + (a->TrackData[a->LastTrack].Address[2] == + b->TrackData[b->LastTrack].Address[2]) && + (a->TrackData[a->LastTrack].Address[3] == + b->TrackData[b->LastTrack].Address[3])) return(1); + + return(0); } -static int get_track_nr(uint8_t id, uint32_t pos) -{ - cdrom_t *dev = cdrom[id]; - int c; - int track = 0; - if (dev->disc_changed) - { +/* Get track number for specified position. */ +static int +get_track_nr(cdrom_t *dev, uint32_t pos) +{ + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + uint32_t track_address; + int c, track = 0; + + DEBUG("IOCTL: get_track_nr(%i): ", pos); + + if (hdev->disc_changed) { + DEBUG("disc changed\n"); + return 0; + } + + if (hdev->last_track_pos == pos) { + DEBUG("hdev->last_track_pos == pos\n"); + return hdev->last_track_nr; + } + + for (c = 0; c < hdev->toc.LastTrack; c++) { + track_address = MSFtoLBA(hdev->toc.TrackData[c].Address[1], + hdev->toc.TrackData[c].Address[2], + hdev->toc.TrackData[c].Address[3]) - 150; + + if (track_address <= pos) { + DEBUG("track = %i, ", c); + track = c; + } + } + + hdev->last_track_pos = pos; + hdev->last_track_nr = track; + + DEBUG("return %i\n", track); + + return track; +} + + +/* Get MSF for start of specified track. */ +static uint32_t +get_track_msf(cdrom_t *dev, int track) +{ + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + uint32_t ret = 0xffffffff; + int c; + + DEBUG("IOCTL: get_track_msf(%i): ", track); + + if (hdev->disc_changed) { + DEBUG("disc changed\n"); + return 0; + } + + for (c = hdev->toc.FirstTrack; c < hdev->toc.LastTrack; c++) { + if (c == track) { + ret = hdev->toc.TrackData[c].Address[3] + + (hdev->toc.TrackData[c].Address[2] << 8) + + (hdev->toc.TrackData[c].Address[1] << 16); + } + } + + DEBUG("return %08lx\n", ret); + + return ret; +} + + +/* API: start playing audio at specified position. */ +static uint8_t +audio_play(cdrom_t *dev, uint32_t pos, uint32_t len, int is_msf) +{ + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + uint32_t start_msf = 0, end_msf = 0; + int m = 0, s = 0, f = 0; + + if (! dev->host_drive) + return 0; + + DEBUG("IOCTL audio_play(%08lx) len=%08lx msf=%i\n", pos, len, is_msf); + + if (is_msf == 2) { + start_msf = get_track_msf(dev, pos); + end_msf = get_track_msf(dev, len); + + if ((start_msf == 0xffffffff) || (end_msf == 0xffffffff)) return 0; - cdrom_ioctl_log("get_track_nr(): disc changed\n"); - } - if (cdrom_ioctl[id].last_track_pos == pos) - { - cdrom_ioctl_log("get_track_nr(): cdrom_ioctl[id].last_track_pos == pos\n"); - return cdrom_ioctl[id].last_track_nr; - } + m = (start_msf >> 16) & 0xff; + s = (start_msf >> 8) & 0xff; + f = start_msf & 0xff; + pos = MSFtoLBA(m, s, f) - 150; + m = (end_msf >> 16) & 0xff; + s = (end_msf >> 8) & 0xff; + f = end_msf & 0xff; + len = MSFtoLBA(m, s, f) - 150; + } else if (is_msf == 1) { + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; - /* for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) */ - for (c = 0; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) - { - uint32_t track_address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1], - cdrom_ioctl_windows[id].toc.TrackData[c].Address[2], - cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]) - 150; - - if (track_address <= pos) - { - cdrom_ioctl_log("get_track_nr(): track = %i\n", c); - track = c; - } - } - cdrom_ioctl[id].last_track_pos = pos; - cdrom_ioctl[id].last_track_nr = track; - - cdrom_ioctl_log("get_track_nr(): return %i\n", track); - return track; -} - -static uint32_t get_track_msf(uint8_t id, uint32_t track_no) -{ - cdrom_t *dev = cdrom[id]; - int c; - - if (dev->disc_changed) - { - return 0; - } - - for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) - { - if (c == track_no) - { - return cdrom_ioctl_windows[id].toc.TrackData[c].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[2] << 8) + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[1] << 16); - } - } - return 0xffffffff; -} - -static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) -{ - cdrom_t *dev = cdrom[id]; - int m = 0, s = 0, f = 0; - uint32_t start_msf = 0, end_msf = 0; - if (!cdrom_drives[id].host_drive) - { - return; - } - cdrom_ioctl_log("Play audio - %08X %08X %i\n", pos, len, ismsf); - if (ismsf == 2) - { - start_msf = get_track_msf(id, pos); - end_msf = get_track_msf(id, len); - if (start_msf == 0xffffffff) - { - return; - } - if (end_msf == 0xffffffff) - { - return; - } - m = (start_msf >> 16) & 0xff; - s = (start_msf >> 8) & 0xff; - f = start_msf & 0xff; + if (pos == 0xffffff) { + DEBUG("Playing from current position (MSF)\n"); + pos = dev->seek_pos; + } else { pos = MSFtoLBA(m, s, f) - 150; - m = (end_msf >> 16) & 0xff; - s = (end_msf >> 8) & 0xff; - f = end_msf & 0xff; - len = MSFtoLBA(m, s, f) - 150; } - else if (ismsf == 1) - { - m = (pos >> 16) & 0xff; - s = (pos >> 8) & 0xff; - f = pos & 0xff; - if (pos == 0xffffff) - { - cdrom_ioctl_log("Playing from current position (MSF)\n"); - pos = dev->seek_pos; - } - else - { - pos = MSFtoLBA(m, s, f) - 150; - } + m = (len >> 16) & 0xff; + s = (len >> 8) & 0xff; + f = len & 0xff; + len = MSFtoLBA(m, s, f) - 150; + } else if (is_msf == 0) { + if (pos == 0xffffffff) { + DEBUG("Playing from current position\n"); + pos = dev->seek_pos; + } + len += pos; + } - m = (len >> 16) & 0xff; - s = (len >> 8) & 0xff; - f = len & 0xff; - len = MSFtoLBA(m, s, f) - 150; - } - else if (ismsf == 0) - { - if (pos == 0xffffffff) - { - cdrom_ioctl_log("Playing from current position\n"); - pos = dev->seek_pos; - } - len += pos; - } - dev->seek_pos = pos; - dev->cd_end = len; + dev->seek_pos = pos; + dev->cd_end = len; - if (!cdrom_ioctl_windows[id].is_playing) - { - ioctl_hopen(id); - cdrom_ioctl_windows[id].is_playing = 1; - } + if (! hdev->is_playing) + hdev->is_playing = 1; + + dev->cd_state = CD_PLAYING; + + return 1; +} + + +/* API: stop playing audio. */ +static void +audio_stop(cdrom_t *dev) +{ + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + + DEBUG("IOCTL: audio_stop(%i)\n", hdev->is_playing); + + hdev->is_playing = 0; + + dev->cd_state = CD_STOPPED; +} + + +/* API: pause playing audio. */ +static void +audio_pause(cdrom_t *dev) +{ + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + + if (! dev->host_drive) + return; + + DEBUG("IOCTL: audio_pause(%i) state=%d\n", + hdev->is_playing, dev->cd_state); + + if (dev->cd_state == CD_PLAYING) + dev->cd_state = CD_PAUSED; +} + + +/* API: resume playing audio. */ +static void +audio_resume(cdrom_t *dev) +{ + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + + if (! dev->host_drive) + return; + + DEBUG("IOCTL: audio_resume(%i) state=%d\n", + hdev->is_playing, dev->cd_state); + + if (dev->cd_state == CD_PAUSED) dev->cd_state = CD_PLAYING; } -static void ioctl_pause(uint8_t id) + +/* API: callback from sound module. */ +static int +audio_callback(cdrom_t *dev, int16_t *bufp, int len) { - cdrom_t *dev = cdrom[id]; + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + RAW_READ_INFO in; + DWORD size; - if (!cdrom_drives[id].host_drive) - { - return; - } - if (dev->cd_state == CD_PLAYING) - { - dev->cd_state = CD_PAUSED; - } -} + DBGLOG(1, "IOCTL: audio_callback(%i) state=%i: ", + dev->sound_on, dev->cd_state); -static void ioctl_resume(uint8_t id) -{ - cdrom_t *dev = cdrom[id]; + if (!dev->sound_on || (dev->cd_state != CD_PLAYING)) { + if (dev->cd_state == CD_PLAYING) { + dev->seek_pos += (len >> 11); + DBGLOG(1, "playing but mute\n"); + } else { + DBGLOG(1, "not playing\n"); + } + hdev->is_playing = 0; - if (!cdrom_drives[id].host_drive) - { - return; - } - if (dev->cd_state == CD_PAUSED) - { - dev->cd_state = CD_PLAYING; - } -} + /* Create some silent data. */ + memset(bufp, 0, len * 2); -static void ioctl_stop(uint8_t id) -{ - cdrom_t *dev = cdrom[id]; + return 0; + } - if (!cdrom_drives[id].host_drive) - { - return; - } - if (cdrom_ioctl_windows[id].is_playing) - { - cdrom_ioctl_windows[id].is_playing = 0; - ioctl_close(id); - } - dev->cd_state = CD_STOPPED; -} + DBGLOG(1, "dev->cd_buflen = %i, len = %i, ", dev->cd_buflen, len); -static int ioctl_ready(uint8_t id) -{ - cdrom_t *dev = cdrom[id]; - unsigned long size; - int temp; - CDROM_TOC ltoc; + while (dev->cd_buflen < len) { + if (dev->seek_pos < dev->cd_end) { + in.DiskOffset.LowPart = dev->seek_pos * 2048; + in.DiskOffset.HighPart = 0; + in.SectorCount = 1; + in.TrackMode = CDDA; - if (!cdrom_drives[id].host_drive) - { - return 0; - } - if (cdrom_ioctl_windows[id].hIOCTL == NULL) - { - ioctl_hopen(id); - temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); - ioctl_close(id); - } - else - { - temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); - } - if (!temp) - { - return 0; - } - if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[1]) || - (ltoc.TrackData[ltoc.LastTrack].Address[2] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[2]) || - (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3]) || - dev->disc_changed || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) - { - dev->cd_state = CD_STOPPED; - if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) - { - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - } - return 1; - } - return 1; -} + if (! DeviceIoControl(hdev->hIOCTL, IOCTL_CDROM_RAW_READ, + &in, sizeof(in), + &dev->cd_buffer[dev->cd_buflen], 2352, + &size, NULL)) { -static int ioctl_get_last_block(uint8_t id, unsigned char starttrack, int msf, int maxlen, int single) -{ - cdrom_t *dev = cdrom[id]; - unsigned long size; - int c, d = 0; - CDROM_TOC lbtoc; - uint32_t lb = 0; - if (!cdrom_drives[id].host_drive) - { - return 0; - } - dev->cd_state = CD_STOPPED; - ioctl_hopen(id); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &lbtoc, sizeof(lbtoc), &size, NULL); - ioctl_close(id); - dev->disc_changed=0; - for (c=d; c <= lbtoc.LastTrack; c++) - { - uint32_t address; - address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1], cdrom_ioctl_windows[id].toc.TrackData[c].Address[2], cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]); - if (address > lb) - { - lb = address; - } - } - return lb; -} + memset(&dev->cd_buffer[dev->cd_buflen], 0, + (BUF_SIZE - dev->cd_buflen) * 2); + hdev->is_playing = 0; -static void ioctl_read_capacity(uint8_t id, uint8_t *b); - -static int ioctl_medium_changed(uint8_t id) -{ - cdrom_t *dev = cdrom[id]; - unsigned long size; - int temp; - CDROM_TOC ltoc; - if (!cdrom_drives[id].host_drive) - { - return 0; /* This will be handled by the not ready handler instead. */ - } - ioctl_hopen(id); - temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc,sizeof(ltoc), &size, NULL); - ioctl_close(id); - if (!temp) - { - return 0; /* Drive empty, a not ready handler matter, not disc change. */ - } - if (dev->disc_changed || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) - { - dev->cd_state = CD_STOPPED; - cdrom_ioctl_windows[id].toc = ltoc; - dev->disc_changed = 0; - if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) - { - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - } - ioctl_hopen(id); - cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ - ioctl_read_capacity(id, NULL); - ioctl_close(id); - dev->cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); - return 1; - } - else - { - if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[1]) || - (ltoc.TrackData[ltoc.LastTrack].Address[2] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[2]) || - (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3])) - { dev->cd_state = CD_STOPPED; - cdrom_ioctl_log("Setting TOC...\n"); - cdrom_ioctl_windows[id].toc = ltoc; - ioctl_hopen(id); - cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ - ioctl_read_capacity(id, NULL); - ioctl_close(id); - dev->cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); - return 1; /* TOC mismatches. */ + dev->cd_buflen = len; + DBGLOG(1, "read sector error, stopped\n"); + return 0; } + + dev->seek_pos++; + dev->cd_buflen += (2352 / 2); + DBGLOG(1, "dev->seek_pos = %i\n", dev->seek_pos); + } else { + memset(&dev->cd_buffer[dev->cd_buflen], 0, + (BUF_SIZE - dev->cd_buflen) * 2); + + dev->cd_state = CD_STOPPED; + dev->cd_buflen = len; + + hdev->is_playing = 0; + + DBGLOG(1, "reached the end\n"); + return 0; } - return 0; /* None of the above, return 0. */ + } + + /* Copy more audio data into the sound buffer. */ + memcpy(bufp, dev->cd_buffer, len * 2); + + /* Move the audio buffer around. */ + //FIXME: should be re-done to avoid moving!! --FvK + memcpy(&dev->cd_buffer[0], &dev->cd_buffer[len], (BUF_SIZE - len) * 2); + dev->cd_buflen -= len; + + return 1; } -static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) + +/* API: stop the CD-ROM device. */ +static void +ioctl_stop(cdrom_t *dev) { - cdrom_t *dev = cdrom[id]; - CDROM_SUB_Q_DATA_FORMAT insub; - SUB_Q_CHANNEL_DATA sub; - unsigned long size; - int pos = 0, track; - uint32_t cdpos, track_address, dat; + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; - if (!cdrom_drives[id].host_drive) return 0; + if (! dev->host_drive) + return; - cdpos = dev->seek_pos; + if (hdev->is_playing) + hdev->is_playing = 0; - if (dev->last_subchannel_pos == cdpos) - { - memcpy(&insub, dev->sub_q_data_format, sizeof(insub)); - memcpy(&sub, dev->sub_q_channel_data, sizeof(sub)); - } - else - { - insub.Format = IOCTL_CDROM_CURRENT_POSITION; - ioctl_hopen(id); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL,&insub,sizeof(insub),&sub,sizeof(sub),&size,NULL); - ioctl_close(id); - memset(dev->sub_q_data_format, 0, 16); - memcpy(dev->sub_q_data_format, &insub, sizeof(insub)); - memset(dev->sub_q_channel_data, 0, 256); - memcpy(dev->sub_q_channel_data, &sub, sizeof(sub)); - dev->last_subchannel_pos = cdpos; - } + dev->cd_state = CD_STOPPED; +} - if (dev->cd_state == CD_PLAYING || dev->cd_state == CD_PAUSED) - { - track = get_track_nr(id, cdpos); - track_address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[track].Address[1], - cdrom_ioctl_windows[id].toc.TrackData[track].Address[2], - cdrom_ioctl_windows[id].toc.TrackData[track].Address[3]) - 150; - cdrom_ioctl_log("ioctl_getcurrentsubchannel(): cdpos = %i, track = %i, track_address = %i\n", cdpos, track, track_address); - - b[pos++] = sub.CurrentPosition.Control; - b[pos++] = track + 1; - b[pos++] = sub.CurrentPosition.IndexNumber; +/* API: check if device is ready for use. */ +static int +ioctl_ready(cdrom_t *dev) +{ + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + CDROM_TOC toc; - if (msf) - { - dat = cdpos + 150; - b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - dat = cdpos - track_address; - b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - } - else - { - b[pos++] = (cdpos >> 24) & 0xff; - b[pos++] = (cdpos >> 16) & 0xff; - b[pos++] = (cdpos >> 8) & 0xff; - b[pos++] = cdpos & 0xff; - cdpos -= track_address; - b[pos++] = (cdpos >> 24) & 0xff; - b[pos++] = (cdpos >> 16) & 0xff; - b[pos++] = (cdpos >> 8) & 0xff; - b[pos++] = cdpos & 0xff; - } + DEBUG("IOCTL ready(%c)\n", dev->host_drive); - if (dev->cd_state == CD_PLAYING) return 0x11; - return 0x12; + if (! dev->host_drive) + return 0; + + /* Grab the current TOC. */ + if (! get_toc(dev, &toc)) return 0; + + /* Same as the one we had? */ + if (!cmp_toc(&toc, &hdev->toc) || hdev->disc_changed || + (dev->host_drive != dev->prev_host_drive)) { + + /* Nope, mark as stopped and ready. */ + dev->cd_state = CD_STOPPED; + if (dev->host_drive != dev->prev_host_drive) + dev->prev_host_drive = dev->host_drive; + + return 1; + } + + return 1; +} + + +static int +get_last_block(cdrom_t *dev, uint8_t starttrack, int msf, int maxlen, int single) +{ + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + uint32_t address, lb; + CDROM_TOC toc; + int c; + + DEBUG("IOCTL get_last_block(%c)\n", dev->host_drive); + + if (! dev->host_drive) + return 0; + + dev->cd_state = CD_STOPPED; + + /* Grab the current TOC. */ + if (! get_toc(dev, &toc)) return 0; + + hdev->disc_changed = 0; + + lb = 0; + for (c = starttrack; c <= toc.LastTrack; c++) { + address = MSFtoLBA(toc.TrackData[c].Address[1], + toc.TrackData[c].Address[2], + toc.TrackData[c].Address[3]); + if (address > lb) + lb = address; + } + + return lb; +} + + +static void read_capacity(cdrom_t *dev, uint8_t *b); + + +/* API: check if medium has changed. */ +static int +medium_changed(cdrom_t *dev) +{ + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + CDROM_TOC toc; + + DEBUG("IOCTL medium_changed(%c)\n", dev->host_drive); + + if (! dev->host_drive) + return 0; + + /* Grab the current TOC. */ + if (! get_toc(dev, &toc)) return 0; + + if (hdev->disc_changed || (dev->host_drive != dev->prev_host_drive)) { + dev->cd_state = CD_STOPPED; + hdev->toc = toc; + hdev->disc_changed = 0; + + if (dev->host_drive != dev->prev_host_drive) + dev->prev_host_drive = dev->host_drive; + + /* + * With this, we read the READ CAPACITY command output + * from the host drive into our cache buffer. + */ + hdev->capacity_read = 0; + read_capacity(dev, NULL); + + dev->cdrom_capacity = get_last_block(dev, 0, 0, 4096, 0); + DEBUG("IOCTL medium_changed: capacity = %lu\n", dev->cdrom_capacity); + + return 1; + } + + if (! cmp_toc(&toc, &hdev->toc)) { + dev->cd_state = CD_STOPPED; + DEBUG("IOCTL: setting TOC...\n"); + hdev->toc = toc; + + /* + * With this, we read the READ CAPACITY command output + * from the host drive into our cache buffer. + */ + hdev->capacity_read = 0; + read_capacity(dev, NULL); + + dev->cdrom_capacity = get_last_block(dev, 0, 0, 4096, 0); +DEBUG("IOCTL medium_changed: capacity = %lu\n", dev->cdrom_capacity); + + return 1; + } + + return 0; +} + + +static uint8_t +get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf) +{ + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + CDROM_SUB_Q_DATA_FORMAT insub; + SUB_Q_CHANNEL_DATA sub; + uint32_t cdpos, track_address, dat; + uint32_t temp; + DWORD size; + int c, pos = 0, track; + + if (! dev->host_drive) return 0; + + cdpos = dev->seek_pos; + + if (hdev->last_subchannel_pos == cdpos) { + memcpy(&insub, hdev->sub_q_data_format, sizeof(insub)); + memcpy(&sub, hdev->sub_q_channel_data, sizeof(sub)); + } else { + insub.Format = IOCTL_CDROM_CURRENT_POSITION; + + if (! DeviceIoControl(hdev->hIOCTL, IOCTL_CDROM_READ_Q_CHANNEL, + &insub, sizeof(insub), &sub, sizeof(sub), + &size, NULL)) return 0; + + memset(hdev->sub_q_data_format, 0, 16); + memcpy(hdev->sub_q_data_format, &insub, sizeof(insub)); + memset(hdev->sub_q_channel_data, 0, 256); + memcpy(hdev->sub_q_channel_data, &sub, sizeof(sub)); + hdev->last_subchannel_pos = cdpos; + } + + if (dev->cd_state == CD_PLAYING || dev->cd_state == CD_PAUSED) { + track = get_track_nr(dev, cdpos); + + track_address = MSFtoLBA(hdev->toc.TrackData[track].Address[1], + hdev->toc.TrackData[track].Address[2], + hdev->toc.TrackData[track].Address[3]) - 150; + + DEBUG("get_current_subchannel(): cdpos = %i, track = %i, track_address = %i\n", cdpos, track, track_address); + + b[pos++] = sub.CurrentPosition.Control; + b[pos++] = track + 1; + b[pos++] = sub.CurrentPosition.IndexNumber; + + if (msf) { + dat = cdpos + 150; + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + dat = cdpos - track_address; + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + } else { + b[pos++] = (cdpos >> 24) & 0xff; + b[pos++] = (cdpos >> 16) & 0xff; + b[pos++] = (cdpos >> 8) & 0xff; + b[pos++] = cdpos & 0xff; + cdpos -= track_address; + b[pos++] = (cdpos >> 24) & 0xff; + b[pos++] = (cdpos >> 16) & 0xff; + b[pos++] = (cdpos >> 8) & 0xff; + b[pos++] = cdpos & 0xff; } - b[pos++]=sub.CurrentPosition.Control; - b[pos++]=sub.CurrentPosition.TrackNumber; - b[pos++]=sub.CurrentPosition.IndexNumber; + if (dev->cd_state == CD_PLAYING) return 0x11; - cdrom_ioctl_log("cdpos = %i, track_address = %i\n", MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1], sub.CurrentPosition.AbsoluteAddress[2], sub.CurrentPosition.AbsoluteAddress[3]), MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1], sub.CurrentPosition.TrackRelativeAddress[2], sub.CurrentPosition.TrackRelativeAddress[3])); + return 0x12; + } + + b[pos++] = sub.CurrentPosition.Control; + b[pos++] = sub.CurrentPosition.TrackNumber; + b[pos++] = sub.CurrentPosition.IndexNumber; + + DEBUG("cdpos = %i, track_address = %i\n", + MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1], + sub.CurrentPosition.AbsoluteAddress[2], + sub.CurrentPosition.AbsoluteAddress[3]), + MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1], + sub.CurrentPosition.TrackRelativeAddress[2], + sub.CurrentPosition.TrackRelativeAddress[3])); - if (msf) - { - int c; - for (c = 0; c < 4; c++) - { - b[pos++] = sub.CurrentPosition.AbsoluteAddress[c]; - } - for (c = 0; c < 4; c++) - { - b[pos++] = sub.CurrentPosition.TrackRelativeAddress[c]; - } - } - else - { - uint32_t temp = MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1], sub.CurrentPosition.AbsoluteAddress[2], sub.CurrentPosition.AbsoluteAddress[3]) - 150; - b[pos++] = temp >> 24; - b[pos++] = temp >> 16; - b[pos++] = temp >> 8; - b[pos++] = temp; - temp = MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1], sub.CurrentPosition.TrackRelativeAddress[2], sub.CurrentPosition.TrackRelativeAddress[3]) - 150; - b[pos++] = temp >> 24; - b[pos++] = temp >> 16; - b[pos++] = temp >> 8; - b[pos++] = temp; - } + if (msf) { + for (c = 0; c < 4; c++) + b[pos++] = sub.CurrentPosition.AbsoluteAddress[c]; - return 0x13; + for (c = 0; c < 4; c++) + b[pos++] = sub.CurrentPosition.TrackRelativeAddress[c]; + } else { + temp = MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1], + sub.CurrentPosition.AbsoluteAddress[2], + sub.CurrentPosition.AbsoluteAddress[3]) - 150; + b[pos++] = temp >> 24; + b[pos++] = temp >> 16; + b[pos++] = temp >> 8; + b[pos++] = temp; + + temp = MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1], + sub.CurrentPosition.TrackRelativeAddress[2], + sub.CurrentPosition.TrackRelativeAddress[3]) - 150; + b[pos++] = temp >> 24; + b[pos++] = temp >> 16; + b[pos++] = temp >> 8; + b[pos++] = temp; + } + + return 0x13; } -static void ioctl_eject(uint8_t id) + +static void +ioctl_eject(cdrom_t *dev) { - cdrom_t *dev = cdrom[id]; - unsigned long size; - if (!cdrom_drives[id].host_drive) - { - return; - } - if (cdrom_ioctl_windows[id].is_playing) - { - cdrom_ioctl_windows[id].is_playing = 0; - ioctl_stop(id); - } - dev->cd_state = CD_STOPPED; - ioctl_hopen(id); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_EJECT_MEDIA,NULL,0,NULL,0,&size,NULL); - ioctl_close(id); + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + DWORD size; + + if (! dev->host_drive) + return; + + if (hdev->is_playing) { + hdev->is_playing = 0; + ioctl_stop(dev); + } + + dev->cd_state = CD_STOPPED; + + (void)DeviceIoControl(hdev->hIOCTL, IOCTL_STORAGE_EJECT_MEDIA, + NULL, 0, NULL, 0, &size, NULL); } -static void ioctl_load(uint8_t id) + +static void +ioctl_load(cdrom_t *dev) { - cdrom_t *dev = cdrom[id]; - unsigned long size; - if (!cdrom_drives[id].host_drive) - { - return; - } - if (cdrom_ioctl_windows[id].is_playing) - { - cdrom_ioctl_windows[id].is_playing = 0; - ioctl_stop(id); - } - dev->cd_state = CD_STOPPED; - ioctl_hopen(id); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_LOAD_MEDIA,NULL,0,NULL,0,&size,NULL); - cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ - ioctl_read_capacity(id, NULL); - ioctl_close(id); - dev->cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + DWORD size; + + if (! dev->host_drive) + return; + + if (hdev->is_playing) { + hdev->is_playing = 0; + + ioctl_stop(dev); + } + + dev->cd_state = CD_STOPPED; + + (void)DeviceIoControl(hdev->hIOCTL, IOCTL_STORAGE_LOAD_MEDIA, + NULL, 0, NULL, 0, &size, NULL); + + /* + * With this, we read the READ CAPACITY command output + * from the host drive into our cache buffer. + */ + hdev->capacity_read = 0; + read_capacity(dev, NULL); + + dev->cdrom_capacity = get_last_block(dev, 0, 0, 4096, 0); } -static int ioctl_is_track_audio(uint8_t id, uint32_t pos, int ismsf) + +static int +is_track_audio(cdrom_t *dev, uint32_t pos, int ismsf) { - cdrom_t *dev = cdrom[id]; - int c; - int control = 0; + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + uint32_t track_address = 0; + int c, control = 0; - uint32_t track_address = 0; + if (hdev->disc_changed) + return 0; - if (dev->disc_changed) - { - return 0; + for (c = 0; hdev->toc.TrackData[c].TrackNumber != 0xaa; c++) { + if (ismsf) { + track_address = hdev->toc.TrackData[c].Address[3]; + track_address |= (hdev->toc.TrackData[c].Address[2] << 8); + track_address |= (hdev->toc.TrackData[c].Address[1] << 16); + } else { + track_address = MSFtoLBA(hdev->toc.TrackData[c].Address[1], + hdev->toc.TrackData[c].Address[2], + hdev->toc.TrackData[c].Address[3]); + track_address -= 150; } - for (c = 0; cdrom_ioctl_windows[id].toc.TrackData[c].TrackNumber != 0xaa; c++) - { - if (ismsf) { - track_address = cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]; - track_address |= (cdrom_ioctl_windows[id].toc.TrackData[c].Address[2] << 8); - track_address |= (cdrom_ioctl_windows[id].toc.TrackData[c].Address[1] << 16); - } else { - track_address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1],cdrom_ioctl_windows[id].toc.TrackData[c].Address[2],cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]); - track_address -= 150; - } + if (hdev->toc.TrackData[c].TrackNumber >= hdev->toc.FirstTrack && + hdev->toc.TrackData[c].TrackNumber <= hdev->toc.LastTrack && + track_address <= pos) + control = hdev->toc.TrackData[c].Control; + } - if (cdrom_ioctl_windows[id].toc.TrackData[c].TrackNumber >= cdrom_ioctl_windows[id].toc.FirstTrack && - cdrom_ioctl_windows[id].toc.TrackData[c].TrackNumber <= cdrom_ioctl_windows[id].toc.LastTrack && - track_address <= pos) - control = cdrom_ioctl_windows[id].toc.TrackData[c].Control; - } + if ((control & 0x0d) <= 1) + return 1; - if ((control & 0xd) <= 1) - return 1; - else - return 0; + return 0; } -/* 00, 08, 10, 18, 20, 28, 30, 38 */ -static const int flags_to_size[5][32] = { { 0, 0, 2352, 2352, 2352, 2352, 2352, 2352, /* 00-38 (CD-DA) */ - 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, /* 40-78 */ - 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, /* 80-B8 */ - 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352 }, /* C0-F8 */ - { 0, 0, 2048, 2336, 4, -296, 2052, 2344, /* 00-38 (Mode 1) */ - 8, -296, 2048, 2048, 12, -296, 2052, 2052, /* 40-78 */ - -296, -296, -296, -296, 16, -296, 2064, 2344, /* 80-B8 */ - -296, -296, 2048, 2048, 24, -296, 2064, 2352 }, /* C0-F8 */ - { 0, 0, 2336, 2336, 4, -296, 2340, 2340, /* 00-38 (Mode 2 non-XA) */ - 8, -296, 2336, 2336, 12, -296, 2340, 2340, /* 40-78 */ - -296, -296, -296, -296, 16, -296, 2352, 2340, /* 80-B8 */ - -296, -296, 2336, 2336, 24, -296, 2352, 2352 }, /* C0-F8 */ - { 0, 0, 2048, 2336, 4, -296, -296, -296, /* 00-38 (Mode 2 Form 1) */ - 8, -296, 2056, 2344, 12, -296, 2060, 2340, /* 40-78 */ - -296, -296, -296, -296, 16, -296, -296, -296, /* 80-B8 */ - -296, -296, -296, -296, 24, -296, 2072, 2352 }, /* C0-F8 */ - { 0, 0, 2328, 2328, 4, -296, -296, -296, /* 00-38 (Mode 2 Form 2) */ - 8, -296, 2336, 2336, 12, -296, 2340, 2340, /* 40-78 */ - -296, -296, -296, -296, 16, -296, -296, -296, /* 80-B8 */ - -296, -296, -296, -296, 24, -296, 2352, 2352 } /* C0-F8 */ - }; -static int ioctl_get_sector_data_type(uint8_t id, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, int ismsf); - -static void cdrom_illegal_mode(uint8_t id) -{ - cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - cdrom_asc = ASC_ILLEGAL_MODE_FOR_THIS_TRACK; - cdrom_ascq = 0; -} - -/* FIXME: allocate on heap! */ -struct sptd_with_sense -{ +struct sptd_with_sense { SCSI_PASS_THROUGH s; - ULONG Filler; + ULONG Filler; UCHAR sense[32]; UCHAR data[65536]; -} sptd; +}; -static int ioctl_get_block_length(uint8_t id, const UCHAR *cdb, int number_of_blocks, int no_length_check) + +/* + * 00, 08, 10, 18, 20, 28, 30, 38 + */ +static const int flags_to_size[5][32] = { + { 0, 0, 2352, 2352, 2352, 2352, 2352, 2352, /* 00-38 (CD-DA) */ + 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, /* 40-78 */ + 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, /* 80-B8 */ + 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352 /* C0-F8 */ + }, + { 0, 0, 2048, 2336, 4, -296, 2052, 2344, /* 00-38 (Mode 1) */ + 8, -296, 2048, 2048, 12, -296, 2052, 2052, /* 40-78 */ + -296, -296, -296, -296, 16, -296, 2064, 2344, /* 80-B8 */ + -296, -296, 2048, 2048, 24, -296, 2064, 2352 /* C0-F8 */ + }, + { 0, 0, 2336, 2336, 4, -296, 2340, 2340, /* 00-38 (Mode 2 non-XA) */ + 8, -296, 2336, 2336, 12, -296, 2340, 2340, /* 40-78 */ + -296, -296, -296, -296, 16, -296, 2352, 2340, /* 80-B8 */ + -296, -296, 2336, 2336, 24, -296, 2352, 2352 /* C0-F8 */ + }, + { 0, 0, 2048, 2336, 4, -296, -296, -296, /* 00-38 (Mode 2 Form 1) */ + 8, -296, 2056, 2344, 12, -296, 2060, 2340, /* 40-78 */ + -296, -296, -296, -296, 16, -296, -296, -296, /* 80-B8 */ + -296, -296, -296, -296, 24, -296, 2072, 2352 /* C0-F8 */ + }, + { 0, 0, 2328, 2328, 4, -296, -296, -296, /* 00-38 (Mode 2 Form 2) */ + 8, -296, 2336, 2336, 12, -296, 2340, 2340, /* 40-78 */ + -296, -296, -296, -296, 16, -296, -296, -296, /* 80-B8 */ + -296, -296, -296, -296, 24, -296, 2352, 2352 /* C0-F8 */ + } +}; + + +static int get_sector_data_type(cdrom_t *, uint8_t, uint8_t, uint8_t, uint8_t, int); + + +static void +illegal_mode(cdrom_t *dev) { - cdrom_t *dev = cdrom[id]; - int sector_type = 0; - int temp_len = 0; + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; - if (no_length_check) - { - switch (cdb[0]) - { - case 0x25: /* READ CAPACITY */ - case 0x44: /* READ HEADER */ - return 8; - case 0x42: /* READ SUBCHANNEL */ - case 0x43: /* READ TOC */ - case 0x51: /* READ DISC INFORMATION */ - case 0x52: /* READ TRACK INFORMATION */ - case 0x5A: /* MODE SENSE (10) */ - return (((uint32_t) cdb[7]) << 8) | ((uint32_t) cdb[8]); - case 0xAD: /* READ DVD STRUCTURE */ - return (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - default: - return 65534; - } - } + cdrom_sense_key = SENSE_ILLEGAL_REQUEST; + cdrom_asc = ASC_ILLEGAL_MODE_FOR_THIS_TRACK; + cdrom_ascq = 0; +} - switch (cdb[0]) - { + +static int +get_block_length(cdrom_t *dev, const UCHAR *cdb, int nblocks, int no_len_check) +{ + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + int sector_type = 0; + int temp_len = 0; + + if (no_len_check) { + switch (cdb[0]) { case 0x25: /* READ CAPACITY */ case 0x44: /* READ HEADER */ return 8; + case 0x42: /* READ SUBCHANNEL */ case 0x43: /* READ TOC */ case 0x51: /* READ DISC INFORMATION */ case 0x52: /* READ TRACK INFORMATION */ case 0x5A: /* MODE SENSE (10) */ - return (((uint32_t) cdb[7]) << 8) | ((uint32_t) cdb[8]); + return (((uint32_t)cdb[7]) << 8) | ((uint32_t)cdb[8]); + case 0xAD: /* READ DVD STRUCTURE */ - return (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); - case 0x08: - case 0x28: - case 0xa8: - /* READ (6), READ (10), READ (12) */ - return 2048 * number_of_blocks; - - case 0xb9: - sector_type = (cdb[1] >> 2) & 7; - if (sector_type == 0) - { - sector_type = ioctl_get_sector_data_type(id, 0, cdb[3], cdb[4], cdb[5], 1); - if (sector_type == 0) - { - cdrom_illegal_mode(id); - return -1; - } - } - goto common_handler; - case 0xbe: - /* READ CD MSF, READ CD */ - sector_type = (cdb[1] >> 2) & 7; - if (sector_type == 0) - { - sector_type = ioctl_get_sector_data_type(id, cdb[2], cdb[3], cdb[4], cdb[5], 0); - if (sector_type == 0) - { - cdrom_illegal_mode(id); - return -1; - } - } -common_handler: - temp_len = flags_to_size[sector_type - 1][cdb[9] >> 3]; - if ((cdb[9] & 6) == 2) - { - temp_len += 294; - } - else if ((cdb[9] & 6) == 4) - { - temp_len += 296; - } - if ((cdb[10] & 7) == 1) - { - temp_len += 96; - } - else if ((cdb[10] & 7) == 2) - { - temp_len += 16; - } - else if ((cdb[10] & 7) == 4) - { - temp_len += 96; - } - if (temp_len <= 0) - { - cdrom_illegal_mode(id); - return -1; - } - return temp_len * dev->requested_blocks; + return (((uint32_t)cdb[8]) << 8) | ((uint32_t)cdb[9]); default: - /* Other commands */ return 65534; - } + } -} + switch (cdb[0]) { + case 0x25: /* READ CAPACITY */ + case 0x44: /* READ HEADER */ + return 8; -static int SCSICommand(uint8_t id, const UCHAR *cdb, UCHAR *buf, uint32_t *len, int no_length_check) -{ - DWORD ioctl_bytes; - int ioctl_rv = 0; + case 0x42: /* READ SUBCHANNEL */ + case 0x43: /* READ TOC */ + case 0x51: /* READ DISC INFORMATION */ + case 0x52: /* READ TRACK INFORMATION */ + case 0x5A: /* MODE SENSE (10) */ + return (((uint32_t)cdb[7]) << 8) | ((uint32_t)cdb[8]); - SCSISense.SenseKey = 0; - SCSISense.Asc = 0; - SCSISense.Ascq = 0; + case 0xAD: /* READ DVD STRUCTURE */ + return (((uint32_t)cdb[8]) << 8) | ((uint32_t)cdb[9]); - *len = 0; - memset(&sptd, 0, sizeof(sptd)); - sptd.s.Length = sizeof(SCSI_PASS_THROUGH); - sptd.s.CdbLength = 12; - sptd.s.DataIn = SCSI_IOCTL_DATA_IN; - sptd.s.TimeOutValue = 80 * 60; - sptd.s.DataTransferLength = ioctl_get_block_length(id, cdb, cdrom_ioctl[id].actual_requested_blocks, no_length_check); - sptd.s.SenseInfoOffset = (uintptr_t)&sptd.sense - (uintptr_t)&sptd; - sptd.s.SenseInfoLength = 32; - sptd.s.DataBufferOffset = (uintptr_t)&sptd.data - (uintptr_t)&sptd; + case 0x08: + case 0x28: + case 0xa8: + /* READ (6), READ (10), READ (12) */ + return 2048 * nblocks; - memcpy(sptd.s.Cdb, cdb, 12); - ioctl_rv = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_SCSI_PASS_THROUGH, &sptd, sizeof(sptd), &sptd, sizeof(sptd), &ioctl_bytes, NULL); - - if (sptd.s.SenseInfoLength) - { - cdrom_sense_key = sptd.sense[2]; - cdrom_asc = sptd.sense[12]; - cdrom_ascq = sptd.sense[13]; - } - - cdrom_ioctl_log("Transferred length: %i (command: %02X)\n", sptd.s.DataTransferLength, cdb[0]); - cdrom_ioctl_log("Sense length: %i (%02X %02X %02X %02X %02X)\n", sptd.s.SenseInfoLength, sptd.sense[0], sptd.sense[1], sptd.sense[2], sptd.sense[12], sptd.sense[13]); - cdrom_ioctl_log("IOCTL bytes: %i; SCSI status: %i, status: %i, LastError: %08X\n", ioctl_bytes, sptd.s.ScsiStatus, ioctl_rv, GetLastError()); - cdrom_ioctl_log("DATA: %02X %02X %02X %02X %02X %02X\n", sptd.data[0], sptd.data[1], sptd.data[2], sptd.data[3], sptd.data[4], sptd.data[5]); - cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.data[6], sptd.data[7], sptd.data[8], sptd.data[9], sptd.data[10], sptd.data[11]); - cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.data[12], sptd.data[13], sptd.data[14], sptd.data[15], sptd.data[16], sptd.data[17]); - cdrom_ioctl_log("SENSE: %02X %02X %02X %02X %02X %02X\n", sptd.sense[0], sptd.sense[1], sptd.sense[2], sptd.sense[3], sptd.sense[4], sptd.sense[5]); - cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.sense[6], sptd.sense[7], sptd.sense[8], sptd.sense[9], sptd.sense[10], sptd.sense[11]); - cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.sense[12], sptd.sense[13], sptd.sense[14], sptd.sense[15], sptd.sense[16], sptd.sense[17]); - *len = sptd.s.DataTransferLength; - if (sptd.s.DataTransferLength != 0) - { - memcpy(buf, sptd.data, sptd.s.DataTransferLength); - } - - return ioctl_rv; -} - -static void ioctl_read_capacity(uint8_t id, uint8_t *b) -{ - cdrom_t *dev = cdrom[id]; - uint32_t len = 0; - - const UCHAR cdb[] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - UCHAR buf[16]; - - if (!cdrom_ioctl[id].capacity_read || (b == NULL)) - { - SCSICommand(id, cdb, buf, &len, 1); - - memcpy(dev->rcbuf, buf, len); - cdrom_ioctl[id].capacity_read = 1; - } - else - { - memcpy(b, dev->rcbuf, 16); - } -} - -static int ioctl_media_type_id(uint8_t id) -{ - uint8_t old_sense[3] = { 0, 0, 0 }; - - UCHAR msbuf[28]; - uint32_t len = 0; - int sense = 0; - - const UCHAR cdb[] = { 0x5A, 0x00, 0x2A, 0, 0, 0, 0, 0, 28, 0, 0, 0 }; - - old_sense[0] = cdrom_sense_key; - old_sense[1] = cdrom_asc; - old_sense[2] = cdrom_asc; - - ioctl_hopen(id); - - SCSICommand(id, cdb, msbuf, &len, 1); - - ioctl_close(id); - - sense = cdrom_sense_key; - cdrom_sense_key = old_sense[0]; - cdrom_asc = old_sense[1]; - cdrom_asc = old_sense[2]; - - if (sense == 0) - { - return msbuf[2]; - } - else - { - return 3; - } -} - -static uint32_t msf_to_lba32(int lba) -{ - int m = (lba >> 16) & 0xff; - int s = (lba >> 8) & 0xff; - int f = lba & 0xff; - return (m * 60 * 75) + (s * 75) + f; -} - -static int ioctl_get_type(uint8_t id, UCHAR *cdb, UCHAR *buf) -{ - int i = 0; - int ioctl_rv = 0; - - uint32_t len = 0; - - for (i = 2; i <= 5; i++) - { - cdb[1] = i << 2; - ioctl_rv = SCSICommand(id, cdb, buf, &len, 1); /* Bypass length check so we don't risk calling this again and getting stuck in an endless up. */ - if (ioctl_rv) - { - return i; - } - } - return 0; -} - -static int ioctl_sector_data_type(uint8_t id, int sector, int ismsf) -{ - int ioctl_rv = 0; - UCHAR cdb_lba[] = { 0xBE, 0, 0, 0, 0, 0, 0, 0, 1, 0x10, 0, 0 }; - UCHAR cdb_msf[] = { 0xB9, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0 }; - UCHAR buf[2352]; - - cdb_lba[2] = (sector >> 24); - cdb_lba[3] = ((sector >> 16) & 0xff); - cdb_lba[4] = ((sector >> 8) & 0xff); - cdb_lba[5] = (sector & 0xff); - - cdb_msf[3] = cdb_msf[6] = ((sector >> 16) & 0xff); - cdb_msf[4] = cdb_msf[7] = ((sector >> 8) & 0xff); - cdb_msf[5] = cdb_msf[8] = (sector & 0xff); - - ioctl_hopen(id); - - if (ioctl_is_track_audio(id, sector, ismsf)) - { - return 1; - } - - if (ismsf) - { - ioctl_rv = ioctl_get_type(id, cdb_msf, buf); - } - else - { - ioctl_rv = ioctl_get_type(id, cdb_lba, buf); - } - - if (ioctl_rv) - { - ioctl_close(id); - return ioctl_rv; - } - - if (ismsf) - { - sector = msf_to_lba32(sector); - if (sector < 150) - { - ioctl_close(id); - return 0; - } - sector -= 150; - ioctl_rv = ioctl_get_type(id, (UCHAR *) cdb_lba, buf); - } - - ioctl_close(id); - return ioctl_rv; -} - -static int ioctl_get_sector_data_type(uint8_t id, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, int ismsf) -{ - int sector = b3; - sector |= ((uint32_t) b2) << 8; - sector |= ((uint32_t) b1) << 16; - sector |= ((uint32_t) b0) << 24; - return ioctl_sector_data_type(id, sector, ismsf); -} - -static void ioctl_validate_toc(uint8_t id) -{ - cdrom_t *dev = cdrom[id]; - unsigned long size; - if (!cdrom_drives[id].host_drive) - { - return; - } - dev->cd_state = CD_STOPPED; - ioctl_hopen(id); - cdrom_ioctl_log("Validating TOC...\n"); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&cdrom_ioctl_windows[id].toc,sizeof(cdrom_ioctl_windows[id].toc),&size,NULL); - ioctl_close(id); - dev->disc_changed = 0; -} - -/* FIXME: malloc this as needed? */ -UCHAR buf[262144]; - -static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len) -{ - cdrom_t *dev = cdrom[id]; - const UCHAR cdb[12]; - - int ret = 0; - - int temp_block_length = 0; - int buffer_pos = 0; - - uint32_t temp_len = 0; - - int i = 0; - - if (in_cdb[0] == 0x43) - { - /* This is a read TOC, so we have to validate the TOC to make the rest of the emulator happy. */ - ioctl_validate_toc(id); - } - - ioctl_hopen(id); - - memcpy((void *) cdb, in_cdb, 12); - - temp_len = 0; - temp_block_length = ioctl_get_block_length(id, cdb, dev->requested_blocks, 0); - if (temp_block_length != -1) { - cdrom_ioctl[id].actual_requested_blocks = 1; - if ((cdb[0] == 0x08) || (cdb[0] == 0x28) || (cdb[0] == 0xA8) || (cdb[0] == 0xB9) || (cdb[0] == 0xBE)) { - buffer_pos = 0; - temp_len = 0; - - for (i = 0; i < dev->requested_blocks; i++) - { - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Transferring block...\n", id, cdrom_ioctl[id].actual_requested_blocks); - cdrom_update_cdb((uint8_t *) cdb, dev->sector_pos + i, 1); - ret = SCSICommand(id, cdb, b + buffer_pos, &temp_len, 0); - buffer_pos += temp_len; + case 0xb9: + sector_type = (cdb[1] >> 2) & 7; + if (sector_type == 0) { + sector_type = get_sector_data_type(dev, 0, cdb[3], cdb[4], cdb[5], 1); + if (sector_type == 0) { + illegal_mode(dev); + return -1; } - *len = buffer_pos; - } else { - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is smaller than 65534, transferring all at once...\n", id, temp_block_length); - ret = SCSICommand(id, cdb, b, len, 0); - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Single transfer done\n", id); } - } + goto common_handler; - cdrom_ioctl_log("IOCTL DATA: %02X %02X %02X %02X %02X %02X %02X %02X\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); - - ioctl_close(id); + case 0xbe: + /* READ CD MSF, READ CD */ + sector_type = (cdb[1] >> 2) & 7; + if (sector_type == 0) { + sector_type = get_sector_data_type(dev, cdb[2], cdb[3], cdb[4], cdb[5], 0); + if (sector_type == 0) { + illegal_mode(dev); + return -1; + } + } - cdrom_ioctl_log("IOCTL Returned value: %i\n", ret); - - return ret; -} +common_handler: + temp_len = flags_to_size[sector_type - 1][cdb[9] >> 3]; + if ((cdb[9] & 6) == 2) + temp_len += 294; + else if ((cdb[9] & 6) == 4) + temp_len += 296; + if ((cdb[10] & 7) == 1) + temp_len += 96; + else if ((cdb[10] & 7) == 2) + temp_len += 16; + else if ((cdb[10] & 7) == 4) + temp_len += 96; -static int ioctl_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) -{ - cdrom_t *dev = cdrom[id]; - int len=4; - DWORD size; - int c,d; - uint32_t temp; - uint32_t last_block; - if (!cdrom_drives[id].host_drive) - { - return 0; - } - dev->cd_state = CD_STOPPED; - ioctl_hopen(id); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&cdrom_ioctl_windows[id].toc,sizeof(cdrom_ioctl_windows[id].toc),&size,NULL); - ioctl_close(id); - dev->disc_changed = 0; - b[2]=cdrom_ioctl_windows[id].toc.FirstTrack; - b[3]=cdrom_ioctl_windows[id].toc.LastTrack; - d=0; - for (c=0;c<=cdrom_ioctl_windows[id].toc.LastTrack;c++) - { - if (cdrom_ioctl_windows[id].toc.TrackData[c].TrackNumber>=starttrack) - { - d=c; - break; - } - } - last_block = 0; - for (c=d;c<=cdrom_ioctl_windows[id].toc.LastTrack;c++) - { - uint32_t address; - if ((len+8)>maxlen) break; - b[len++]=0; /*Reserved*/ - b[len++]=(cdrom_ioctl_windows[id].toc.TrackData[c].Adr<<4)|cdrom_ioctl_windows[id].toc.TrackData[c].Control; - b[len++]=cdrom_ioctl_windows[id].toc.TrackData[c].TrackNumber; - b[len++]=0; /*Reserved*/ - address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1],cdrom_ioctl_windows[id].toc.TrackData[c].Address[2],cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]); - if (address > last_block) - last_block = address; + if (temp_len <= 0) { + illegal_mode(dev); + return -1; + } + return temp_len * hdev->requested_blocks; - if (msf) - { - b[len++]=cdrom_ioctl_windows[id].toc.TrackData[c].Address[0]; - b[len++]=cdrom_ioctl_windows[id].toc.TrackData[c].Address[1]; - b[len++]=cdrom_ioctl_windows[id].toc.TrackData[c].Address[2]; - b[len++]=cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]; - } - else - { - temp=MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1],cdrom_ioctl_windows[id].toc.TrackData[c].Address[2],cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]) - 150; - b[len++]=temp>>24; - b[len++]=temp>>16; - b[len++]=temp>>8; - b[len++]=temp; - } - if (single) break; - } - b[0] = (uint8_t)(((len-2) >> 8) & 0xff); - b[1] = (uint8_t)((len-2) & 0xff); - return len; -} + default: + /* Other commands */ + return 65534; -static int ioctl_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxlen) -{ - cdrom_t *dev = cdrom[id]; - int len=4; - int size; - uint32_t temp; - CDROM_READ_TOC_EX toc_ex; - CDROM_TOC_SESSION_DATA toc; - if (!cdrom_drives[id].host_drive) - { - return 0; - } - dev->cd_state = CD_STOPPED; - memset(&toc_ex,0,sizeof(toc_ex)); - memset(&toc,0,sizeof(toc)); - toc_ex.Format=CDROM_READ_TOC_EX_FORMAT_SESSION; - toc_ex.Msf=msf; - toc_ex.SessionTrack=0; - ioctl_hopen(id); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC_EX, &toc_ex,sizeof(toc_ex),&toc,sizeof(toc),(PDWORD)&size,NULL); - ioctl_close(id); - b[2]=toc.FirstCompleteSession; - b[3]=toc.LastCompleteSession; - b[len++]=0; /*Reserved*/ - b[len++]=(toc.TrackData[0].Adr<<4)|toc.TrackData[0].Control; - b[len++]=toc.TrackData[0].TrackNumber; - b[len++]=0; /*Reserved*/ - if (msf) - { - b[len++]=toc.TrackData[0].Address[0]; - b[len++]=toc.TrackData[0].Address[1]; - b[len++]=toc.TrackData[0].Address[2]; - b[len++]=toc.TrackData[0].Address[3]; - } - else - { - temp=MSFtoLBA(toc.TrackData[0].Address[1],toc.TrackData[0].Address[2],toc.TrackData[0].Address[3]) - 150; - b[len++]=temp>>24; - b[len++]=temp>>16; - b[len++]=temp>>8; - b[len++]=temp; - } - - return len; -} - -static int ioctl_readtoc_raw(uint8_t id, uint8_t *b, int maxlen) -{ - cdrom_t *dev = cdrom[id]; - int len=4; - int size; - int i; - CDROM_READ_TOC_EX toc_ex; - CDROM_TOC_FULL_TOC_DATA toc; - if (!cdrom_drives[id].host_drive) - { - return 0; - } - dev->cd_state = CD_STOPPED; - memset(&toc_ex,0,sizeof(toc_ex)); - memset(&toc,0,sizeof(toc)); - toc_ex.Format=CDROM_READ_TOC_EX_FORMAT_FULL_TOC; - toc_ex.Msf=1; - toc_ex.SessionTrack=0; - ioctl_hopen(id); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC_EX, &toc_ex,sizeof(toc_ex),&toc,sizeof(toc),(PDWORD)&size,NULL); - ioctl_close(id); - if (maxlen >= 3) b[2]=toc.FirstCompleteSession; - if (maxlen >= 4) b[3]=toc.LastCompleteSession; - - if (len >= maxlen) return len; - - size -= sizeof(CDROM_TOC_FULL_TOC_DATA); - size /= sizeof(toc.Descriptors[0]); - - for (i = 0; i <= size; i++) - { - b[len++]=toc.Descriptors[i].SessionNumber; - if (len == maxlen) return len; - b[len++]=(toc.Descriptors[i].Adr<<4)|toc.Descriptors[i].Control; - if (len == maxlen) return len; - b[len++]=0; - if (len == maxlen) return len; - b[len++]=toc.Descriptors[i].Reserved1; /*Reserved*/ - if (len == maxlen) return len; - b[len++]=toc.Descriptors[i].MsfExtra[0]; - if (len == maxlen) return len; - b[len++]=toc.Descriptors[i].MsfExtra[1]; - if (len == maxlen) return len; - b[len++]=toc.Descriptors[i].MsfExtra[2]; - if (len == maxlen) return len; - b[len++]=toc.Descriptors[i].Zero; - if (len == maxlen) return len; - b[len++]=toc.Descriptors[i].Msf[0]; - if (len == maxlen) return len; - b[len++]=toc.Descriptors[i].Msf[1]; - if (len == maxlen) return len; - b[len++]=toc.Descriptors[i].Msf[2]; - if (len == maxlen) return len; - } - - return len; -} - -static uint32_t ioctl_size(uint8_t id) -{ - uint8_t capacity_buffer[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - uint32_t capacity = 0; - - ioctl_read_capacity(id, capacity_buffer); - capacity = ((uint32_t) capacity_buffer[0]) << 24; - capacity |= ((uint32_t) capacity_buffer[1]) << 16; - capacity |= ((uint32_t) capacity_buffer[2]) << 8; - capacity |= (uint32_t) capacity_buffer[3]; - return capacity + 1; -} - -static int ioctl_status(uint8_t id) -{ - cdrom_t *dev = cdrom[id]; - - if (!(ioctl_ready(id)) && (cdrom_drives[id].host_drive <= 0)) - { - return CD_STATUS_EMPTY; - } - - switch(dev->cd_state) - { - case CD_PLAYING: - return CD_STATUS_PLAYING; - case CD_PAUSED: - return CD_STATUS_PAUSED; - case CD_STOPPED: - return CD_STATUS_STOPPED; - default: - return CD_STATUS_EMPTY; - } -} - - -void -ioctl_reset(uint8_t id) -{ - cdrom_t *dev = cdrom[id]; - CDROM_TOC ltoc; - unsigned long size; - - if (!cdrom_drives[id].host_drive) { - dev->disc_changed = 1; - return; } - - ioctl_hopen(id); - - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, - IOCTL_CDROM_READ_TOC, - NULL, 0, <oc, sizeof(ltoc), &size, NULL); - - ioctl_close(id); - - cdrom_ioctl_windows[id].toc = ltoc; - - dev->disc_changed = 0; } -int -ioctl_hopen(uint8_t id) +static int +SCSICommand(cdrom_t *dev, const UCHAR *cdb, UCHAR *buf, uint32_t *len, int no_length_check) { - if (cdrom_ioctl_windows[id].is_playing) return 0; + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + struct sptd_with_sense sptd; + DWORD size; + int ret = 0; - cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, 0, NULL); - return 0; -} +#if 0 + SCSISense.SenseKey = 0; + SCSISense.Asc = 0; + SCSISense.Ascq = 0; +#endif -#define rcs "Read capacity: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n" -#define drb dev->rcbuf + *len = 0; + memset(&sptd, 0, sizeof(sptd)); + sptd.s.Length = sizeof(SCSI_PASS_THROUGH); + sptd.s.CdbLength = 12; + sptd.s.DataIn = SCSI_IOCTL_DATA_IN; + sptd.s.TimeOutValue = 80 * 60; + sptd.s.DataTransferLength = get_block_length(dev, cdb, hdev->actual_requested_blocks, no_length_check); + sptd.s.SenseInfoOffset = (uintptr_t)&sptd.sense - (uintptr_t)&sptd; + sptd.s.SenseInfoLength = 32; + sptd.s.DataBufferOffset = (uintptr_t)&sptd.data - (uintptr_t)&sptd; + memcpy(sptd.s.Cdb, cdb, 12); + ret = DeviceIoControl(hdev->hIOCTL, IOCTL_SCSI_PASS_THROUGH, + &sptd, sizeof(sptd), + &sptd, sizeof(sptd), &size, NULL); -int -ioctl_open(cdrom_t *dev, char d) -{ - sprintf(cdrom_ioctl[id].ioctl_path,"\\\\.\\%c:",d); - pclog("IOCTL path: %s\n", cdrom_ioctl[id].ioctl_path); - dev->disc_changed = 1; - - cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - cdrom_drives[id].handler = &ioctl_cdrom; - dev->handler_inited = 1; - cdrom_ioctl_windows[id].is_playing = 0; - cdrom_ioctl[id].capacity_read=0; /* With these two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ - ioctl_read_capacity(id, NULL); - pclog(rcs, drb[0], drb[1], drb[2], drb[3], drb[4], drb[5], drb[6], drb[7], - drb[8], drb[9], drb[10], drb[11], drb[12], drb[13], drb[14], drb[15]); - CloseHandle(cdrom_ioctl_windows[id].hIOCTL); - - cdrom_ioctl_windows[id].hIOCTL = NULL; - - return 0; -} - - -void -ioctl_close(cdrom_t *dev) -{ - if (cdrom_ioctl_windows[id].is_playing) return; - - if (cdrom_ioctl_windows[id].hIOCTL) { - CloseHandle(cdrom_ioctl_windows[id].hIOCTL); - cdrom_ioctl_windows[id].hIOCTL = NULL; + if (sptd.s.SenseInfoLength) { + cdrom_sense_key = sptd.sense[2]; + cdrom_asc = sptd.sense[12]; + cdrom_ascq = sptd.sense[13]; } + + DEBUG("Transferred length: %i (command: %02X)\n", sptd.s.DataTransferLength, cdb[0]); + DEBUG("Sense length: %i (%02X %02X %02X %02X %02X)\n", sptd.s.SenseInfoLength, sptd.sense[0], sptd.sense[1], sptd.sense[2], sptd.sense[12], sptd.sense[13]); + DEBUG("IOCTL bytes: %i; SCSI status: %i, status: %i, LastError: %08X\n", size, sptd.s.ScsiStatus, ret, GetLastError()); + DEBUG("DATA: %02X %02X %02X %02X %02X %02X\n", sptd.data[0], + sptd.data[1], sptd.data[2], sptd.data[3], sptd.data[4], sptd.data[5]); + DEBUG(" %02X %02X %02X %02X %02X %02X\n", + sptd.data[6], sptd.data[7], sptd.data[8], sptd.data[9], + sptd.data[10], sptd.data[11]); + DEBUG(" %02X %02X %02X %02X %02X %02X\n", + sptd.data[12], sptd.data[13], sptd.data[14], sptd.data[15], + sptd.data[16], sptd.data[17]); + DEBUG("SENSE: %02X %02X %02X %02X %02X %02X\n", + sptd.sense[0], sptd.sense[1], sptd.sense[2], sptd.sense[3], + sptd.sense[4], sptd.sense[5]); + DEBUG(" %02X %02X %02X %02X %02X %02X\n", + sptd.sense[6], sptd.sense[7], sptd.sense[8], sptd.sense[9], + sptd.sense[10], sptd.sense[11]); + DEBUG(" %02X %02X %02X %02X %02X %02X\n", + sptd.sense[12], sptd.sense[13], sptd.sense[14], sptd.sense[15], + sptd.sense[16], sptd.sense[17]); + + *len = sptd.s.DataTransferLength; + if (sptd.s.DataTransferLength != 0) + memcpy(buf, sptd.data, sptd.s.DataTransferLength); + + return ret; } static void -ioctl_exit(cdrom_t *dev) +read_capacity(cdrom_t *dev, uint8_t *b) { - cdrom_ioctl_windows[id].is_playing = 0; + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + const UCHAR cdb[] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + UCHAR buf[16]; + uint32_t len = 0; - ioctl_stop(id); - dev->handler_inited = 0; - dev->disc_changed = 1; + if (! hdev->capacity_read || (b == NULL)) { + SCSICommand(dev, cdb, buf, &len, 1); + + memcpy(hdev->rcbuf, buf, len); + hdev->capacity_read = 1; + } else { + memcpy(b, hdev->rcbuf, 16); + } } -static cdrom_ops_t cdrom_ioctl_ops = { +static int +media_type_id(cdrom_t *dev) +{ + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + const UCHAR cdb[] = { 0x5A, 0x00, 0x2A, 0, 0, 0, 0, 0, 28, 0, 0, 0 }; + uint8_t old_sense[3] = { 0, 0, 0 }; + UCHAR msbuf[28]; + uint32_t len = 0; + int sense = 0; + + old_sense[0] = cdrom_sense_key; + old_sense[1] = cdrom_asc; + old_sense[2] = cdrom_asc; + + SCSICommand(dev, cdb, msbuf, &len, 1); + + sense = cdrom_sense_key; + cdrom_sense_key = old_sense[0]; + cdrom_asc = old_sense[1]; + cdrom_asc = old_sense[2]; + + if (sense == 0) + return msbuf[2]; + + return 3; +} + + +static uint32_t +msf_to_lba32(int lba) +{ + int m = (lba >> 16) & 0xff; + int s = (lba >> 8) & 0xff; + int f = lba & 0xff; + + return (m * 60 * 75) + (s * 75) + f; +} + + +static int +get_type(cdrom_t *dev, UCHAR *cdb, UCHAR *buf) +{ + uint32_t len = 0; + int i, ret = 0; + + for (i = 2; i <= 5; i++) { + cdb[1] = i << 2; + + /* + * Bypass length check so we don't risk calling + * this again and getting stuck in an endless loop. + */ + ret = SCSICommand(dev, cdb, buf, &len, 1); + if (ret) + return i; + } + + return 0; +} + + +static int +sector_data_type(cdrom_t *dev, int sector, int ismsf) +{ + UCHAR cdb_lba[] = { 0xBE, 0, 0, 0, 0, 0, 0, 0, 1, 0x10, 0, 0 }; + UCHAR cdb_msf[] = { 0xB9, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0 }; + UCHAR buf[2352]; + int ret = 0; + + cdb_lba[2] = (sector >> 24); + cdb_lba[3] = ((sector >> 16) & 0xff); + cdb_lba[4] = ((sector >> 8) & 0xff); + cdb_lba[5] = (sector & 0xff); + + cdb_msf[3] = cdb_msf[6] = ((sector >> 16) & 0xff); + cdb_msf[4] = cdb_msf[7] = ((sector >> 8) & 0xff); + cdb_msf[5] = cdb_msf[8] = (sector & 0xff); + + if (is_track_audio(dev, sector, ismsf)) + return 1; + + if (ismsf) + ret = get_type(dev, cdb_msf, buf); + else + ret = get_type(dev, cdb_lba, buf); + + if (ret) + return ret; + + if (ismsf) { + sector = msf_to_lba32(sector); + if (sector < 150) + return 0; + sector -= 150; + ret = get_type(dev, (UCHAR *)cdb_lba, buf); + } + + return ret; +} + + +static int +get_sector_data_type(cdrom_t *dev, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, int ismsf) +{ + int sector = b3; + + sector |= ((uint32_t) b2) << 8; + sector |= ((uint32_t) b1) << 16; + sector |= ((uint32_t) b0) << 24; + + return sector_data_type(dev, sector, ismsf); +} + + +static void +validate_toc(cdrom_t *dev) +{ + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + DWORD size; + + if (! dev->host_drive) + return; + + dev->cd_state = CD_STOPPED; + + DEBUG("Validating TOC...\n"); + (void)DeviceIoControl(hdev->hIOCTL, + IOCTL_CDROM_READ_TOC, + NULL, 0, + &hdev->toc, sizeof(hdev->toc), &size, NULL); + hdev->disc_changed = 0; +} + + +static int +pass_through(cdrom_t *dev, uint8_t *in_cdb, uint8_t *b, uint32_t *len) +{ + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + const UCHAR cdb[12]; + uint32_t temp_len = 0; + int temp_block_length = 0; + int ret = 0, buffer_pos = 0; + int i; + + if (in_cdb[0] == 0x43) { + /* + * This is a read TOC, so we have to validate + * the TOC to make the rest of the emulator happy. + */ + validate_toc(dev); + } + + memcpy((void *)cdb, in_cdb, 12); + + temp_len = 0; + temp_block_length = get_block_length(dev, cdb, hdev->requested_blocks, 0); + if (temp_block_length != -1) { + hdev->actual_requested_blocks = 1; + if ((cdb[0] == 0x08) || (cdb[0] == 0x28) || (cdb[0] == 0xA8) || + (cdb[0] == 0xB9) || (cdb[0] == 0xBE)) { + buffer_pos = 0; + temp_len = 0; + + for (i = 0; i < hdev->requested_blocks; i++) { + DEBUG("pass_through(): Transferring block...\n"); + scsi_cdrom_update_cdb((uint8_t *)cdb, + hdev->sector_pos + i, 1); + ret = SCSICommand(dev, cdb, b + buffer_pos, &temp_len, 0); + buffer_pos += temp_len; + } + + *len = buffer_pos; + } else { + DEBUG("pass_through(): Expected transfer length %i is smaller than 65534, transferring all at once...\n", temp_block_length); + ret = SCSICommand(dev, cdb, b, len, 0); + DEBUG("pass_through(): Single transfer done\n"); + } + } + + DEBUG("IOCTL DATA: %02X %02X %02X %02X %02X %02X %02X %02X\n", + b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); + + DEBUG("IOCTL Returned value: %i\n", ret); + + return ret; +} + + +static int +readsector_raw(cdrom_t *dev, uint8_t *buffer, int sector, int ismsf, + int cdrom_sector_type, int cdrom_sector_flags, int *len) +{ +// cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + + DEBUG("IOCTL read_raw(%i) msf=%i type=%i flags=%04x\n", + sector, ismsf, cdrom_sector_type, cdrom_sector_flags); + + return 0; +} + + +static int +read_toc(cdrom_t *dev, uint8_t *b, uint8_t starttrack, int msf, int maxlen, int single) +{ + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + uint32_t last_block; + uint32_t address; + uint32_t temp; + DWORD size; + int c, d, len = 4; + + DEBUG("IOCTL read_toc(%i) msf=%i maxlen=%i single=%i\n", + starttrack, msf, maxlen, single); + + if (! dev->host_drive) + return 0; + + dev->cd_state = CD_STOPPED; + + (void)DeviceIoControl(hdev->hIOCTL, IOCTL_CDROM_READ_TOC, + NULL, 0, &hdev->toc, sizeof(hdev->toc), &size, NULL); + + hdev->disc_changed = 0; + + b[2] = hdev->toc.FirstTrack; + b[3] = hdev->toc.LastTrack; + + d = 0; + for (c = 0; c <= hdev->toc.LastTrack; c++) { + if (hdev->toc.TrackData[c].TrackNumber >= starttrack) { + d = c; + break; + } + } + + last_block = 0; + + for (c = d; c<= hdev->toc.LastTrack; c++) { + if ((len + 8) > maxlen) break; + + b[len++] = 0; /*Reserved*/ + b[len++] = (hdev->toc.TrackData[c].Adr<<4)|hdev->toc.TrackData[c].Control; + b[len++] = hdev->toc.TrackData[c].TrackNumber; + b[len++] = 0; /*Reserved*/ + + address = MSFtoLBA(hdev->toc.TrackData[c].Address[1], + hdev->toc.TrackData[c].Address[2], + hdev->toc.TrackData[c].Address[3]); + + if (address > last_block) + last_block = address; + + if (msf) { + b[len++] = hdev->toc.TrackData[c].Address[0]; + b[len++] = hdev->toc.TrackData[c].Address[1]; + b[len++] = hdev->toc.TrackData[c].Address[2]; + b[len++] = hdev->toc.TrackData[c].Address[3]; + } else { + temp = MSFtoLBA(hdev->toc.TrackData[c].Address[1], + hdev->toc.TrackData[c].Address[2], + hdev->toc.TrackData[c].Address[3]) - 150; + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + + if (single) break; + } + + b[0] = (uint8_t) (((len-2) >> 8) & 0xff); + b[1] = (uint8_t) ((len-2) & 0xff); + + return len; +} + + +static int +read_toc_session(cdrom_t *dev, uint8_t *b, int msf, int maxlen) +{ + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + CDROM_TOC_SESSION_DATA toc; + CDROM_READ_TOC_EX toc_ex; + uint32_t temp; + DWORD size; + int len = 4; + + if (! dev->host_drive) + return 0; + + dev->cd_state = CD_STOPPED; + memset(&toc, 0, sizeof(toc)); + + memset(&toc_ex, 0, sizeof(toc_ex)); + toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_SESSION; + toc_ex.Msf = msf; + toc_ex.SessionTrack = 0; + + (void)DeviceIoControl(hdev->hIOCTL, IOCTL_CDROM_READ_TOC_EX, + &toc_ex, sizeof(toc_ex), + &toc, sizeof(toc), &size, NULL); + + b[2] = toc.FirstCompleteSession; + b[3] = toc.LastCompleteSession; + b[len++] = 0; /*Reserved*/ + b[len++] = (toc.TrackData[0].Adr << 4) | toc.TrackData[0].Control; + b[len++] = toc.TrackData[0].TrackNumber; + b[len++] = 0; /*Reserved*/ + if (msf) { + b[len++] = toc.TrackData[0].Address[0]; + b[len++] = toc.TrackData[0].Address[1]; + b[len++] = toc.TrackData[0].Address[2]; + b[len++] = toc.TrackData[0].Address[3]; + } else { + temp = MSFtoLBA(toc.TrackData[0].Address[1], + toc.TrackData[0].Address[2], + toc.TrackData[0].Address[3]) - 150; + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + + return len; +} + + +static int +read_toc_raw(cdrom_t *dev, uint8_t *b, int maxlen) +{ + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + CDROM_TOC_FULL_TOC_DATA toc; + CDROM_READ_TOC_EX toc_ex; + DWORD size; + int i, len = 4; + + if (! dev->host_drive) + return 0; + + dev->cd_state = CD_STOPPED; + memset(&toc, 0, sizeof(toc)); + + memset(&toc_ex, 0, sizeof(toc_ex)); + toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_FULL_TOC; + toc_ex.Msf = 1; + toc_ex.SessionTrack = 0; + + (void)DeviceIoControl(hdev->hIOCTL, IOCTL_CDROM_READ_TOC_EX, + &toc_ex, sizeof(toc_ex), + &toc, sizeof(toc), &size, NULL); + + if (maxlen >= 3) + b[2] = toc.FirstCompleteSession; + if (maxlen >= 4) + b[3] = toc.LastCompleteSession; + + if (len >= maxlen) + return len; + + size -= sizeof(CDROM_TOC_FULL_TOC_DATA); + size /= sizeof(toc.Descriptors[0]); + + for (i = 0; i <= (int)size; i++) { + b[len++] = toc.Descriptors[i].SessionNumber; + if (len == maxlen) + return len; + b[len++] = (toc.Descriptors[i].Adr<<4)|toc.Descriptors[i].Control; + if (len == maxlen) + return len; + b[len++] = 0; + if (len == maxlen) + return len; + b[len++] = toc.Descriptors[i].Reserved1; /*Reserved*/ + if (len == maxlen) + return len; + b[len++] = toc.Descriptors[i].MsfExtra[0]; + if (len == maxlen) + return len; + b[len++] = toc.Descriptors[i].MsfExtra[1]; + if (len == maxlen) + return len; + b[len++] = toc.Descriptors[i].MsfExtra[2]; + if (len == maxlen) + return len; + b[len++] = toc.Descriptors[i].Zero; + if (len == maxlen) + return len; + b[len++] = toc.Descriptors[i].Msf[0]; + if (len == maxlen) + return len; + b[len++] = toc.Descriptors[i].Msf[1]; + if (len == maxlen) + return len; + b[len++] = toc.Descriptors[i].Msf[2]; + if (len == maxlen) + return len; + } + + return len; +} + + +static uint32_t +ioctl_size(cdrom_t *dev) +{ + uint8_t buffer[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint32_t capacity = 0; + + read_capacity(dev, buffer); + + capacity = ((uint32_t)buffer[0]) << 24; + capacity |= ((uint32_t)buffer[1]) << 16; + capacity |= ((uint32_t)buffer[2]) << 8; + capacity |= (uint32_t)buffer[3]; + + return capacity + 1; +} + + +static int +ioctl_status(cdrom_t *dev) +{ + if (!(ioctl_ready(dev)) && (dev->host_drive <= 0)) + return CD_STATUS_EMPTY; + + switch(dev->cd_state) { + case CD_PLAYING: + return CD_STATUS_PLAYING; + + case CD_PAUSED: + return CD_STATUS_PAUSED; + + case CD_STOPPED: + return CD_STATUS_STOPPED; + + default: + break; + } + + return CD_STATUS_EMPTY; +} + + +static void +ioctl_close(cdrom_t *dev) +{ + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + + DEBUG("IOCTL close(%i) handle=%08lx\n", hdev->is_playing, hdev->hIOCTL); + + hdev->is_playing = 0; + + ioctl_stop(dev); + + hdev->disc_changed = 1; + + if (hdev->hIOCTL != NULL) + CloseHandle(hdev->hIOCTL); + + free(hdev); + + dev->local = NULL; + dev->reset = NULL; +} + + +static const cdrom_ops_t cdrom_host_ops = { ioctl_ready, - ioctl_medium_changed, - ioctl_media_type_id, - ioctl_audio_callback, - ioctl_audio_stop, - ioctl_readtoc, - ioctl_readtoc_session, - ioctl_readtoc_raw, - ioctl_getcurrentsubchannel, - ioctl_pass_through, - NULL, - ioctl_playaudio, - ioctl_load, - ioctl_eject, - ioctl_pause, - ioctl_resume, + medium_changed, + media_type_id, + ioctl_size, ioctl_status, - ioctl_is_track_audio, ioctl_stop, - ioctl_exit + ioctl_close, + + ioctl_eject, + ioctl_load, + + read_toc, + read_toc_session, + read_toc_raw, + + audio_play, + audio_stop, + audio_pause, + audio_resume, + audio_callback, + + get_current_subchannel, + readsector_raw }; + + +static void +ioctl_reset(cdrom_t *dev) +{ + cdrom_host_t *hdev = (cdrom_host_t *)dev->local; + CDROM_TOC toc; + DWORD size; + + DEBUG("IOCTL reset(%c) handle=%08lx\n", dev->host_drive, hdev->hIOCTL); + + if (! dev->host_drive) { + hdev->disc_changed = 1; + return; + } + + memset(&toc, 0x00, sizeof(toc)); + (void)DeviceIoControl(hdev->hIOCTL, IOCTL_CDROM_READ_TOC, + NULL, 0, &toc, sizeof(toc), &size, NULL); + hdev->toc = toc; + + toc_dump(&hdev->toc, 0); + + hdev->disc_changed = 0; +} + + +int +cdrom_host_open(cdrom_t *dev, char d) +{ + cdrom_host_t *hdev; + + /* Allocate our control block. */ + hdev = (cdrom_host_t *)mem_alloc(sizeof(cdrom_host_t)); + swprintf(hdev->path, sizeof_w(hdev->path), L"\\\\.\\%c:", d); + hdev->disc_changed = 1; + dev->local = hdev; + + hdev->hIOCTL = CreateFile(hdev->path, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, 0, NULL); + + DEBUG("IOCTL open(%ls) = %08lx\n", hdev->path, hdev->hIOCTL); + + dev->ops = &cdrom_host_ops; + dev->reset = ioctl_reset; + + /* + * With these, we read the READ CAPACITY command + * output from the host drive into our cache buffer. + */ + hdev->capacity_read = 0; + read_capacity(dev, NULL); + + DEBUG("Read capacity: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", + hdev->rcbuf[0], hdev->rcbuf[1], hdev->rcbuf[2], hdev->rcbuf[3], + hdev->rcbuf[4], hdev->rcbuf[5], hdev->rcbuf[6], hdev->rcbuf[7], + hdev->rcbuf[8], hdev->rcbuf[9], hdev->rcbuf[10], hdev->rcbuf[11], + hdev->rcbuf[12], hdev->rcbuf[13], hdev->rcbuf[14], hdev->rcbuf[15]); + + return 0; +} #endif + + +void +cdrom_host_init(void) +{ + WCHAR temp[16]; + int i = 0; + + cdrom_host_drive_available_num = 0; + for (i = 'A'; i <= 'Z'; i++) { + swprintf(temp, sizeof_w(temp), L"%c:\\", i); + + if (GetDriveType(temp) == DRIVE_CDROM) { + cdrom_host_drive_available[i - 'A'] = 1; + + cdrom_host_drive_available_num++; + } else + cdrom_host_drive_available[i - 'A'] = 0; + } +} diff --git a/src/win/win_settings_network.h b/src/win/win_settings_network.h index 3a94713..4da1959 100644 --- a/src/win/win_settings_network.h +++ b/src/win/win_settings_network.h @@ -8,7 +8,7 @@ * * Implementation of the Settings dialog. * - * Version: @(#)win_settings_network.h 1.0.6 2018/09/29 + * Version: @(#)win_settings_network.h 1.0.7 2018/10/16 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -64,7 +64,7 @@ network_recalc_combos(HWND hdlg) h = GetDlgItem(hdlg, IDC_COMBO_NET_CARD); if (temp_net_type == NET_TYPE_SLIRP) EnableWindow(h, TRUE); - else if ((temp_net_type == NET_TYPE_PCAP) && (network_dev_to_id(temp_host_dev) > 0)) + else if ((temp_net_type == NET_TYPE_PCAP) && (network_card_to_id(temp_host_dev) > 0)) EnableWindow(h, TRUE); else EnableWindow(h, FALSE); @@ -74,7 +74,7 @@ network_recalc_combos(HWND hdlg) EnableWindow(h, TRUE); } else if (network_card_has_config(temp_net_card) && (temp_net_type == NET_TYPE_PCAP) && - (network_dev_to_id(temp_host_dev) > 0)) { + (network_card_to_id(temp_host_dev) > 0)) { EnableWindow(h, TRUE); } else { EnableWindow(h, FALSE); @@ -118,7 +118,7 @@ network_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) mbstowcs(temp, network_devs[c].description, sizeof_w(temp)); SendMessage(h, CB_ADDSTRING, 0, (LPARAM)temp); } - SendMessage(h, CB_SETCURSEL, network_dev_to_id(temp_host_dev), 0); + SendMessage(h, CB_SETCURSEL, network_card_to_id(temp_host_dev), 0); /*NIC config*/ h = GetDlgItem(hdlg, IDC_COMBO_NET_CARD);