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:
OBattler
2018-10-10 22:33:24 +02:00
parent 173b1f7694
commit 6155802b59
36 changed files with 4557 additions and 4792 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -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
}

View File

@@ -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;
}

View File

@@ -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));
}