Split generic CD-ROM from SCSI-style CD-ROM;
Redid the way SCSI and ATAPI devices are handled; Slight timings change in the NCR 5380; Devices are now closed by device_close_all() in the reverse order of the one in which they were started; Slight changes to some code in win/; Added the WM_HARDRESET and WM_SHUTDOWN window messages for configuration manager purposes.
This commit is contained in:
3085
src/cdrom/cdrom.c
3085
src/cdrom/cdrom.c
File diff suppressed because it is too large
Load Diff
@@ -6,10 +6,9 @@
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the CD-ROM drive with SCSI(-like)
|
||||
* commands, for both ATAPI and SCSI usage.
|
||||
* Generic CD-ROM drive core header.
|
||||
*
|
||||
* Version: @(#)cdrom.h 1.0.13 2018/06/18
|
||||
* Version: @(#)cdrom.h 1.0.14 2018/10/09
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
@@ -27,21 +26,10 @@
|
||||
#define CD_STATUS_PAUSED 3
|
||||
#define CD_STATUS_STOPPED 4
|
||||
|
||||
#define CDROM_PHASE_IDLE 0x00
|
||||
#define CDROM_PHASE_COMMAND 0x01
|
||||
#define CDROM_PHASE_COMPLETE 0x02
|
||||
#define CDROM_PHASE_DATA_IN 0x03
|
||||
#define CDROM_PHASE_DATA_IN_DMA 0x04
|
||||
#define CDROM_PHASE_DATA_OUT 0x05
|
||||
#define CDROM_PHASE_DATA_OUT_DMA 0x06
|
||||
#define CDROM_PHASE_ERROR 0x80
|
||||
|
||||
#define BUF_SIZE 32768
|
||||
|
||||
#define CDROM_IMAGE 200
|
||||
|
||||
#define CDROM_TIME (5LL * 100LL * (1LL << TIMER_SHIFT))
|
||||
|
||||
|
||||
enum {
|
||||
CDROM_BUS_DISABLED = 0,
|
||||
@@ -73,116 +61,67 @@ typedef struct {
|
||||
} CDROM;
|
||||
|
||||
typedef struct {
|
||||
int host_drive;
|
||||
int prev_host_drive;
|
||||
CDROM *handler;
|
||||
|
||||
unsigned int bus_type; /* 0 = ATAPI, 1 = SCSI */
|
||||
int16_t cd_buffer[BUF_SIZE];
|
||||
|
||||
uint8_t speed, ide_channel,
|
||||
bus_mode; /* Bit 0 = PIO suported;
|
||||
pad, bus_mode; /* Bit 0 = PIO suported;
|
||||
Bit 1 = DMA supportd. */
|
||||
int host_drive, prev_host_drive,
|
||||
cd_status, prev_status,
|
||||
cd_buflen, cd_state,
|
||||
handler_inited, cur_speed,
|
||||
id;
|
||||
|
||||
unsigned int scsi_device_id, sound_on;
|
||||
unsigned int bus_type, /* 0 = ATAPI, 1 = SCSI */
|
||||
scsi_device_id, sound_on;
|
||||
|
||||
uint32_t seek_pos, seek_diff,
|
||||
cd_end, cdrom_capacity;
|
||||
|
||||
void *p;
|
||||
|
||||
void (*insert)(void *p);
|
||||
uint32_t (*get_volume)(void *p, int channel);
|
||||
uint32_t (*get_channel)(void *p, int channel);
|
||||
void (*close)(void *p);
|
||||
} cdrom_drive_t;
|
||||
|
||||
typedef struct {
|
||||
mode_sense_pages_t ms_pages_saved;
|
||||
|
||||
CDROM *handler;
|
||||
cdrom_drive_t *drv;
|
||||
|
||||
uint8_t previous_command,
|
||||
error, features,
|
||||
status, phase,
|
||||
id, *buffer,
|
||||
atapi_cdb[16],
|
||||
current_cdb[16],
|
||||
sense[256];
|
||||
|
||||
uint16_t request_length, max_transfer_len;
|
||||
int16_t cd_buffer[BUF_SIZE];
|
||||
|
||||
int media_status, is_dma,
|
||||
packet_status, requested_blocks,
|
||||
current_page_len, current_page_pos,
|
||||
mode_select_phase, do_page_save,
|
||||
total_length, written_length,
|
||||
callback, data_pos,
|
||||
cd_status, prev_status,
|
||||
unit_attention, request_pos,
|
||||
total_read, cur_speed,
|
||||
block_total, all_blocks_total,
|
||||
old_len, block_descriptor_len,
|
||||
init_length, last_subchannel_pos,
|
||||
cd_buflen, cd_state,
|
||||
handler_inited, disc_changed;
|
||||
|
||||
uint32_t sector_pos, sector_len,
|
||||
seek_pos, seek_diff,
|
||||
pos, packet_len,
|
||||
cdb_len, cd_end,
|
||||
cdrom_capacity;
|
||||
|
||||
uint64_t current_page_code;
|
||||
} cdrom_t;
|
||||
|
||||
typedef struct {
|
||||
int image_is_iso;
|
||||
wchar_t image_path[1024],
|
||||
*prev_image_path;
|
||||
FILE* image;
|
||||
|
||||
int image_is_iso;
|
||||
} cdrom_image_t;
|
||||
|
||||
|
||||
extern cdrom_t *cdrom[CDROM_NUM];
|
||||
extern cdrom_drive_t cdrom_drives[CDROM_NUM];
|
||||
extern cdrom_image_t cdrom_image[CDROM_NUM];
|
||||
extern uint8_t atapi_cdrom_drives[8];
|
||||
extern uint8_t scsi_cdrom_drives[16];
|
||||
|
||||
#define cdrom_sense_error dev->sense[0]
|
||||
#define cdrom_sense_key dev->sense[2]
|
||||
#define cdrom_asc dev->sense[12]
|
||||
#define cdrom_ascq dev->sense[13]
|
||||
#define cdrom_drive cdrom_drives[id].host_drive
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length, void *priv);
|
||||
extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length, void *priv);
|
||||
extern void (*ide_bus_master_set_irq)(int channel, void *priv);
|
||||
extern void *ide_bus_master_priv[2];
|
||||
|
||||
extern uint32_t cdrom_mode_sense_get_channel(cdrom_t *dev, int channel);
|
||||
extern uint32_t cdrom_mode_sense_get_volume(cdrom_t *dev, int channel);
|
||||
extern void build_atapi_cdrom_map(void);
|
||||
extern void build_scsi_cdrom_map(void);
|
||||
extern int cdrom_CDROM_PHASE_to_scsi(cdrom_t *dev);
|
||||
extern int cdrom_atapi_phase_to_scsi(cdrom_t *dev);
|
||||
extern void cdrom_command(cdrom_t *dev, uint8_t *cdb);
|
||||
extern void cdrom_phase_callback(cdrom_t *dev);
|
||||
extern uint32_t cdrom_read(uint8_t channel, int length);
|
||||
extern void cdrom_write(uint8_t channel, uint32_t val, int length);
|
||||
|
||||
extern int cdrom_lba_to_msf_accurate(int lba);
|
||||
extern double cdrom_get_short_seek(cdrom_drive_t *dev);
|
||||
extern double cdrom_get_long_seek(cdrom_drive_t *dev);
|
||||
extern double cdrom_seek_time(cdrom_drive_t *dev);
|
||||
extern void cdrom_seek(cdrom_drive_t *dev, uint32_t pos);
|
||||
extern int cdrom_playing_completed(cdrom_drive_t *dev);
|
||||
|
||||
extern void cdrom_close_handler(uint8_t id);
|
||||
extern void cdrom_close(void);
|
||||
extern void cdrom_reset(cdrom_t *dev);
|
||||
extern void cdrom_set_signature(cdrom_t *dev);
|
||||
extern void cdrom_request_sense_for_scsi(cdrom_t *dev, uint8_t *buffer, uint8_t alloc_length);
|
||||
extern void cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks);
|
||||
extern void cdrom_insert(cdrom_t *dev);
|
||||
|
||||
extern int find_cdrom_for_scsi_id(uint8_t scsi_id);
|
||||
extern int cdrom_read_capacity(cdrom_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len);
|
||||
|
||||
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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* CD-ROM image support.
|
||||
*
|
||||
* Version: @(#)cdrom_image.cc 1.0.1 2018/10/02
|
||||
* Version: @(#)cdrom_image.cc 1.0.2 2018/10/09
|
||||
*
|
||||
* Author: RichardG867,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -138,10 +138,10 @@ cdrom_image_log(const char *format, ...)
|
||||
int
|
||||
image_audio_callback(uint8_t id, int16_t *output, int len)
|
||||
{
|
||||
cdrom_t *dev = cdrom[id];
|
||||
cdrom_drive_t *dev = &cdrom_drives[id];
|
||||
int ret = 1;
|
||||
|
||||
if (!cdrom_drives[id].sound_on || (dev->cd_state != CD_PLAYING) || cdrom_image[id].image_is_iso) {
|
||||
if (!dev->sound_on || (dev->cd_state != CD_PLAYING) || cdrom_image[id].image_is_iso) {
|
||||
cdrom_image_log("image_audio_callback(i): Not playing\n", id);
|
||||
if (dev->cd_state == CD_PLAYING)
|
||||
dev->seek_pos += (len >> 11);
|
||||
@@ -179,7 +179,7 @@ image_audio_callback(uint8_t id, int16_t *output, int len)
|
||||
void
|
||||
image_audio_stop(uint8_t id)
|
||||
{
|
||||
cdrom_t *dev = cdrom[id];
|
||||
cdrom_drive_t *dev = &cdrom_drives[id];
|
||||
|
||||
dev->cd_state = CD_STOPPED;
|
||||
}
|
||||
@@ -188,7 +188,7 @@ image_audio_stop(uint8_t id)
|
||||
static uint8_t
|
||||
image_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf)
|
||||
{
|
||||
cdrom_t *dev = cdrom[id];
|
||||
cdrom_drive_t *dev = &cdrom_drives[id];
|
||||
if (!cdimg[id])
|
||||
return 0;
|
||||
int number;
|
||||
@@ -245,7 +245,7 @@ image_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf)
|
||||
static void
|
||||
image_pause(uint8_t id)
|
||||
{
|
||||
cdrom_t *dev = cdrom[id];
|
||||
cdrom_drive_t *dev = &cdrom_drives[id];
|
||||
|
||||
if (!cdimg[id] || cdrom_image[id].image_is_iso) return;
|
||||
if (dev->cd_state == CD_PLAYING)
|
||||
@@ -256,7 +256,7 @@ image_pause(uint8_t id)
|
||||
static void
|
||||
image_resume(uint8_t id)
|
||||
{
|
||||
cdrom_t *dev = cdrom[id];
|
||||
cdrom_drive_t *dev = &cdrom_drives[id];
|
||||
|
||||
if (!cdimg[id] || cdrom_image[id].image_is_iso)
|
||||
return;
|
||||
@@ -268,7 +268,7 @@ image_resume(uint8_t id)
|
||||
static void
|
||||
image_stop(uint8_t id)
|
||||
{
|
||||
cdrom_t *dev = cdrom[id];
|
||||
cdrom_drive_t *dev = &cdrom_drives[id];
|
||||
|
||||
if (!cdimg[id] || cdrom_image[id].image_is_iso)
|
||||
return;
|
||||
@@ -322,7 +322,7 @@ image_medium_changed(uint8_t id)
|
||||
static uint8_t
|
||||
image_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf)
|
||||
{
|
||||
cdrom_t *dev = cdrom[id];
|
||||
cdrom_drive_t *dev = &cdrom_drives[id];
|
||||
uint8_t ret;
|
||||
int pos = 0;
|
||||
uint32_t cdpos;
|
||||
@@ -837,7 +837,7 @@ image_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdr
|
||||
static uint32_t
|
||||
image_size(uint8_t id)
|
||||
{
|
||||
cdrom_t *dev = cdrom[id];
|
||||
cdrom_drive_t *dev = &cdrom_drives[id];
|
||||
|
||||
return dev->cdrom_capacity;
|
||||
}
|
||||
@@ -987,7 +987,7 @@ image_readtoc_raw(uint8_t id, unsigned char *b, int maxlen)
|
||||
static int
|
||||
image_status(uint8_t id)
|
||||
{
|
||||
cdrom_t *dev = cdrom[id];
|
||||
cdrom_drive_t *dev = &cdrom_drives[id];
|
||||
|
||||
if (!cdimg[id])
|
||||
return CD_STATUS_EMPTY;
|
||||
@@ -1021,7 +1021,7 @@ image_reset(UNUSED(uint8_t id))
|
||||
void
|
||||
image_close(uint8_t id)
|
||||
{
|
||||
cdrom_t *dev = cdrom[id];
|
||||
cdrom_drive_t *dev = &cdrom_drives[id];
|
||||
|
||||
dev->cd_state = CD_STOPPED;
|
||||
if (cdimg[id]) {
|
||||
@@ -1034,7 +1034,7 @@ image_close(uint8_t id)
|
||||
int
|
||||
image_open(uint8_t id, wchar_t *fn)
|
||||
{
|
||||
cdrom_t *dev = cdrom[id];
|
||||
cdrom_drive_t *dev = &cdrom_drives[id];
|
||||
|
||||
wcscpy(cdrom_image[id].image_path, fn);
|
||||
|
||||
@@ -1049,14 +1049,14 @@ image_open(uint8_t id, wchar_t *fn)
|
||||
if (!cdimg[id]->SetDevice(afn, false)) {
|
||||
image_close(id);
|
||||
cdrom_set_null_handler(id);
|
||||
cdrom_image_log("[f] image_open(): cdrom[%i]->handler = %08X\n", id, cdrom[id]->handler);
|
||||
cdrom_image_log("[f] image_open(): cdrom_drives[%i].handler = %08X\n", id, cdrom_drives[id].handler);
|
||||
return 1;
|
||||
}
|
||||
dev->cd_state = CD_STOPPED;
|
||||
dev->seek_pos = 0;
|
||||
dev->cd_buflen = 0;
|
||||
dev->cdrom_capacity = image_get_last_block(id) + 1;
|
||||
cdrom[id]->handler = &image_cdrom;
|
||||
cdrom_drives[id].handler = &image_cdrom;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1065,7 +1065,7 @@ image_open(uint8_t id, wchar_t *fn)
|
||||
static void
|
||||
image_exit(uint8_t id)
|
||||
{
|
||||
cdrom_t *dev = cdrom[id];
|
||||
cdrom_drive_t *dev = &cdrom_drives[id];
|
||||
|
||||
dev->handler_inited = 0;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Implementation of the CD-ROM null interface for unmounted
|
||||
* guest CD-ROM drives.
|
||||
*
|
||||
* Version: @(#)cdrom_null.c 1.0.8 2018/10/02
|
||||
* Version: @(#)cdrom_null.c 1.0.9 2018/10/09
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -134,7 +134,7 @@ null_media_type_id(uint8_t id)
|
||||
void
|
||||
cdrom_set_null_handler(uint8_t id)
|
||||
{
|
||||
cdrom[id]->handler = &null_cdrom;
|
||||
cdrom_drives[id].handler = &null_cdrom;
|
||||
cdrom_drives[id].host_drive = 0;
|
||||
memset(cdrom_image[id].image_path, 0, sizeof(cdrom_image[id].image_path));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user