mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 01:25:33 -07:00
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:
@@ -106,8 +106,7 @@ STUFF :=
|
||||
# -DENABLE_BUSLOGIC_LOG=N sets logging level at N.
|
||||
# -DENABLE_NCR5380_LOG=N sets logging level at N.
|
||||
# -DENABLE_NCR53C810_LOG=N sets logging level at N.
|
||||
# -DENABLE_SCSI_LOG=N sets logging level at N.
|
||||
# -DENABLE_SCSI_BUS_LOG=N sets logging level at N.
|
||||
# -DENABLE_SCSI_CDROM_LOG=N sets logging level at N.
|
||||
# -DENABLE_SCSI_DISK_LOG=N sets logging level at N.
|
||||
# -DENABLE_X54X_LOG=N sets logging level at N.
|
||||
# sound/ logging:
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Implementation of the generic device interface to handle
|
||||
* all devices attached to the emulator.
|
||||
*
|
||||
* Version: @(#)device.c 1.0.17 2018/10/02
|
||||
* Version: @(#)device.c 1.0.18 2018/10/10
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -217,8 +217,10 @@ device_close_all(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < DEVICE_MAX; c++) {
|
||||
for (c = (DEVICE_MAX - 1); c >= 0; c--) {
|
||||
if (devices[c] != NULL) {
|
||||
if (devices[c]->name)
|
||||
devicelog("Closing device: \"%s\"...\n", devices[c]->name);
|
||||
if (devices[c]->close != NULL)
|
||||
devices[c]->close(device_priv[c]);
|
||||
devices[c] = device_priv[c] = NULL;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,7 @@
|
||||
* Implementation of the IDE emulation for hard disks and ATAPI
|
||||
* CD-ROM devices.
|
||||
*
|
||||
* Version: @(#)hdd_ide.h 1.0.11 2018/09/15
|
||||
* Version: @(#)hdd_ide.h 1.0.12 2018/10/10
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -20,28 +20,77 @@
|
||||
# define EMU_IDE_H
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t atastat, error,
|
||||
command, fdisk;
|
||||
int type, board,
|
||||
irqstat, service,
|
||||
blocksize, blockcount,
|
||||
hdd_num, channel,
|
||||
pos, sector_pos,
|
||||
lba, skip512,
|
||||
reset, mdma_mode,
|
||||
do_initial_read;
|
||||
uint32_t secount, sector,
|
||||
cylinder, head,
|
||||
drive, cylprecomp,
|
||||
cfg_spt, cfg_hpc,
|
||||
lba_addr, tracks,
|
||||
spt, hpc;
|
||||
enum
|
||||
{
|
||||
IDE_NONE = 0,
|
||||
IDE_HDD,
|
||||
IDE_ATAPI
|
||||
};
|
||||
|
||||
uint16_t *buffer;
|
||||
uint8_t *sector_buffer;
|
||||
typedef struct {
|
||||
uint8_t atastat, error,
|
||||
command, fdisk;
|
||||
int type, board,
|
||||
irqstat, service,
|
||||
blocksize, blockcount,
|
||||
hdd_num, channel,
|
||||
pos, sector_pos,
|
||||
lba, skip512,
|
||||
reset, mdma_mode,
|
||||
do_initial_read;
|
||||
uint32_t secount, sector,
|
||||
cylinder, head,
|
||||
drive, cylprecomp,
|
||||
cfg_spt, cfg_hpc,
|
||||
lba_addr, tracks,
|
||||
spt, hpc;
|
||||
|
||||
uint16_t *buffer;
|
||||
uint8_t *sector_buffer;
|
||||
|
||||
/* Stuff mostly used by ATAPI */
|
||||
void *p;
|
||||
int interrupt_drq;
|
||||
|
||||
int (*get_max)(int ide_has_dma, int type);
|
||||
int (*get_timings)(int ide_has_dma, int type);
|
||||
void (*identify)(void *p, int ide_has_dma);
|
||||
void (*set_signature)(void *p);
|
||||
void (*packet_write)(void *p, uint32_t val, int length);
|
||||
uint32_t (*packet_read)(void *p, int length);
|
||||
void (*stop)(void *p);
|
||||
void (*packet_callback)(void *p);
|
||||
void (*device_reset)(void *p);
|
||||
} ide_t;
|
||||
|
||||
/* Type:
|
||||
0 = PIO,
|
||||
1 = SDMA,
|
||||
2 = MDMA,
|
||||
3 = UDMA
|
||||
Return:
|
||||
-1 = Not supported,
|
||||
Anything else = maximum mode
|
||||
|
||||
This will eventually be hookable. */
|
||||
enum {
|
||||
TYPE_PIO = 0,
|
||||
TYPE_SDMA,
|
||||
TYPE_MDMA,
|
||||
TYPE_UDMA
|
||||
};
|
||||
|
||||
/* Return:
|
||||
0 = Not supported,
|
||||
Anything else = timings
|
||||
|
||||
This will eventually be hookable. */
|
||||
enum {
|
||||
TIMINGS_DMA = 0,
|
||||
TIMINGS_PIO,
|
||||
TIMINGS_PIO_FC
|
||||
};
|
||||
|
||||
|
||||
extern int ideboard;
|
||||
extern int ide_ter_enabled, ide_qua_enabled;
|
||||
@@ -82,6 +131,7 @@ extern void ide_sec_disable(void);
|
||||
extern void ide_set_callback(uint8_t channel, int64_t callback);
|
||||
extern void secondary_ide_check(void);
|
||||
|
||||
extern void ide_padstr(char *str, const char *src, int len);
|
||||
extern void ide_padstr8(uint8_t *buf, int buf_size, const char *src);
|
||||
|
||||
extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length, void *priv);
|
||||
@@ -90,6 +140,8 @@ extern void (*ide_bus_master_set_irq)(int channel, void *priv);
|
||||
extern void *ide_bus_master_priv[2];
|
||||
|
||||
extern void ide_enable_pio_override(void);
|
||||
extern void ide_allocate_buffer(ide_t *dev);
|
||||
extern void ide_atapi_attach(ide_t *dev);
|
||||
|
||||
|
||||
#endif /*EMU_IDE_H*/
|
||||
|
||||
457
src/disk/zip.c
457
src/disk/zip.c
@@ -51,11 +51,8 @@
|
||||
#define zipbufferb dev->buffer
|
||||
|
||||
|
||||
zip_t *zip[ZIP_NUM];
|
||||
zip_t *zip[ZIP_NUM] = { NULL, NULL, NULL, NULL };
|
||||
zip_drive_t zip_drives[ZIP_NUM];
|
||||
uint8_t atapi_zip_drives[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
uint8_t scsi_zip_drives[16] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
|
||||
|
||||
/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */
|
||||
@@ -456,7 +453,7 @@ static const mode_sense_pages_t zip_250_mode_sense_pages_changeable =
|
||||
static void zip_command_complete(zip_t *dev);
|
||||
static void zip_init(zip_t *dev);
|
||||
|
||||
void zip_phase_callback(zip_t *dev);
|
||||
static void zip_callback(void *p);
|
||||
|
||||
|
||||
#ifdef ENABLE_ZIP_LOG
|
||||
@@ -581,43 +578,6 @@ zip_disk_close(zip_t *dev)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
build_atapi_zip_map()
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
memset(atapi_zip_drives, 0xff, 8);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
atapi_zip_drives[i] = find_zip_for_channel(i);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
find_zip_for_scsi_id(uint8_t scsi_id)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
for (i = 0; i < ZIP_NUM; i++) {
|
||||
if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && (zip_drives[i].scsi_device_id == scsi_id))
|
||||
return i;
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
build_scsi_zip_map()
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
memset(scsi_zip_drives, 0xff, 16);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
scsi_zip_drives[i] = find_zip_for_scsi_id(i);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
zip_set_callback(zip_t *dev)
|
||||
{
|
||||
@@ -626,9 +586,11 @@ zip_set_callback(zip_t *dev)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
zip_set_signature(zip_t *dev)
|
||||
static void
|
||||
zip_set_signature(void *p)
|
||||
{
|
||||
zip_t *dev = (zip_t *) p;
|
||||
|
||||
if (dev->id >= ZIP_NUM)
|
||||
return;
|
||||
dev->phase = 1;
|
||||
@@ -696,9 +658,11 @@ zip_current_mode(zip_t *dev)
|
||||
|
||||
|
||||
/* Translates ATAPI status (ERR_STAT flag) to SCSI status. */
|
||||
int
|
||||
zip_ZIP_PHASE_to_scsi(zip_t *dev)
|
||||
static int
|
||||
zip_err_stat_to_scsi(void *p)
|
||||
{
|
||||
zip_t *dev = (zip_t *) p;
|
||||
|
||||
if (dev->status & ERR_STAT)
|
||||
return SCSI_STATUS_CHECK_CONDITION;
|
||||
else
|
||||
@@ -795,9 +759,10 @@ zip_mode_sense_save(zip_t *dev)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
zip_read_capacity(zip_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len)
|
||||
static int
|
||||
zip_read_capacity(void *p, uint8_t *cdb, uint8_t *buffer, uint32_t *len)
|
||||
{
|
||||
zip_t *dev = (zip_t *) p;
|
||||
int size = 0;
|
||||
|
||||
if (dev->drv->is_250)
|
||||
@@ -855,10 +820,10 @@ zip_mode_sense_read(zip_t *dev, uint8_t page_control, uint8_t page, uint8_t pos)
|
||||
|
||||
|
||||
static uint32_t
|
||||
zip_mode_sense(zip_t *dev, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t block_descriptor_len)
|
||||
zip_mode_sense(zip_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block_descriptor_len)
|
||||
{
|
||||
uint64_t pf;
|
||||
uint8_t page_control = (type >> 6) & 3;
|
||||
uint8_t page_control = (page >> 6) & 3;
|
||||
|
||||
if (dev->drv->is_250)
|
||||
pf = zip_250_mode_sense_page_flags;
|
||||
@@ -870,7 +835,7 @@ zip_mode_sense(zip_t *dev, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t blo
|
||||
|
||||
uint8_t msplen;
|
||||
|
||||
type &= 0x3f;
|
||||
page &= 0x3f;
|
||||
|
||||
if (block_descriptor_len) {
|
||||
if (dev->drv->is_250) {
|
||||
@@ -891,8 +856,8 @@ zip_mode_sense(zip_t *dev, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t blo
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x40; i++) {
|
||||
if ((type == GPMODE_ALL_PAGES) || (type == i)) {
|
||||
if (pf & (1LL << dev->current_page_code)) {
|
||||
if ((page == GPMODE_ALL_PAGES) || (page == i)) {
|
||||
if (pf & (1LL << ((uint64_t) page))) {
|
||||
buf[pos++] = zip_mode_sense_read(dev, page_control, i, 0);
|
||||
msplen = zip_mode_sense_read(dev, page_control, i, 1);
|
||||
buf[pos++] = msplen;
|
||||
@@ -976,8 +941,8 @@ zip_command_common(zip_t *dev)
|
||||
dev->status = BUSY_STAT;
|
||||
dev->phase = 1;
|
||||
dev->pos = 0;
|
||||
if (dev->packet_status == ZIP_PHASE_COMPLETE) {
|
||||
zip_phase_callback(dev);
|
||||
if (dev->packet_status == PHASE_COMPLETE) {
|
||||
zip_callback((void *) dev);
|
||||
dev->callback = 0LL;
|
||||
} else {
|
||||
if (dev->drv->bus_type == ZIP_BUS_SCSI) {
|
||||
@@ -1003,7 +968,7 @@ zip_command_common(zip_t *dev)
|
||||
static void
|
||||
zip_command_complete(zip_t *dev)
|
||||
{
|
||||
dev->packet_status = ZIP_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
zip_command_common(dev);
|
||||
}
|
||||
|
||||
@@ -1011,25 +976,23 @@ zip_command_complete(zip_t *dev)
|
||||
static void
|
||||
zip_command_read(zip_t *dev)
|
||||
{
|
||||
dev->packet_status = ZIP_PHASE_DATA_IN;
|
||||
dev->packet_status = PHASE_DATA_IN;
|
||||
zip_command_common(dev);
|
||||
dev->total_read = 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
zip_command_read_dma(zip_t *dev)
|
||||
{
|
||||
dev->packet_status = ZIP_PHASE_DATA_IN_DMA;
|
||||
dev->packet_status = PHASE_DATA_IN_DMA;
|
||||
zip_command_common(dev);
|
||||
dev->total_read = 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
zip_command_write(zip_t *dev)
|
||||
{
|
||||
dev->packet_status = ZIP_PHASE_DATA_OUT;
|
||||
dev->packet_status = PHASE_DATA_OUT;
|
||||
zip_command_common(dev);
|
||||
}
|
||||
|
||||
@@ -1037,7 +1000,7 @@ zip_command_write(zip_t *dev)
|
||||
static void
|
||||
zip_command_write_dma(zip_t *dev)
|
||||
{
|
||||
dev->packet_status = ZIP_PHASE_DATA_OUT_DMA;
|
||||
dev->packet_status = PHASE_DATA_OUT_DMA;
|
||||
zip_command_common(dev);
|
||||
}
|
||||
|
||||
@@ -1088,7 +1051,6 @@ zip_data_command_finish(zip_t *dev, int len, int block_len, int alloc_len, int d
|
||||
static void
|
||||
zip_sense_clear(zip_t *dev, int command)
|
||||
{
|
||||
dev->previous_command = command;
|
||||
zip_sense_key = zip_asc = zip_ascq = 0;
|
||||
}
|
||||
|
||||
@@ -1101,7 +1063,7 @@ zip_set_phase(zip_t *dev, uint8_t phase)
|
||||
if (dev->drv->bus_type != ZIP_BUS_SCSI)
|
||||
return;
|
||||
|
||||
SCSIDevices[scsi_id].Phase = phase;
|
||||
scsi_devices[scsi_id].phase = phase;
|
||||
}
|
||||
|
||||
|
||||
@@ -1232,8 +1194,6 @@ zip_data_phase_error(zip_t *dev)
|
||||
static int
|
||||
zip_blocks(zip_t *dev, int32_t *len, int first_batch, int out)
|
||||
{
|
||||
dev->data_pos = 0;
|
||||
|
||||
*len = 0;
|
||||
|
||||
if (!dev->sector_len) {
|
||||
@@ -1348,11 +1308,6 @@ zip_pre_execution_check(zip_t *dev, uint8_t *cdb)
|
||||
zip_sense_clear(dev, cdb[0]);
|
||||
|
||||
/* Next it's time for NOT READY. */
|
||||
if (!ready)
|
||||
dev->media_status = MEC_MEDIA_REMOVAL;
|
||||
else
|
||||
dev->media_status = (dev->unit_attention) ? MEC_NEW_MEDIA : MEC_NO_CHANGE;
|
||||
|
||||
if ((zip_command_flags[cdb[0]] & CHECK_READY) && !ready) {
|
||||
zip_log("ZIP %i: Not ready (%02X)\n", dev->id, cdb[0]);
|
||||
zip_not_ready(dev);
|
||||
@@ -1382,8 +1337,10 @@ zip_rezero(zip_t *dev)
|
||||
|
||||
|
||||
void
|
||||
zip_reset(zip_t *dev)
|
||||
zip_reset(void *p)
|
||||
{
|
||||
zip_t *dev = (zip_t *) p;
|
||||
|
||||
zip_rezero(dev);
|
||||
dev->status = 0;
|
||||
dev->callback = 0LL;
|
||||
@@ -1429,9 +1386,10 @@ zip_request_sense(zip_t *dev, uint8_t *buffer, uint8_t alloc_length, int desc)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
zip_request_sense_for_scsi(zip_t *dev, uint8_t *buffer, uint8_t alloc_length)
|
||||
static void
|
||||
zip_request_sense_for_scsi(void *p, uint8_t *buffer, uint8_t alloc_length)
|
||||
{
|
||||
zip_t *dev = (zip_t *) p;
|
||||
int ready = 0;
|
||||
|
||||
ready = (dev->drv->f != NULL);
|
||||
@@ -1483,9 +1441,10 @@ zip_buf_free(zip_t *dev)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
zip_command(zip_t *dev, uint8_t *cdb)
|
||||
static void
|
||||
zip_command(void *p, uint8_t *cdb)
|
||||
{
|
||||
zip_t *dev = (zip_t *) p;
|
||||
int pos = 0, block_desc = 0;
|
||||
int ret;
|
||||
int32_t len, max_len;
|
||||
@@ -1497,7 +1456,7 @@ zip_command(zip_t *dev, uint8_t *cdb)
|
||||
int32_t *BufLen;
|
||||
|
||||
if (dev->drv->bus_type == ZIP_BUS_SCSI) {
|
||||
BufLen = &SCSIDevices[dev->drv->scsi_device_id].BufferLength;
|
||||
BufLen = &scsi_devices[dev->drv->scsi_device_id].buffer_length;
|
||||
dev->status &= ~ERR_STAT;
|
||||
} else {
|
||||
BufLen = &blen;
|
||||
@@ -1507,8 +1466,6 @@ zip_command(zip_t *dev, uint8_t *cdb)
|
||||
dev->packet_len = 0;
|
||||
dev->request_pos = 0;
|
||||
|
||||
dev->data_pos = 0;
|
||||
|
||||
memcpy(dev->current_cdb, cdb, 12);
|
||||
|
||||
if (cdb[0] != 0) {
|
||||
@@ -1597,7 +1554,7 @@ zip_command(zip_t *dev, uint8_t *cdb)
|
||||
|
||||
if (!max_len) {
|
||||
zip_set_phase(dev, SCSI_PHASE_STATUS);
|
||||
dev->packet_status = ZIP_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->callback = 20LL * ZIP_TIME;
|
||||
zip_set_callback(dev);
|
||||
break;
|
||||
@@ -1650,7 +1607,7 @@ zip_command(zip_t *dev, uint8_t *cdb)
|
||||
if (!dev->sector_len) {
|
||||
zip_set_phase(dev, SCSI_PHASE_STATUS);
|
||||
/* zip_log("ZIP %i: All done - callback set\n", dev->id); */
|
||||
dev->packet_status = ZIP_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->callback = 20LL * ZIP_TIME;
|
||||
zip_set_callback(dev);
|
||||
break;
|
||||
@@ -1677,8 +1634,7 @@ zip_command(zip_t *dev, uint8_t *cdb)
|
||||
|
||||
zip_data_command_finish(dev, alloc_length, 512, alloc_length, 0);
|
||||
|
||||
dev->all_blocks_total = dev->block_total;
|
||||
if (dev->packet_status != ZIP_PHASE_COMPLETE)
|
||||
if (dev->packet_status != PHASE_COMPLETE)
|
||||
ui_sb_update_icon(SB_ZIP | dev->id, 1);
|
||||
else
|
||||
ui_sb_update_icon(SB_ZIP | dev->id, 0);
|
||||
@@ -1743,7 +1699,7 @@ zip_command(zip_t *dev, uint8_t *cdb)
|
||||
if (!dev->sector_len) {
|
||||
zip_set_phase(dev, SCSI_PHASE_STATUS);
|
||||
/* zip_log("ZIP %i: All done - callback set\n", dev->id); */
|
||||
dev->packet_status = ZIP_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->callback = 20LL * ZIP_TIME;
|
||||
zip_set_callback(dev);
|
||||
break;
|
||||
@@ -1764,8 +1720,7 @@ zip_command(zip_t *dev, uint8_t *cdb)
|
||||
|
||||
zip_data_command_finish(dev, dev->packet_len, 512, dev->packet_len, 1);
|
||||
|
||||
dev->all_blocks_total = dev->block_total;
|
||||
if (dev->packet_status != ZIP_PHASE_COMPLETE)
|
||||
if (dev->packet_status != PHASE_COMPLETE)
|
||||
ui_sb_update_icon(SB_ZIP | dev->id, 1);
|
||||
else
|
||||
ui_sb_update_icon(SB_ZIP | dev->id, 0);
|
||||
@@ -1805,7 +1760,7 @@ zip_command(zip_t *dev, uint8_t *cdb)
|
||||
if (!dev->sector_len) {
|
||||
zip_set_phase(dev, SCSI_PHASE_STATUS);
|
||||
/* zip_log("ZIP %i: All done - callback set\n", dev->id); */
|
||||
dev->packet_status = ZIP_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->callback = 20LL * ZIP_TIME;
|
||||
zip_set_callback(dev);
|
||||
break;
|
||||
@@ -1826,8 +1781,7 @@ zip_command(zip_t *dev, uint8_t *cdb)
|
||||
|
||||
zip_data_command_finish(dev, dev->packet_len, 512, dev->packet_len, 1);
|
||||
|
||||
dev->all_blocks_total = dev->block_total;
|
||||
if (dev->packet_status != ZIP_PHASE_COMPLETE)
|
||||
if (dev->packet_status != PHASE_COMPLETE)
|
||||
ui_sb_update_icon(SB_ZIP | dev->id, 1);
|
||||
else
|
||||
ui_sb_update_icon(SB_ZIP | dev->id, 0);
|
||||
@@ -1850,10 +1804,7 @@ zip_command(zip_t *dev, uint8_t *cdb)
|
||||
zip_buf_alloc(dev, 65536);
|
||||
}
|
||||
|
||||
dev->current_page_code = cdb[2] & 0x3F;
|
||||
zip_log("Mode sense page: %02X\n", dev->current_page_code);
|
||||
|
||||
if (!(zip_mode_sense_page_flags & (1LL << dev->current_page_code))) {
|
||||
if (!(zip_mode_sense_page_flags & (1LL << (uint64_t) (cdb[2] & 0x3f)))) {
|
||||
zip_invalid_field(dev);
|
||||
zip_buf_free(dev);
|
||||
return;
|
||||
@@ -1905,8 +1856,6 @@ zip_command(zip_t *dev, uint8_t *cdb)
|
||||
dev->total_length = len;
|
||||
dev->do_page_save = cdb[1] & 1;
|
||||
|
||||
dev->current_page_pos = 0;
|
||||
|
||||
zip_data_command_finish(dev, len, len, len, 1);
|
||||
return;
|
||||
|
||||
@@ -2335,11 +2284,11 @@ zip_pio_request(zip_t *dev, uint8_t out)
|
||||
zip_log("ZIP %i: Packet length %i, request length %i\n", dev->id, dev->packet_len,
|
||||
dev->max_transfer_len);
|
||||
|
||||
dev->packet_status = out ? ZIP_PHASE_DATA_OUT : ZIP_PHASE_DATA_IN;
|
||||
dev->packet_status = out ? PHASE_DATA_OUT : PHASE_DATA_IN;
|
||||
|
||||
dev->status = BUSY_STAT;
|
||||
dev->phase = 1;
|
||||
zip_phase_callback(dev);
|
||||
zip_callback((void *) dev);
|
||||
dev->callback = 0LL;
|
||||
zip_set_callback(dev);
|
||||
|
||||
@@ -2349,22 +2298,17 @@ zip_pio_request(zip_t *dev, uint8_t out)
|
||||
|
||||
|
||||
static int
|
||||
zip_read_from_ide_dma(uint8_t channel)
|
||||
zip_read_from_ide_dma(zip_t *dev)
|
||||
{
|
||||
zip_t *dev;
|
||||
|
||||
uint8_t id = atapi_zip_drives[channel];
|
||||
int ret;
|
||||
|
||||
if (id > ZIP_NUM)
|
||||
if (!dev)
|
||||
return 0;
|
||||
|
||||
dev = zip[id];
|
||||
|
||||
if (ide_bus_master_write) {
|
||||
ret = ide_bus_master_write(channel >> 1,
|
||||
ret = ide_bus_master_write(dev->drv->ide_channel >> 1,
|
||||
zipbufferb, dev->packet_len,
|
||||
ide_bus_master_priv[channel >> 1]);
|
||||
ide_bus_master_priv[dev->drv->ide_channel >> 1]);
|
||||
if (ret == 2) /* DMA not enabled, wait for it to be enabled. */
|
||||
return 2;
|
||||
else if (ret == 1) { /* DMA error. */
|
||||
@@ -2380,18 +2324,14 @@ zip_read_from_ide_dma(uint8_t channel)
|
||||
static int
|
||||
zip_read_from_scsi_dma(uint8_t scsi_id)
|
||||
{
|
||||
zip_t *dev;
|
||||
zip_t *dev = (zip_t *) scsi_devices[scsi_id].p;
|
||||
int32_t *BufLen = &scsi_devices[scsi_id].buffer_length;
|
||||
|
||||
uint8_t id = scsi_zip_drives[scsi_id];
|
||||
int32_t *BufLen = &SCSIDevices[scsi_id].BufferLength;
|
||||
|
||||
if (id > ZIP_NUM)
|
||||
if (!dev)
|
||||
return 0;
|
||||
|
||||
dev = zip[id];
|
||||
|
||||
zip_log("Reading from SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, *BufLen);
|
||||
memcpy(zipbufferb, SCSIDevices[scsi_id].CmdBuffer, *BufLen);
|
||||
memcpy(zipbufferb, scsi_devices[scsi_id].cmd_buffer, *BufLen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -2407,13 +2347,13 @@ zip_irq_raise(zip_t *dev)
|
||||
static int
|
||||
zip_read_from_dma(zip_t *dev)
|
||||
{
|
||||
int32_t *BufLen = &SCSIDevices[dev->drv->scsi_device_id].BufferLength;
|
||||
int32_t *BufLen = &scsi_devices[dev->drv->scsi_device_id].buffer_length;
|
||||
int ret = 0;
|
||||
|
||||
if (dev->drv->bus_type == ZIP_BUS_SCSI)
|
||||
ret = zip_read_from_scsi_dma(dev->drv->scsi_device_id);
|
||||
else
|
||||
ret = zip_read_from_ide_dma(dev->drv->ide_channel);
|
||||
ret = zip_read_from_ide_dma(dev);
|
||||
|
||||
if (ret != 1)
|
||||
return ret;
|
||||
@@ -2433,24 +2373,17 @@ zip_read_from_dma(zip_t *dev)
|
||||
|
||||
|
||||
static int
|
||||
zip_write_to_ide_dma(uint8_t channel)
|
||||
zip_write_to_ide_dma(zip_t *dev)
|
||||
{
|
||||
zip_t *dev;
|
||||
|
||||
uint8_t id = atapi_zip_drives[channel];
|
||||
int ret;
|
||||
|
||||
if (id > ZIP_NUM) {
|
||||
zip_log("ZIP %i: Drive not found\n", id);
|
||||
if (!dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev = zip[id];
|
||||
|
||||
if (ide_bus_master_read) {
|
||||
ret = ide_bus_master_read(channel >> 1,
|
||||
ret = ide_bus_master_read(dev->drv->ide_channel >> 1,
|
||||
zipbufferb, dev->packet_len,
|
||||
ide_bus_master_priv[channel >> 1]);
|
||||
ide_bus_master_priv[dev->drv->ide_channel >> 1]);
|
||||
if (ret == 2) /* DMA not enabled, wait for it to be enabled. */
|
||||
return 2;
|
||||
else if (ret == 1) { /* DMA error. */
|
||||
@@ -2466,26 +2399,17 @@ zip_write_to_ide_dma(uint8_t channel)
|
||||
static int
|
||||
zip_write_to_scsi_dma(uint8_t scsi_id)
|
||||
{
|
||||
zip_t *dev;
|
||||
zip_t *dev = (zip_t *) scsi_devices[scsi_id].p;
|
||||
int32_t *BufLen = &scsi_devices[scsi_id].buffer_length;
|
||||
|
||||
uint8_t id = scsi_zip_drives[scsi_id];
|
||||
int32_t *BufLen = &SCSIDevices[scsi_id].BufferLength;
|
||||
|
||||
if (id > ZIP_NUM)
|
||||
if (!dev)
|
||||
return 0;
|
||||
|
||||
dev = zip[id];
|
||||
|
||||
zip_log("Writing to SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, *BufLen);
|
||||
memcpy(SCSIDevices[scsi_id].CmdBuffer, zipbufferb, *BufLen);
|
||||
zip_log("ZIP %i: Data from CD buffer: %02X %02X %02X %02X %02X %02X %02X %02X\n", id,
|
||||
memcpy(scsi_devices[scsi_id].cmd_buffer, zipbufferb, *BufLen);
|
||||
zip_log("ZIP %i: Data from CD buffer: %02X %02X %02X %02X %02X %02X %02X %02X\n", dev->id,
|
||||
zipbufferb[0], zipbufferb[1], zipbufferb[2], zipbufferb[3], zipbufferb[4], zipbufferb[5],
|
||||
zipbufferb[6], zipbufferb[7]);
|
||||
zip_log("ZIP %i: Data from SCSI DMA : %02X %02X %02X %02X %02X %02X %02X %02X\n", id,
|
||||
SCSIDevices[scsi_id].CmdBuffer[0], SCSIDevices[scsi_id].CmdBuffer[1],
|
||||
SCSIDevices[scsi_id].CmdBuffer[2], SCSIDevices[scsi_id].CmdBuffer[3],
|
||||
SCSIDevices[scsi_id].CmdBuffer[4], SCSIDevices[scsi_id].CmdBuffer[5],
|
||||
SCSIDevices[scsi_id].CmdBuffer[6], SCSIDevices[scsi_id].CmdBuffer[7]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -2493,14 +2417,14 @@ zip_write_to_scsi_dma(uint8_t scsi_id)
|
||||
static int
|
||||
zip_write_to_dma(zip_t *dev)
|
||||
{
|
||||
int32_t *BufLen = &SCSIDevices[dev->drv->scsi_device_id].BufferLength;
|
||||
int32_t *BufLen = &scsi_devices[dev->drv->scsi_device_id].buffer_length;
|
||||
int ret = 0;
|
||||
|
||||
if (dev->drv->bus_type == ZIP_BUS_SCSI) {
|
||||
zip_log("Write to SCSI DMA: (ID %02X)\n", dev->drv->scsi_device_id);
|
||||
ret = zip_write_to_scsi_dma(dev->drv->scsi_device_id);
|
||||
} else
|
||||
ret = zip_write_to_ide_dma(dev->drv->ide_channel);
|
||||
ret = zip_write_to_ide_dma(dev);
|
||||
|
||||
if (dev->drv->bus_type == ZIP_BUS_SCSI)
|
||||
zip_log("ZIP %i: SCSI Output data length: %i\n", dev->id, *BufLen);
|
||||
@@ -2511,40 +2435,41 @@ zip_write_to_dma(zip_t *dev)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
zip_phase_callback(zip_t *dev)
|
||||
static void
|
||||
zip_callback(void *p)
|
||||
{
|
||||
zip_t *dev = (zip_t *) p;
|
||||
int ret;
|
||||
|
||||
switch(dev->packet_status) {
|
||||
case ZIP_PHASE_IDLE:
|
||||
zip_log("ZIP %i: ZIP_PHASE_IDLE\n", dev->id);
|
||||
case PHASE_IDLE:
|
||||
zip_log("ZIP %i: PHASE_IDLE\n", dev->id);
|
||||
dev->pos = 0;
|
||||
dev->phase = 1;
|
||||
dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT);
|
||||
return;
|
||||
case ZIP_PHASE_COMMAND:
|
||||
zip_log("ZIP %i: ZIP_PHASE_COMMAND\n", dev->id);
|
||||
case PHASE_COMMAND:
|
||||
zip_log("ZIP %i: PHASE_COMMAND\n", dev->id);
|
||||
dev->status = BUSY_STAT | (dev->status & ERR_STAT);
|
||||
memcpy(dev->atapi_cdb, zipbufferb, 12);
|
||||
zip_command(dev, dev->atapi_cdb);
|
||||
return;
|
||||
case ZIP_PHASE_COMPLETE:
|
||||
zip_log("ZIP %i: ZIP_PHASE_COMPLETE\n", dev->id);
|
||||
case PHASE_COMPLETE:
|
||||
zip_log("ZIP %i: PHASE_COMPLETE\n", dev->id);
|
||||
dev->status = READY_STAT;
|
||||
dev->phase = 3;
|
||||
dev->packet_status = 0xFF;
|
||||
ui_sb_update_icon(SB_ZIP | dev->id, 0);
|
||||
zip_irq_raise(dev);
|
||||
return;
|
||||
case ZIP_PHASE_DATA_OUT:
|
||||
zip_log("ZIP %i: ZIP_PHASE_DATA_OUT\n", dev->id);
|
||||
case PHASE_DATA_OUT:
|
||||
zip_log("ZIP %i: PHASE_DATA_OUT\n", dev->id);
|
||||
dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT);
|
||||
dev->phase = 0;
|
||||
zip_irq_raise(dev);
|
||||
return;
|
||||
case ZIP_PHASE_DATA_OUT_DMA:
|
||||
zip_log("ZIP %i: ZIP_PHASE_DATA_OUT_DMA\n", dev->id);
|
||||
case PHASE_DATA_OUT_DMA:
|
||||
zip_log("ZIP %i: PHASE_DATA_OUT_DMA\n", dev->id);
|
||||
ret = zip_read_from_dma(dev);
|
||||
|
||||
if ((ret == 1) || (dev->drv->bus_type == ZIP_BUS_SCSI)) {
|
||||
@@ -2559,14 +2484,14 @@ zip_phase_callback(zip_t *dev)
|
||||
zip_buf_free(dev);
|
||||
}
|
||||
return;
|
||||
case ZIP_PHASE_DATA_IN:
|
||||
zip_log("ZIP %i: ZIP_PHASE_DATA_IN\n", dev->id);
|
||||
case PHASE_DATA_IN:
|
||||
zip_log("ZIP %i: PHASE_DATA_IN\n", dev->id);
|
||||
dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT);
|
||||
dev->phase = 2;
|
||||
zip_irq_raise(dev);
|
||||
return;
|
||||
case ZIP_PHASE_DATA_IN_DMA:
|
||||
zip_log("ZIP %i: ZIP_PHASE_DATA_IN_DMA\n", dev->id);
|
||||
case PHASE_DATA_IN_DMA:
|
||||
zip_log("ZIP %i: PHASE_DATA_IN_DMA\n", dev->id);
|
||||
ret = zip_write_to_dma(dev);
|
||||
|
||||
if ((ret == 1) || (dev->drv->bus_type == ZIP_BUS_SCSI)) {
|
||||
@@ -2581,8 +2506,8 @@ zip_phase_callback(zip_t *dev)
|
||||
zip_buf_free(dev);
|
||||
}
|
||||
return;
|
||||
case ZIP_PHASE_ERROR:
|
||||
zip_log("ZIP %i: ZIP_PHASE_ERROR\n", dev->id);
|
||||
case PHASE_ERROR:
|
||||
zip_log("ZIP %i: PHASE_ERROR\n", dev->id);
|
||||
dev->status = READY_STAT | ERR_STAT;
|
||||
dev->phase = 3;
|
||||
dev->packet_status = 0xFF;
|
||||
@@ -2593,23 +2518,19 @@ zip_phase_callback(zip_t *dev)
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
zip_read(uint8_t channel, int length)
|
||||
static uint32_t
|
||||
zip_packet_read(void *p, int length)
|
||||
{
|
||||
zip_t *dev;
|
||||
zip_t *dev = (zip_t *) p;
|
||||
|
||||
uint16_t *zipbufferw;
|
||||
uint32_t *zipbufferl;
|
||||
|
||||
uint8_t id = atapi_zip_drives[channel];
|
||||
|
||||
uint32_t temp = 0;
|
||||
|
||||
if (id > ZIP_NUM)
|
||||
if (!dev)
|
||||
return 0;
|
||||
|
||||
dev = zip[id];
|
||||
|
||||
zipbufferw = (uint16_t *) zipbufferb;
|
||||
zipbufferl = (uint32_t *) zipbufferb;
|
||||
|
||||
@@ -2639,39 +2560,29 @@ zip_read(uint8_t channel, int length)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dev->packet_status == ZIP_PHASE_DATA_IN) {
|
||||
zip_log("ZIP %i: Returning: %04X (buffer position: %05i, request position: %05i)\n",
|
||||
id, temp, (dev->pos - 2) & 0xffff, (dev->request_pos - 2) & 0xffff);
|
||||
if (dev->packet_status == PHASE_DATA_IN) {
|
||||
if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) {
|
||||
/* Time for a DRQ. */
|
||||
zip_log("ZIP %i: Issuing read callback\n", id);
|
||||
zip_pio_request(dev, 0);
|
||||
}
|
||||
return temp;
|
||||
} else {
|
||||
zip_log("ZIP %i: Returning: 0000 (buffer position: %05i, request position: %05i)\n",
|
||||
id, (dev->pos - 2) & 0xffff, (dev->request_pos - 2) & 0xffff);
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
zip_write(uint8_t channel, uint32_t val, int length)
|
||||
static void
|
||||
zip_packet_write(void *p, uint32_t val, int length)
|
||||
{
|
||||
zip_t *dev;
|
||||
zip_t *dev = (zip_t *) p;
|
||||
|
||||
uint16_t *zipbufferw;
|
||||
uint32_t *zipbufferl;
|
||||
|
||||
uint8_t id = atapi_zip_drives[channel];
|
||||
|
||||
if (id > ZIP_NUM)
|
||||
if (!dev)
|
||||
return;
|
||||
|
||||
dev = zip[id];
|
||||
|
||||
if (dev->packet_status == ZIP_PHASE_IDLE) {
|
||||
if (dev->packet_status == PHASE_IDLE) {
|
||||
if (!zipbufferb)
|
||||
zip_buf_alloc(dev, 12);
|
||||
}
|
||||
@@ -2702,19 +2613,19 @@ zip_write(uint8_t channel, uint32_t val, int length)
|
||||
return;
|
||||
}
|
||||
|
||||
if (dev->packet_status == ZIP_PHASE_DATA_OUT) {
|
||||
if (dev->packet_status == PHASE_DATA_OUT) {
|
||||
if ((dev->request_pos >= dev->max_transfer_len) || (dev->pos >= dev->packet_len)) {
|
||||
/* Time for a DRQ. */
|
||||
zip_pio_request(dev, 1);
|
||||
}
|
||||
return;
|
||||
} else if (dev->packet_status == ZIP_PHASE_IDLE) {
|
||||
} else if (dev->packet_status == PHASE_IDLE) {
|
||||
if (dev->pos >= 12) {
|
||||
dev->pos = 0;
|
||||
dev->status = BUSY_STAT;
|
||||
dev->packet_status = ZIP_PHASE_COMMAND;
|
||||
dev->packet_status = PHASE_COMMAND;
|
||||
timer_process();
|
||||
zip_phase_callback(dev);
|
||||
zip_callback((void *) dev);
|
||||
timer_update_outstanding();
|
||||
}
|
||||
return;
|
||||
@@ -2732,19 +2643,168 @@ zip_global_init(void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
zip_100_identify(ide_t *ide)
|
||||
{
|
||||
ide_padstr((char *) (ide->buffer + 23), "E.08", 8); /* Firmware */
|
||||
ide_padstr((char *) (ide->buffer + 27), "IOMEGA ZIP 100 ATAPI", 40); /* Model */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
zip_250_identify(ide_t *ide, int ide_has_dma)
|
||||
{
|
||||
ide_padstr((char *) (ide->buffer + 23), "42.S", 8); /* Firmware */
|
||||
ide_padstr((char *) (ide->buffer + 27), "IOMEGA ZIP 250 ATAPI", 40); /* Model */
|
||||
|
||||
if (ide_has_dma) {
|
||||
ide->buffer[80] = 0x30; /*Supported ATA versions : ATA/ATAPI-4 ATA/ATAPI-5*/
|
||||
ide->buffer[81] = 0x15; /*Maximum ATA revision supported : ATA/ATAPI-5 T13 1321D revision 1*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
zip_get_max(int ide_has_dma, int type)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch(type) {
|
||||
case TYPE_PIO:
|
||||
ret = ide_has_dma ? 3 : 0;
|
||||
break;
|
||||
case TYPE_SDMA:
|
||||
default:
|
||||
ret = -1;
|
||||
break;
|
||||
case TYPE_MDMA:
|
||||
ret = ide_has_dma ? -1 : 1;
|
||||
break;
|
||||
case TYPE_UDMA:
|
||||
ret = ide_has_dma ? -1 : 2;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
zip_get_timings(int ide_has_dma, int type)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch(type) {
|
||||
case TIMINGS_DMA:
|
||||
ret = ide_has_dma ? 0x96 : 0;
|
||||
break;
|
||||
case TIMINGS_PIO:
|
||||
ret = ide_has_dma ? 0xb4 : 0;
|
||||
break;
|
||||
case TIMINGS_PIO_FC:
|
||||
ret = ide_has_dma ? 0xb4 : 0;
|
||||
break;
|
||||
default:
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
zip_identify(void *p, int ide_has_dma)
|
||||
{
|
||||
ide_t *ide = (ide_t *) p;
|
||||
zip_t *zip;
|
||||
|
||||
zip = (zip_t *) ide->p;
|
||||
|
||||
/* Using (2<<5) below makes the ASUS P/I-P54TP4XE misdentify the ZIP drive
|
||||
as a LS-120. */
|
||||
ide->buffer[0] = 0x8000 | (0<<8) | 0x80 | (1<<5); /* ATAPI device, direct-access device, removable media, interrupt DRQ */
|
||||
ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */
|
||||
ide->buffer[49] = 0x200; /* LBA supported */
|
||||
ide->buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */
|
||||
|
||||
if (zip_drives[zip->id].is_250)
|
||||
zip_250_identify(ide, ide_has_dma);
|
||||
else
|
||||
zip_100_identify(ide);
|
||||
}
|
||||
|
||||
|
||||
static zip_t *
|
||||
zip_drive_reset(int c)
|
||||
{
|
||||
scsi_device_t *sd;
|
||||
ide_t *id;
|
||||
|
||||
if (!zip[c]) {
|
||||
zip[c] = (zip_t *) malloc(sizeof(zip_t));
|
||||
memset(zip[c], 0, sizeof(zip_t));
|
||||
}
|
||||
|
||||
zip[c]->id = c;
|
||||
|
||||
if (zip_drives[c].bus_type == ZIP_BUS_SCSI) {
|
||||
/* SCSI ZIP, attach to the SCSI bus. */
|
||||
sd = &scsi_devices[zip_drives[c].scsi_device_id];
|
||||
|
||||
sd->p = zip[c];
|
||||
sd->command = zip_command;
|
||||
sd->callback = zip_callback;
|
||||
sd->err_stat_to_scsi = zip_err_stat_to_scsi;
|
||||
sd->request_sense = zip_request_sense_for_scsi;
|
||||
sd->reset = zip_reset;
|
||||
sd->read_capacity = zip_read_capacity;
|
||||
sd->type = SCSI_REMOVABLE_DISK;
|
||||
} else if (zip_drives[c].bus_type == ZIP_BUS_ATAPI) {
|
||||
/* ATAPI CD-ROM, attach to the IDE bus. */
|
||||
id = ide_drives[zip_drives[c].ide_channel];
|
||||
/* If the IDE channel is initialized, we attach to it,
|
||||
otherwise, we do nothing - it's going to be a drive
|
||||
that's not attached to anything. */
|
||||
if (id) {
|
||||
id->p = zip[c];
|
||||
id->get_max = zip_get_max;
|
||||
id->get_timings = zip_get_timings;
|
||||
id->identify = zip_identify;
|
||||
id->set_signature = zip_set_signature;
|
||||
id->packet_write = zip_packet_write;
|
||||
id->packet_read = zip_packet_read;
|
||||
id->stop = NULL;
|
||||
id->packet_callback = zip_callback;
|
||||
id->device_reset = zip_reset;
|
||||
id->interrupt_drq = 1;
|
||||
|
||||
ide_atapi_attach(id);
|
||||
}
|
||||
}
|
||||
|
||||
return zip[c];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
zip_hard_reset(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < ZIP_NUM; c++) {
|
||||
if (zip_drives[c].bus_type) {
|
||||
if ((zip_drives[c].bus_type == ZIP_BUS_ATAPI) || (zip_drives[c].bus_type == ZIP_BUS_SCSI)) {
|
||||
zip_log("ZIP hard_reset drive=%d\n", c);
|
||||
|
||||
if (!zip[c]) {
|
||||
zip[c] = (zip_t *) malloc(sizeof(zip_t));
|
||||
memset(zip[c], 0, sizeof(zip_t));
|
||||
}
|
||||
/* Make sure to ignore any SCSI ZIP drive that has an out of range ID. */
|
||||
if ((zip_drives[c].bus_type == ZIP_BUS_SCSI) && (zip_drives[c].scsi_device_id > SCSI_ID_MAX))
|
||||
continue;
|
||||
|
||||
/* Make sure to ignore any ATAPI ZIP drive that has an out of range IDE channel. */
|
||||
if ((zip_drives[c].bus_type == ZIP_BUS_ATAPI) && (zip_drives[c].ide_channel > 7))
|
||||
continue;
|
||||
|
||||
zip[c] = zip_drive_reset(c);
|
||||
|
||||
zip[c]->id = c;
|
||||
zip[c]->drv = &zip_drives[c];
|
||||
@@ -2755,10 +2815,13 @@ zip_hard_reset(void)
|
||||
zip_load(zip[c], zip_drives[c].image_path);
|
||||
|
||||
zip_mode_sense_load(zip[c]);
|
||||
|
||||
if (zip_drives[c].bus_type == ZIP_BUS_SCSI)
|
||||
zip_log("SCSI ZIP drive %i attached to SCSI ID %i\n", c, zip_drives[c].scsi_device_id);
|
||||
else if (zip_drives[c].bus_type == ZIP_BUS_ATAPI)
|
||||
zip_log("ATAPI ZIP drive %i attached to IDE channel %i\n", c, zip_drives[c].ide_channel);
|
||||
}
|
||||
}
|
||||
|
||||
build_atapi_zip_map();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,15 +21,6 @@
|
||||
|
||||
#define ZIP_NUM 4
|
||||
|
||||
#define ZIP_PHASE_IDLE 0x00
|
||||
#define ZIP_PHASE_COMMAND 0x01
|
||||
#define ZIP_PHASE_COMPLETE 0x02
|
||||
#define ZIP_PHASE_DATA_IN 0x03
|
||||
#define ZIP_PHASE_DATA_IN_DMA 0x04
|
||||
#define ZIP_PHASE_DATA_OUT 0x05
|
||||
#define ZIP_PHASE_DATA_OUT_DMA 0x06
|
||||
#define ZIP_PHASE_ERROR 0x80
|
||||
|
||||
#define BUF_SIZE 32768
|
||||
|
||||
#define ZIP_TIME (5LL * 100LL * (1LL << TIMER_SHIFT))
|
||||
@@ -70,34 +61,30 @@ typedef struct {
|
||||
|
||||
zip_drive_t *drv;
|
||||
|
||||
uint8_t previous_command,
|
||||
error, features,
|
||||
status, phase,
|
||||
id, *buffer,
|
||||
uint8_t *buffer,
|
||||
atapi_cdb[16],
|
||||
current_cdb[16],
|
||||
sense[256];
|
||||
|
||||
uint8_t status, phase,
|
||||
error, id,
|
||||
features, pad0,
|
||||
pad1, pad2;
|
||||
|
||||
uint16_t request_length, max_transfer_len;
|
||||
|
||||
int toctimes, media_status,
|
||||
is_dma, requested_blocks,
|
||||
current_page_len, current_page_pos,
|
||||
total_length, written_length,
|
||||
mode_select_phase, do_page_save,
|
||||
callback, data_pos,
|
||||
packet_status, unit_attention,
|
||||
cdb_len_setting, cdb_len,
|
||||
request_pos, total_read,
|
||||
block_total, all_blocks_total,
|
||||
old_len, block_descriptor_len,
|
||||
init_length;
|
||||
int requested_blocks, packet_status,
|
||||
total_length, do_page_save,
|
||||
unit_attention;
|
||||
|
||||
uint32_t sector_pos, sector_len,
|
||||
packet_len, pos,
|
||||
seek_pos;
|
||||
packet_len, pos;
|
||||
|
||||
uint64_t current_page_code;
|
||||
int64_t callback;
|
||||
|
||||
int request_pos, old_len;
|
||||
|
||||
uint32_t seek_pos;
|
||||
} zip_t;
|
||||
|
||||
|
||||
@@ -121,29 +108,14 @@ extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_leng
|
||||
extern void (*ide_bus_master_set_irq)(int channel, void *priv);
|
||||
extern void *ide_bus_master_priv[2];
|
||||
|
||||
extern void build_atapi_zip_map(void);
|
||||
extern void build_scsi_zip_map(void);
|
||||
extern int zip_ZIP_PHASE_to_scsi(zip_t *dev);
|
||||
extern int zip_atapi_phase_to_scsi(zip_t *dev);
|
||||
extern void zip_command(zip_t *dev, uint8_t *cdb);
|
||||
extern void zip_phase_callback(zip_t *dev);
|
||||
extern uint32_t zip_read(uint8_t channel, int length);
|
||||
extern void zip_write(uint8_t channel, uint32_t val, int length);
|
||||
|
||||
extern void zip_disk_close(zip_t *dev);
|
||||
extern void zip_disk_reload(zip_t *dev);
|
||||
extern void zip_reset(zip_t *dev);
|
||||
extern void zip_set_signature(zip_t *dev);
|
||||
extern void zip_request_sense_for_scsi(zip_t *dev, uint8_t *buffer, uint8_t alloc_length);
|
||||
extern void zip_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks);
|
||||
extern void zip_insert(zip_t *dev);
|
||||
|
||||
extern int find_zip_for_scsi_id(uint8_t scsi_id);
|
||||
extern int zip_read_capacity(zip_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len);
|
||||
|
||||
extern void zip_global_init(void);
|
||||
extern void zip_hard_reset(void);
|
||||
|
||||
extern void zip_reset(void *p);
|
||||
extern int zip_load(zip_t *dev, wchar_t *fn);
|
||||
extern void zip_close();
|
||||
|
||||
|
||||
@@ -26,8 +26,9 @@
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include "86box.h"
|
||||
#include "scsi/scsi_device.h"
|
||||
#include "cdrom/cdrom.h"
|
||||
#include "scsi/scsi_device.h"
|
||||
#include "scsi/scsi_cdrom.h"
|
||||
#include "dma.h"
|
||||
#include "io.h"
|
||||
#include "device.h"
|
||||
@@ -825,7 +826,7 @@ piix_reset(void *p)
|
||||
|
||||
for (i = 0; i < CDROM_NUM; i++) {
|
||||
if (cdrom_drives[i].bus_type == CDROM_BUS_ATAPI)
|
||||
cdrom_reset(cdrom[i]);
|
||||
scsi_cdrom_reset(scsi_cdrom[i]);
|
||||
}
|
||||
for (i = 0; i < ZIP_NUM; i++) {
|
||||
if (zip_drives[i].bus_type == ZIP_BUS_ATAPI)
|
||||
|
||||
32
src/pc.c
32
src/pc.c
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Main emulator module where most things are controlled.
|
||||
*
|
||||
* Version: @(#)pc.c 1.0.80 2018/10/02
|
||||
* Version: @(#)pc.c 1.0.81 2018/10/10
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -665,14 +665,15 @@ again2:
|
||||
|
||||
hdc_init(hdc_name);
|
||||
|
||||
scsi_card_init();
|
||||
|
||||
/* These now come after as they now attach to the bus. */
|
||||
scsi_disk_hard_reset();
|
||||
|
||||
cdrom_hard_reset();
|
||||
|
||||
zip_hard_reset();
|
||||
|
||||
scsi_disk_hard_reset();
|
||||
|
||||
scsi_card_init();
|
||||
|
||||
pc_full_speed();
|
||||
shadowbios = 0;
|
||||
|
||||
@@ -736,6 +737,10 @@ pc_reset_hard_close(void)
|
||||
|
||||
cdrom_close();
|
||||
|
||||
zip_close();
|
||||
|
||||
scsi_disk_close();
|
||||
|
||||
closeal();
|
||||
}
|
||||
|
||||
@@ -766,15 +771,12 @@ pc_reset_hard_init(void)
|
||||
/* This is needed to initialize the serial timer. */
|
||||
serial_init();
|
||||
|
||||
cdrom_hard_reset();
|
||||
|
||||
zip_hard_reset();
|
||||
|
||||
scsi_disk_hard_reset();
|
||||
|
||||
/* Initialize the actual machine and its basic modules. */
|
||||
machine_init();
|
||||
|
||||
/* Reset and reconfigure the Sound Card layer. */
|
||||
sound_card_reset();
|
||||
|
||||
/* Reset any ISA memory cards. */
|
||||
isamem_reset();
|
||||
|
||||
@@ -811,8 +813,11 @@ pc_reset_hard_init(void)
|
||||
/* Reset and reconfigure the SCSI layer. */
|
||||
scsi_card_init();
|
||||
|
||||
/* Reset and reconfigure the Sound Card layer. */
|
||||
sound_card_reset();
|
||||
cdrom_hard_reset();
|
||||
|
||||
zip_hard_reset();
|
||||
|
||||
scsi_disk_hard_reset();
|
||||
|
||||
/* Reset and reconfigure the Network Card layer. */
|
||||
network_reset();
|
||||
@@ -917,6 +922,7 @@ pc_close(thread_t *ptr)
|
||||
network_close();
|
||||
|
||||
sound_cd_thread_end();
|
||||
|
||||
cdrom_close();
|
||||
|
||||
zip_close();
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Handling of the SCSI controllers.
|
||||
*
|
||||
* Version: @(#)scsi.c 1.0.21 2018/10/02
|
||||
* Version: @(#)scsi.c 1.0.22 2018/10/10
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -43,15 +43,9 @@
|
||||
#endif
|
||||
|
||||
|
||||
scsi_device_t SCSIDevices[SCSI_ID_MAX];
|
||||
char scsi_fn[SCSI_NUM][512];
|
||||
uint16_t scsi_disk_location[SCSI_NUM];
|
||||
|
||||
int scsi_card_current = 0;
|
||||
int scsi_card_last = 0;
|
||||
|
||||
uint32_t SCSI_BufferLength;
|
||||
|
||||
|
||||
typedef const struct {
|
||||
const char *name;
|
||||
@@ -83,26 +77,6 @@ static SCSI_CARD scsi_cards[] = {
|
||||
};
|
||||
|
||||
|
||||
#ifdef ENABLE_SCSI_LOG
|
||||
int scsi_do_log = ENABLE_SCSI_LOG;
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
scsi_log(const char *fmt, ...)
|
||||
{
|
||||
#ifdef ENABLE_SCSI_LOG
|
||||
va_list ap;
|
||||
|
||||
if (scsi_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int scsi_card_available(int card)
|
||||
{
|
||||
if (scsi_cards[card].device)
|
||||
@@ -159,25 +133,13 @@ void scsi_card_init(void)
|
||||
if (!scsi_cards[scsi_card_current].device)
|
||||
return;
|
||||
|
||||
scsi_log("Building SCSI hard disk map...\n");
|
||||
build_scsi_disk_map();
|
||||
scsi_log("Building SCSI CD-ROM map...\n");
|
||||
build_scsi_cdrom_map();
|
||||
scsi_log("Building SCSI ZIP map...\n");
|
||||
build_scsi_zip_map();
|
||||
for (i = 0; i < SCSI_ID_MAX; i++) {
|
||||
if (scsi_devices[i].cmd_buffer)
|
||||
free(scsi_devices[i].cmd_buffer);
|
||||
scsi_devices[i].cmd_buffer = NULL;
|
||||
|
||||
for (i=0; i<SCSI_ID_MAX; i++) {
|
||||
if (scsi_disks[i] != 0xff)
|
||||
SCSIDevices[i].LunType = SCSI_DISK;
|
||||
else if (scsi_cdrom_drives[i] != 0xff)
|
||||
SCSIDevices[i].LunType = SCSI_CDROM;
|
||||
else if (scsi_zip_drives[i] != 0xff)
|
||||
SCSIDevices[i].LunType = SCSI_ZIP;
|
||||
else
|
||||
SCSIDevices[i].LunType = SCSI_NONE;
|
||||
if (SCSIDevices[i].CmdBuffer)
|
||||
free(SCSIDevices[i].CmdBuffer);
|
||||
SCSIDevices[i].CmdBuffer = NULL;
|
||||
memset(&scsi_devices[i], 0, sizeof(scsi_device_t));
|
||||
scsi_devices[i].type = SCSI_NONE;
|
||||
}
|
||||
|
||||
device_add(scsi_cards[scsi_card_current].device);
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* 1 - BT-545S ISA;
|
||||
* 2 - BT-958D PCI
|
||||
*
|
||||
* Version: @(#)scsi_buslogic.c 1.0.39 2018/06/11
|
||||
* Version: @(#)scsi_buslogic.c 1.0.40 2018/10/09
|
||||
*
|
||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -556,6 +556,7 @@ BuslogicSCSIBIOSDMATransfer(ESCMD *ESCSICmd, uint8_t TargetID, int dir)
|
||||
int DataLength = ESCSICmd->DataLength;
|
||||
uint32_t Address;
|
||||
uint32_t TransferLength;
|
||||
scsi_device_t *dev = &scsi_devices[TargetID];
|
||||
|
||||
if (ESCSICmd->DataDirection == 0x03) {
|
||||
/* Non-data command. */
|
||||
@@ -567,16 +568,16 @@ BuslogicSCSIBIOSDMATransfer(ESCMD *ESCSICmd, uint8_t TargetID, int dir)
|
||||
|
||||
/* If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without
|
||||
checking its length, so do this procedure for both read/write commands. */
|
||||
if ((DataLength > 0) && (SCSIDevices[TargetID].BufferLength > 0)) {
|
||||
if ((DataLength > 0) && (dev->buffer_length > 0)) {
|
||||
Address = DataPointer;
|
||||
TransferLength = MIN(DataLength, SCSIDevices[TargetID].BufferLength);
|
||||
TransferLength = MIN(DataLength, dev->buffer_length);
|
||||
|
||||
if (dir && ((ESCSICmd->DataDirection == CCB_DATA_XFER_OUT) || (ESCSICmd->DataDirection == 0x00))) {
|
||||
buslogic_log("BusLogic BIOS DMA: Reading %i bytes from %08X\n", TransferLength, Address);
|
||||
DMAPageRead(Address, (uint8_t *)SCSIDevices[TargetID].CmdBuffer, TransferLength);
|
||||
DMAPageRead(Address, (uint8_t *)dev->cmd_buffer, TransferLength);
|
||||
} else if (!dir && ((ESCSICmd->DataDirection == CCB_DATA_XFER_IN) || (ESCSICmd->DataDirection == 0x00))) {
|
||||
buslogic_log("BusLogic BIOS DMA: Writing %i bytes at %08X\n", TransferLength, Address);
|
||||
DMAPageWrite(Address, (uint8_t *)SCSIDevices[TargetID].CmdBuffer, TransferLength);
|
||||
DMAPageWrite(Address, (uint8_t *)dev->cmd_buffer, TransferLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -591,6 +592,7 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u
|
||||
int target_cdb_len = 12;
|
||||
uint8_t target_id = 0;
|
||||
int phase;
|
||||
scsi_device_t *sd = &scsi_devices[ESCSICmd->TargetId];
|
||||
|
||||
DataInBuf[0] = DataInBuf[1] = 0;
|
||||
|
||||
@@ -602,9 +604,9 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u
|
||||
|
||||
buslogic_log("Scanning SCSI Target ID %i\n", ESCSICmd->TargetId);
|
||||
|
||||
SCSIDevices[ESCSICmd->TargetId].Status = SCSI_STATUS_OK;
|
||||
sd->status = SCSI_STATUS_OK;
|
||||
|
||||
if (!scsi_device_present(ESCSICmd->TargetId)) {
|
||||
if (!scsi_device_present(sd)) {
|
||||
buslogic_log("SCSI Target ID %i has no device attached\n", ESCSICmd->TargetId);
|
||||
DataInBuf[2] = CCB_SELECTION_TIMEOUT;
|
||||
DataInBuf[3] = SCSI_STATUS_OK;
|
||||
@@ -623,7 +625,7 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u
|
||||
|
||||
target_cdb_len = 12;
|
||||
|
||||
if (!scsi_device_valid(ESCSICmd->TargetId)) fatal("SCSI target on ID %02i has disappeared\n", ESCSICmd->TargetId);
|
||||
if (!scsi_device_valid(sd)) fatal("SCSI target on ID %02i has disappeared\n", ESCSICmd->TargetId);
|
||||
|
||||
buslogic_log("SCSI target command being executed on: SCSI ID %i, SCSI LUN %i, Target %i\n", ESCSICmd->TargetId, ESCSICmd->LogicalUnit, target_id);
|
||||
|
||||
@@ -639,26 +641,26 @@ BuslogicSCSIBIOSRequestSetup(x54x_t *dev, uint8_t *CmdBuf, uint8_t *DataInBuf, u
|
||||
memcpy(temp_cdb, ESCSICmd->CDB, target_cdb_len);
|
||||
}
|
||||
|
||||
SCSIDevices[ESCSICmd->TargetId].BufferLength = ESCSICmd->DataLength;
|
||||
scsi_device_command_phase0(ESCSICmd->TargetId, temp_cdb);
|
||||
sd->buffer_length = ESCSICmd->DataLength;
|
||||
scsi_device_command_phase0(sd, temp_cdb);
|
||||
|
||||
phase = SCSIDevices[ESCSICmd->TargetId].Phase;
|
||||
phase = sd->phase;
|
||||
if (phase != SCSI_PHASE_STATUS) {
|
||||
if (phase == SCSI_PHASE_DATA_IN)
|
||||
scsi_device_command_phase1(ESCSICmd->TargetId);
|
||||
scsi_device_command_phase1(sd);
|
||||
BuslogicSCSIBIOSDMATransfer(ESCSICmd, ESCSICmd->TargetId, (phase == SCSI_PHASE_DATA_OUT));
|
||||
if (phase == SCSI_PHASE_DATA_OUT)
|
||||
scsi_device_command_phase1(ESCSICmd->TargetId);
|
||||
scsi_device_command_phase1(sd);
|
||||
}
|
||||
|
||||
x54x_buf_free(ESCSICmd->TargetId);
|
||||
|
||||
buslogic_log("BIOS Request complete\n");
|
||||
|
||||
if (SCSIDevices[ESCSICmd->TargetId].Status == SCSI_STATUS_OK) {
|
||||
if (sd->status == SCSI_STATUS_OK) {
|
||||
DataInBuf[2] = CCB_COMPLETE;
|
||||
DataInBuf[3] = SCSI_STATUS_OK;
|
||||
} else if (SCSIDevices[ESCSICmd->TargetId].Status == SCSI_STATUS_CHECK_CONDITION) {
|
||||
} else if (scsi_devices[ESCSICmd->TargetId].status == SCSI_STATUS_CHECK_CONDITION) {
|
||||
DataInBuf[2] = CCB_COMPLETE;
|
||||
DataInBuf[3] = SCSI_STATUS_CHECK_CONDITION;
|
||||
}
|
||||
@@ -697,15 +699,15 @@ buslogic_cmds(void *p)
|
||||
case 0x23:
|
||||
memset(dev->DataBuf, 0, 8);
|
||||
for (i = 8; i < 15; i++) {
|
||||
dev->DataBuf[i-8] = 0;
|
||||
if (scsi_device_present(i) && (i != buslogic_get_host_id(dev)))
|
||||
dev->DataBuf[i-8] |= 1;
|
||||
dev->DataBuf[i - 8] = 0;
|
||||
if (scsi_device_present(&scsi_devices[i]) && (i != buslogic_get_host_id(dev)))
|
||||
dev->DataBuf[i - 8] |= 1;
|
||||
}
|
||||
dev->DataReplyLeft = 8;
|
||||
break;
|
||||
case 0x24:
|
||||
for (i=0; i<15; i++) {
|
||||
if (scsi_device_present(i) && (i != buslogic_get_host_id(dev)))
|
||||
for (i = 0; i < 15; i++) {
|
||||
if (scsi_device_present(&scsi_devices[i]) && (i != buslogic_get_host_id(dev)))
|
||||
TargetsPresentMask |= (1 << i);
|
||||
}
|
||||
dev->DataBuf[0] = TargetsPresentMask & 0xFF;
|
||||
|
||||
3091
src/scsi/scsi_cdrom.c
Normal file
3091
src/scsi/scsi_cdrom.c
Normal file
File diff suppressed because it is too large
Load Diff
75
src/scsi/scsi_cdrom.h
Normal file
75
src/scsi/scsi_cdrom.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the CD-ROM drive with SCSI(-like)
|
||||
* commands, for both ATAPI and SCSI usage.
|
||||
*
|
||||
* Version: @(#)scsi_cdrom.h 1.0.0 2018/10/09
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2018 Miran Grca.
|
||||
*/
|
||||
#ifndef EMU_SCSI_CDROM_H
|
||||
#define EMU_SCSI_CDROM_H
|
||||
|
||||
|
||||
#define CDROM_TIME (5LL * 100LL * (1LL << TIMER_SHIFT))
|
||||
|
||||
|
||||
#ifdef SCSI_DEVICE_H
|
||||
typedef struct {
|
||||
/* Common block. */
|
||||
mode_sense_pages_t ms_pages_saved;
|
||||
|
||||
cdrom_drive_t *drv;
|
||||
|
||||
uint8_t *buffer,
|
||||
atapi_cdb[16],
|
||||
current_cdb[16],
|
||||
sense[256];
|
||||
|
||||
uint8_t status, phase,
|
||||
error, id,
|
||||
features, pad0,
|
||||
pad1, pad2;
|
||||
|
||||
uint16_t request_length, max_transfer_len;
|
||||
|
||||
int requested_blocks, packet_status,
|
||||
total_length, do_page_save,
|
||||
unit_attention;
|
||||
|
||||
uint32_t sector_pos, sector_len,
|
||||
packet_len, pos;
|
||||
|
||||
int64_t callback;
|
||||
|
||||
int media_status, data_pos,
|
||||
request_pos, total_read,
|
||||
old_len;
|
||||
|
||||
uint8_t previous_command,
|
||||
pad3, pad4, pad5;
|
||||
} scsi_cdrom_t;
|
||||
#endif
|
||||
|
||||
|
||||
extern scsi_cdrom_t *scsi_cdrom[CDROM_NUM];
|
||||
|
||||
#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_drives[id].host_drive
|
||||
|
||||
|
||||
extern void scsi_cdrom_reset(void *p);
|
||||
|
||||
|
||||
#endif /*EMU_SCSI_CDROM_H*/
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* The generic SCSI device command handler.
|
||||
*
|
||||
* Version: @(#)scsi_device.c 1.0.17 2018/06/02
|
||||
* Version: @(#)scsi_device.c 1.0.18 2018/10/10
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -25,325 +25,153 @@
|
||||
#include "../disk/hdd.h"
|
||||
#include "scsi.h"
|
||||
#include "scsi_device.h"
|
||||
#include "../cdrom/cdrom.h"
|
||||
#include "../disk/zip.h"
|
||||
#include "scsi_disk.h"
|
||||
|
||||
|
||||
scsi_device_t scsi_devices[SCSI_ID_MAX];
|
||||
|
||||
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 };
|
||||
|
||||
|
||||
static uint8_t
|
||||
scsi_device_target_command(int lun_type, uint8_t id, uint8_t *cdb)
|
||||
scsi_device_target_command(scsi_device_t *dev, uint8_t *cdb)
|
||||
{
|
||||
switch(lun_type) {
|
||||
case SCSI_DISK:
|
||||
scsi_disk_command(scsi_disk[id], cdb);
|
||||
return scsi_disk_err_stat_to_scsi(scsi_disk[id]);
|
||||
case SCSI_CDROM:
|
||||
cdrom_command(cdrom[id], cdb);
|
||||
return cdrom_CDROM_PHASE_to_scsi(cdrom[id]);
|
||||
case SCSI_ZIP:
|
||||
zip_command(zip[id], cdb);
|
||||
return zip_ZIP_PHASE_to_scsi(zip[id]);
|
||||
default:
|
||||
return SCSI_STATUS_CHECK_CONDITION;
|
||||
}
|
||||
if (dev->command && dev->err_stat_to_scsi) {
|
||||
dev->command(dev->p, cdb);
|
||||
return dev->err_stat_to_scsi(dev->p);
|
||||
} else
|
||||
return SCSI_STATUS_CHECK_CONDITION;
|
||||
}
|
||||
|
||||
|
||||
static void scsi_device_target_phase_callback(int lun_type, uint8_t id)
|
||||
static void scsi_device_target_callback(scsi_device_t *dev)
|
||||
{
|
||||
switch(lun_type) {
|
||||
case SCSI_DISK:
|
||||
scsi_disk_callback(scsi_disk[id]);
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
cdrom_phase_callback(cdrom[id]);
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
zip_phase_callback(zip[id]);
|
||||
break;
|
||||
}
|
||||
if (dev->callback)
|
||||
dev->callback(dev->p);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static int scsi_device_target_err_stat_to_scsi(int lun_type, uint8_t id)
|
||||
static int scsi_device_target_err_stat_to_scsi(scsi_device_t *dev)
|
||||
{
|
||||
switch(lun_type) {
|
||||
case SCSI_DISK:
|
||||
return scsi_disk_err_stat_to_scsi(scsi_disk[id]);
|
||||
case SCSI_CDROM:
|
||||
return cdrom_CDROM_PHASE_to_scsi(cdrom[id]);
|
||||
case SCSI_ZIP:
|
||||
return zip_ZIP_PHASE_to_scsi(zip[id]);
|
||||
default:
|
||||
return SCSI_STATUS_CHECK_CONDITION;
|
||||
}
|
||||
if (dev->err_stat_to_scsi)
|
||||
return dev->err_stat_to_scsi(dev->p);
|
||||
else
|
||||
return SCSI_STATUS_CHECK_CONDITION;
|
||||
}
|
||||
|
||||
|
||||
int64_t scsi_device_get_callback(uint8_t scsi_id)
|
||||
int64_t scsi_device_get_callback(scsi_device_t *dev)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
scsi_device_data_t *sdd = (scsi_device_data_t *) dev->p;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
return scsi_disk[id]->callback;
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
return cdrom[id]->callback;
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
return zip[id]->callback;
|
||||
break;
|
||||
default:
|
||||
return -1LL;
|
||||
break;
|
||||
}
|
||||
if (sdd)
|
||||
return sdd->callback;
|
||||
else
|
||||
return -1LL;
|
||||
}
|
||||
|
||||
|
||||
uint8_t *scsi_device_sense(uint8_t scsi_id)
|
||||
uint8_t *scsi_device_sense(scsi_device_t *dev)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
scsi_device_data_t *sdd = (scsi_device_data_t *) dev->p;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
return scsi_disk[id]->sense;
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
return cdrom[id]->sense;
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
return zip[id]->sense;
|
||||
break;
|
||||
default:
|
||||
return scsi_null_device_sense;
|
||||
break;
|
||||
}
|
||||
if (sdd)
|
||||
return sdd->sense;
|
||||
else
|
||||
return scsi_null_device_sense;
|
||||
}
|
||||
|
||||
|
||||
void scsi_device_request_sense(uint8_t scsi_id, uint8_t *buffer, uint8_t alloc_length)
|
||||
void scsi_device_request_sense(scsi_device_t *dev, uint8_t *buffer, uint8_t alloc_length)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
scsi_disk_request_sense_for_scsi(scsi_disk[id], buffer, alloc_length);
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
cdrom_request_sense_for_scsi(cdrom[id], buffer, alloc_length);
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
zip_request_sense_for_scsi(zip[id], buffer, alloc_length);
|
||||
break;
|
||||
default:
|
||||
memcpy(buffer, scsi_null_device_sense, alloc_length);
|
||||
break;
|
||||
}
|
||||
if (dev->request_sense)
|
||||
dev->request_sense(dev, buffer, alloc_length);
|
||||
else
|
||||
memcpy(buffer, scsi_null_device_sense, alloc_length);
|
||||
}
|
||||
|
||||
|
||||
void scsi_device_reset(uint8_t scsi_id)
|
||||
void scsi_device_reset(scsi_device_t *dev)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
scsi_disk_reset(scsi_disk[id]);
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
cdrom_reset(cdrom[id]);
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
zip_reset(zip[id]);
|
||||
break;
|
||||
}
|
||||
if (dev->reset)
|
||||
dev->reset(dev->p);
|
||||
}
|
||||
|
||||
|
||||
void scsi_device_type_data(uint8_t scsi_id, uint8_t *type, uint8_t *rmb)
|
||||
void scsi_device_type_data(scsi_device_t *dev, uint8_t *type, uint8_t *rmb)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
*type = *rmb = 0x00;
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
*type = 0x05;
|
||||
*rmb = 0x80;
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
*type = 0x00;
|
||||
*rmb = 0x80;
|
||||
break;
|
||||
default:
|
||||
*type = *rmb = 0xff;
|
||||
break;
|
||||
}
|
||||
*rmb = dev->type >> 8;
|
||||
*type = dev->type & 0xff;
|
||||
}
|
||||
|
||||
|
||||
int scsi_device_read_capacity(uint8_t scsi_id, uint8_t *cdb, uint8_t *buffer, uint32_t *len)
|
||||
int scsi_device_read_capacity(scsi_device_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
return scsi_disk_read_capacity(scsi_disk[id], cdb, buffer, len);
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
return cdrom_read_capacity(cdrom[id], cdb, buffer, len);
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
return zip_read_capacity(zip[id], cdb, buffer, len);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
if (dev->read_capacity)
|
||||
return dev->read_capacity(dev->p, cdb, buffer, len);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int scsi_device_present(uint8_t scsi_id)
|
||||
int scsi_device_present(scsi_device_t *dev)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_NONE:
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
if (dev->type == SCSI_NONE)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int scsi_device_valid(uint8_t scsi_id)
|
||||
int scsi_device_valid(scsi_device_t *dev)
|
||||
{
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
uint8_t id = 0;
|
||||
|
||||
switch (lun_type)
|
||||
{
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
break;
|
||||
default:
|
||||
id = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return (id == 0xFF) ? 0 : 1;
|
||||
if (dev->p)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int scsi_device_cdb_length(uint8_t scsi_id)
|
||||
int scsi_device_cdb_length(scsi_device_t *dev)
|
||||
{
|
||||
/* Right now, it's 12 for all devices. */
|
||||
return 12;
|
||||
}
|
||||
|
||||
|
||||
void scsi_device_command_phase0(uint8_t scsi_id, uint8_t *cdb)
|
||||
void scsi_device_command_phase0(scsi_device_t *dev, uint8_t *cdb)
|
||||
{
|
||||
uint8_t id = 0;
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
switch (lun_type) {
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
break;
|
||||
default:
|
||||
id = 0;
|
||||
SCSIDevices[scsi_id].Phase = SCSI_PHASE_STATUS;
|
||||
SCSIDevices[scsi_id].Status = SCSI_STATUS_CHECK_CONDITION;
|
||||
return;
|
||||
if (!dev->p) {
|
||||
dev->phase = SCSI_PHASE_STATUS;
|
||||
dev->status = SCSI_STATUS_CHECK_CONDITION;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Finally, execute the SCSI command immediately and get the transfer length. */
|
||||
SCSIDevices[scsi_id].Phase = SCSI_PHASE_COMMAND;
|
||||
SCSIDevices[scsi_id].Status = scsi_device_target_command(lun_type, id, cdb);
|
||||
dev->phase = SCSI_PHASE_COMMAND;
|
||||
dev->status = scsi_device_target_command(dev, cdb);
|
||||
|
||||
if (SCSIDevices[scsi_id].Phase == SCSI_PHASE_STATUS) {
|
||||
if (dev->phase == SCSI_PHASE_STATUS) {
|
||||
/* Command completed (either OK or error) - call the phase callback to complete the command. */
|
||||
scsi_device_target_phase_callback(lun_type, id);
|
||||
scsi_device_target_callback(dev);
|
||||
}
|
||||
/* If the phase is DATA IN or DATA OUT, finish this here. */
|
||||
}
|
||||
|
||||
void scsi_device_command_phase1(uint8_t scsi_id)
|
||||
void scsi_device_command_phase1(scsi_device_t *dev)
|
||||
{
|
||||
uint8_t id = 0;
|
||||
uint8_t lun_type = SCSIDevices[scsi_id].LunType;
|
||||
|
||||
switch (lun_type) {
|
||||
case SCSI_DISK:
|
||||
id = scsi_disks[scsi_id];
|
||||
break;
|
||||
case SCSI_CDROM:
|
||||
id = scsi_cdrom_drives[scsi_id];
|
||||
break;
|
||||
case SCSI_ZIP:
|
||||
id = scsi_zip_drives[scsi_id];
|
||||
break;
|
||||
default:
|
||||
id = 0;
|
||||
return;
|
||||
}
|
||||
if (!dev->p)
|
||||
return;
|
||||
|
||||
/* Call the second phase. */
|
||||
scsi_device_target_phase_callback(lun_type, id);
|
||||
SCSIDevices[scsi_id].Status = scsi_device_target_err_stat_to_scsi(lun_type, id);
|
||||
scsi_device_target_callback(dev);
|
||||
dev->status = scsi_device_target_err_stat_to_scsi(dev);
|
||||
/* Command second phase complete - call the callback to complete the command. */
|
||||
scsi_device_target_phase_callback(lun_type, id);
|
||||
scsi_device_target_callback(dev);
|
||||
}
|
||||
|
||||
int32_t *scsi_device_get_buf_len(uint8_t scsi_id)
|
||||
int32_t *scsi_device_get_buf_len(scsi_device_t *dev)
|
||||
{
|
||||
return &SCSIDevices[scsi_id].BufferLength;
|
||||
return &dev->buffer_length;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the generic SCSI device command handler.
|
||||
*
|
||||
* Version: @(#)scsi_device.h 1.0.10 2018/10/07
|
||||
* Version: @(#)scsi_device.h 1.0.11 2018/10/09
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -250,6 +250,15 @@
|
||||
|
||||
#define BUS_IDLE (1 << 31)
|
||||
|
||||
#define PHASE_IDLE 0x00
|
||||
#define PHASE_COMMAND 0x01
|
||||
#define PHASE_COMPLETE 0x02
|
||||
#define PHASE_DATA_IN 0x03
|
||||
#define PHASE_DATA_IN_DMA 0x04
|
||||
#define PHASE_DATA_OUT 0x05
|
||||
#define PHASE_DATA_OUT_DMA 0x06
|
||||
#define PHASE_ERROR 0x80
|
||||
|
||||
#define SCSI_PHASE_DATA_OUT 0
|
||||
#define SCSI_PHASE_DATA_IN BUS_IO
|
||||
#define SCSI_PHASE_COMMAND BUS_CD
|
||||
@@ -264,28 +273,38 @@
|
||||
#define MODE_SELECT_PHASE_PAGE 4
|
||||
|
||||
|
||||
/* This is probably no longer needed. */
|
||||
#if 0
|
||||
typedef struct
|
||||
{
|
||||
int state;
|
||||
int new_state;
|
||||
int clear_req;
|
||||
uint32_t bus_in, bus_out;
|
||||
int dev_id;
|
||||
uint8_t command[20];
|
||||
|
||||
int command_pos;
|
||||
uint8_t command[20];
|
||||
int data_pos;
|
||||
|
||||
int change_state_delay;
|
||||
int new_req_delay;
|
||||
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 *CmdBuffer;
|
||||
int LunType;
|
||||
int32_t BufferLength;
|
||||
uint8_t Status;
|
||||
uint8_t Phase;
|
||||
uint8_t *cmd_buffer;
|
||||
|
||||
int32_t buffer_length;
|
||||
|
||||
uint8_t status, phase;
|
||||
uint16_t type;
|
||||
|
||||
void *p;
|
||||
|
||||
void (*command)(void *p, uint8_t *cdb);
|
||||
void (*callback)(void *p);
|
||||
int (*err_stat_to_scsi)(void *p);
|
||||
void (*request_sense)(void *p, uint8_t *buffer, uint8_t alloc_length);
|
||||
void (*reset)(void *p);
|
||||
int (*read_capacity)(void *p, uint8_t *cdb, uint8_t *buffer, uint32_t *len);
|
||||
} scsi_device_t;
|
||||
|
||||
#pragma pack(push,1)
|
||||
@@ -294,15 +313,43 @@ typedef struct {
|
||||
} mode_sense_pages_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
enum {
|
||||
SCSI_NONE = 0,
|
||||
SCSI_DISK,
|
||||
SCSI_CDROM,
|
||||
SCSI_ZIP
|
||||
};
|
||||
/* This is so we can access the common elements to all SCSI device structs
|
||||
without knowing the device type. */
|
||||
typedef struct {
|
||||
mode_sense_pages_t ms_pages_saved;
|
||||
|
||||
void *p;
|
||||
|
||||
extern scsi_device_t SCSIDevices[SCSI_ID_MAX];
|
||||
uint8_t *temp_buffer,
|
||||
pad[16], /* This is atapi_cdb in ATAPI-supporting devices,
|
||||
and pad in SCSI-only devices. */
|
||||
current_cdb[16],
|
||||
sense[256];
|
||||
|
||||
uint8_t status, phase,
|
||||
error, id,
|
||||
features, pad0,
|
||||
pad1, pad2;
|
||||
|
||||
uint16_t request_length, max_transfer_len;
|
||||
|
||||
int requested_blocks, packet_status,
|
||||
total_length, do_page_save,
|
||||
unit_attention;
|
||||
|
||||
uint32_t sector_pos, sector_len,
|
||||
packet_len, pos;
|
||||
|
||||
int64_t callback;
|
||||
} scsi_device_data_t;
|
||||
|
||||
/* These are based on the INQUIRY values. */
|
||||
#define SCSI_NONE 0x0060
|
||||
#define SCSI_FIXED_DISK 0x0000
|
||||
#define SCSI_REMOVABLE_DISK 0x8000
|
||||
#define SCSI_REMOVABLE_CDROM 0x8005
|
||||
|
||||
extern scsi_device_t scsi_devices[SCSI_ID_MAX];
|
||||
|
||||
|
||||
extern int cdrom_add_error_and_subchannel(uint8_t *b, int real_sector_type);
|
||||
@@ -312,20 +359,19 @@ extern int mode_select_init(uint8_t command, uint16_t pl_length, uint8_t do_save
|
||||
extern int mode_select_terminate(int force);
|
||||
extern int mode_select_write(uint8_t val);
|
||||
|
||||
extern uint8_t *scsi_device_sense(uint8_t id);
|
||||
extern void scsi_device_type_data(uint8_t id, uint8_t *type, uint8_t *rmb);
|
||||
extern int64_t scsi_device_get_callback(uint8_t scsi_id);
|
||||
extern void scsi_device_request_sense(uint8_t scsi_id, uint8_t *buffer,
|
||||
extern uint8_t *scsi_device_sense(scsi_device_t *dev);
|
||||
extern void scsi_device_type_data(scsi_device_t *dev, uint8_t *type, uint8_t *rmb);
|
||||
extern int64_t scsi_device_get_callback(scsi_device_t *dev);
|
||||
extern void scsi_device_request_sense(scsi_device_t *dev, uint8_t *buffer,
|
||||
uint8_t alloc_length);
|
||||
extern void scsi_device_reset(uint8_t scsi_id);
|
||||
extern int scsi_device_read_capacity(uint8_t id, uint8_t *cdb,
|
||||
extern void scsi_device_reset(scsi_device_t *dev);
|
||||
extern int scsi_device_read_capacity(scsi_device_t *dev, uint8_t *cdb,
|
||||
uint8_t *buffer, uint32_t *len);
|
||||
extern int scsi_device_present(uint8_t id);
|
||||
extern int scsi_device_valid(uint8_t id);
|
||||
extern int scsi_device_cdb_length(uint8_t id);
|
||||
extern void scsi_device_command(uint8_t id, int cdb_len, uint8_t *cdb);
|
||||
extern void scsi_device_command_phase0(uint8_t scsi_id, uint8_t *cdb);
|
||||
extern void scsi_device_command_phase1(uint8_t scsi_id);
|
||||
extern int32_t *scsi_device_get_buf_len(uint8_t scsi_id);
|
||||
extern int scsi_device_present(scsi_device_t *dev);
|
||||
extern int scsi_device_valid(scsi_device_t *dev);
|
||||
extern int scsi_device_cdb_length(scsi_device_t *dev);
|
||||
extern void scsi_device_command_phase0(scsi_device_t *dev, uint8_t *cdb);
|
||||
extern void scsi_device_command_phase1(scsi_device_t *dev);
|
||||
extern int32_t *scsi_device_get_buf_len(scsi_device_t *dev);
|
||||
|
||||
#endif /*SCSI_DEVICE_H*/
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "../plat.h"
|
||||
#include "../ui.h"
|
||||
#include "scsi_device.h"
|
||||
#include "../cdrom/cdrom.h"
|
||||
#include "scsi_disk.h"
|
||||
|
||||
|
||||
@@ -54,12 +53,8 @@
|
||||
#define scsi_disk_ascq dev->sense[13]
|
||||
|
||||
|
||||
scsi_disk_t *scsi_disk[HDD_NUM];
|
||||
|
||||
uint8_t scsi_disks[16] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||
};
|
||||
scsi_disk_t *scsi_disk[HDD_NUM] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
||||
|
||||
|
||||
/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */
|
||||
@@ -145,6 +140,9 @@ static const mode_sense_pages_t scsi_disk_mode_sense_pages_changeable =
|
||||
} };
|
||||
|
||||
|
||||
static void scsi_disk_callback(void *p);
|
||||
|
||||
|
||||
#ifdef ENABLE_SCSI_DISK_LOG
|
||||
int scsi_disk_do_log = ENABLE_SCSI_DISK_LOG;
|
||||
#endif
|
||||
@@ -166,9 +164,11 @@ scsi_disk_log(const char *fmt, ...)
|
||||
|
||||
|
||||
/* Translates ATAPI status (ERR_STAT flag) to SCSI status. */
|
||||
int
|
||||
scsi_disk_err_stat_to_scsi(scsi_disk_t *dev)
|
||||
static int
|
||||
scsi_disk_err_stat_to_scsi(void *p)
|
||||
{
|
||||
scsi_disk_t *dev = (scsi_disk_t *) p;
|
||||
|
||||
if (dev->status & ERR_STAT)
|
||||
return SCSI_STATUS_CHECK_CONDITION;
|
||||
else
|
||||
@@ -176,48 +176,6 @@ scsi_disk_err_stat_to_scsi(scsi_disk_t *dev)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
find_hdd_for_scsi_id(uint8_t scsi_id)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
for (i = 0; i < HDD_NUM; i++) {
|
||||
if (wcslen(hdd[i].fn) == 0)
|
||||
continue;
|
||||
if ((hdd[i].spt == 0) || (hdd[i].hpc == 0) || (hdd[i].tracks == 0))
|
||||
continue;
|
||||
if ((hdd[i].bus == HDD_BUS_SCSI) && (hdd[i].scsi_id == scsi_id))
|
||||
return i;
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
scsi_loadhd(int scsi_id, int id)
|
||||
{
|
||||
if (! hdd_image_load(id))
|
||||
scsi_disks[scsi_id] = 0xff;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
build_scsi_disk_map(void)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
memset(scsi_disks, 0xff, 16);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
scsi_disks[i] = find_hdd_for_scsi_id(i);
|
||||
if (scsi_disks[i] != 0xff) {
|
||||
if (wcslen(hdd[scsi_disks[i]].fn) > 0)
|
||||
scsi_loadhd(i, scsi_disks[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
scsi_disk_mode_sense_load(scsi_disk_t *dev)
|
||||
{
|
||||
@@ -256,9 +214,10 @@ scsi_disk_mode_sense_save(scsi_disk_t *dev)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
scsi_disk_read_capacity(scsi_disk_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len)
|
||||
static int
|
||||
scsi_disk_read_capacity(void *p, uint8_t *cdb, uint8_t *buffer, uint32_t *len)
|
||||
{
|
||||
scsi_disk_t *dev = (scsi_disk_t *) p;
|
||||
int size = 0;
|
||||
|
||||
size = hdd_image_get_last_sector(dev->id);
|
||||
@@ -296,14 +255,14 @@ scsi_disk_mode_sense_read(scsi_disk_t *dev, uint8_t page_control, uint8_t page,
|
||||
|
||||
|
||||
uint32_t
|
||||
scsi_disk_mode_sense(scsi_disk_t *dev, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t block_descriptor_len)
|
||||
scsi_disk_mode_sense(scsi_disk_t *dev, uint8_t *buf, uint32_t pos, uint8_t page, uint8_t block_descriptor_len)
|
||||
{
|
||||
uint8_t msplen, page_control = (type >> 6) & 3;
|
||||
uint8_t msplen, page_control = (page >> 6) & 3;
|
||||
|
||||
int i = 0, j = 0;
|
||||
int size = 0;
|
||||
|
||||
type &= 0x3f;
|
||||
page &= 0x3f;
|
||||
|
||||
size = hdd_image_get_last_sector(dev->id);
|
||||
|
||||
@@ -319,8 +278,8 @@ scsi_disk_mode_sense(scsi_disk_t *dev, uint8_t *buf, uint32_t pos, uint8_t type,
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x40; i++) {
|
||||
if ((type == GPMODE_ALL_PAGES) || (type == i)) {
|
||||
if (scsi_disk_mode_sense_page_flags & (1LL << dev->current_page_code)) {
|
||||
if ((page == GPMODE_ALL_PAGES) || (page == i)) {
|
||||
if (scsi_disk_mode_sense_page_flags & (1LL << (uint64_t) page)) {
|
||||
buf[pos++] = scsi_disk_mode_sense_read(dev, page_control, i, 0);
|
||||
msplen = scsi_disk_mode_sense_read(dev, page_control, i, 1);
|
||||
buf[pos++] = msplen;
|
||||
@@ -340,8 +299,8 @@ scsi_disk_command_common(scsi_disk_t *dev)
|
||||
{
|
||||
dev->status = BUSY_STAT;
|
||||
dev->phase = 1;
|
||||
if (dev->packet_status == CDROM_PHASE_COMPLETE) {
|
||||
scsi_disk_callback(dev);
|
||||
if (dev->packet_status == PHASE_COMPLETE) {
|
||||
scsi_disk_callback((void *) dev);
|
||||
dev->callback = 0LL;
|
||||
} else
|
||||
dev->callback = -1LL; /* Speed depends on SCSI controller */
|
||||
@@ -351,7 +310,7 @@ scsi_disk_command_common(scsi_disk_t *dev)
|
||||
static void
|
||||
scsi_disk_command_complete(scsi_disk_t *dev)
|
||||
{
|
||||
dev->packet_status = CDROM_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
scsi_disk_command_common(dev);
|
||||
}
|
||||
|
||||
@@ -359,7 +318,7 @@ scsi_disk_command_complete(scsi_disk_t *dev)
|
||||
static void
|
||||
scsi_disk_command_read_dma(scsi_disk_t *dev)
|
||||
{
|
||||
dev->packet_status = CDROM_PHASE_DATA_IN_DMA;
|
||||
dev->packet_status = PHASE_DATA_IN_DMA;
|
||||
scsi_disk_command_common(dev);
|
||||
}
|
||||
|
||||
@@ -367,7 +326,7 @@ scsi_disk_command_read_dma(scsi_disk_t *dev)
|
||||
static void
|
||||
scsi_disk_command_write_dma(scsi_disk_t *dev)
|
||||
{
|
||||
dev->packet_status = CDROM_PHASE_DATA_OUT_DMA;
|
||||
dev->packet_status = PHASE_DATA_OUT_DMA;
|
||||
scsi_disk_command_common(dev);
|
||||
}
|
||||
|
||||
@@ -407,7 +366,7 @@ scsi_disk_set_phase(scsi_disk_t *dev, uint8_t phase)
|
||||
if (dev->drv->bus != HDD_BUS_SCSI)
|
||||
return;
|
||||
|
||||
SCSIDevices[scsi_id].Phase = phase;
|
||||
scsi_devices[scsi_id].phase = phase;
|
||||
}
|
||||
|
||||
|
||||
@@ -533,9 +492,11 @@ scsi_disk_rezero(scsi_disk_t *dev)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
scsi_disk_reset(scsi_disk_t *dev)
|
||||
static void
|
||||
scsi_disk_reset(void *p)
|
||||
{
|
||||
scsi_disk_t *dev = (scsi_disk_t *) p;
|
||||
|
||||
scsi_disk_rezero(dev);
|
||||
dev->status = 0;
|
||||
dev->callback = 0;
|
||||
@@ -568,9 +529,11 @@ scsi_disk_request_sense(scsi_disk_t *dev, uint8_t *buffer, uint8_t alloc_length,
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
scsi_disk_request_sense_for_scsi(scsi_disk_t *dev, uint8_t *buffer, uint8_t alloc_length)
|
||||
static void
|
||||
scsi_disk_request_sense_for_scsi(void *p, uint8_t *buffer, uint8_t alloc_length)
|
||||
{
|
||||
scsi_disk_t *dev = (scsi_disk_t *) p;
|
||||
|
||||
scsi_disk_request_sense(dev, buffer, alloc_length, 0);
|
||||
}
|
||||
|
||||
@@ -588,9 +551,10 @@ scsi_disk_set_buf_len(scsi_disk_t *dev, int32_t *BufLen, int32_t *src_len)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb)
|
||||
static void
|
||||
scsi_disk_command(void *p, uint8_t *cdb)
|
||||
{
|
||||
scsi_disk_t *dev = (scsi_disk_t *) p;
|
||||
uint8_t *hdbufferb;
|
||||
int32_t *BufLen;
|
||||
int32_t len, max_len, alloc_length;
|
||||
@@ -602,8 +566,8 @@ scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb)
|
||||
char device_identify_ex[15] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 };
|
||||
int block_desc = 0;
|
||||
|
||||
hdbufferb = SCSIDevices[dev->drv->scsi_id].CmdBuffer;
|
||||
BufLen = &SCSIDevices[dev->drv->scsi_id].BufferLength;
|
||||
hdbufferb = scsi_devices[dev->drv->scsi_id].cmd_buffer;
|
||||
BufLen = &scsi_devices[dev->drv->scsi_id].buffer_length;
|
||||
|
||||
last_sector = hdd_image_get_last_sector(dev->id);
|
||||
|
||||
@@ -666,7 +630,7 @@ scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb)
|
||||
|
||||
if (!len) {
|
||||
scsi_disk_set_phase(dev, SCSI_PHASE_STATUS);
|
||||
dev->packet_status = CDROM_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->callback = 20 * SCSI_TIME;
|
||||
break;
|
||||
}
|
||||
@@ -715,7 +679,7 @@ scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb)
|
||||
if ((!dev->sector_len) || (*BufLen == 0)) {
|
||||
scsi_disk_set_phase(dev, SCSI_PHASE_STATUS);
|
||||
scsi_disk_log("SCSI HD %i: All done - callback set\n", dev);
|
||||
dev->packet_status = CDROM_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->callback = 20 * SCSI_TIME;
|
||||
break;
|
||||
}
|
||||
@@ -779,7 +743,7 @@ scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb)
|
||||
if ((!dev->sector_len) || (*BufLen == 0)) {
|
||||
scsi_disk_set_phase(dev, SCSI_PHASE_STATUS);
|
||||
scsi_disk_log("SCSI HD %i: All done - callback set\n", dev->id);
|
||||
dev->packet_status = CDROM_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->callback = 20 * SCSI_TIME;
|
||||
break;
|
||||
}
|
||||
@@ -817,7 +781,7 @@ scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb)
|
||||
if ((!dev->sector_len) || (*BufLen == 0)) {
|
||||
scsi_disk_set_phase(dev, SCSI_PHASE_STATUS);
|
||||
scsi_disk_log("SCSI HD %i: All done - callback set\n", dev->id);
|
||||
dev->packet_status = CDROM_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->callback = 20 * SCSI_TIME;
|
||||
break;
|
||||
}
|
||||
@@ -847,8 +811,6 @@ scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb)
|
||||
else
|
||||
len = (cdb[8] | (cdb[7] << 8));
|
||||
|
||||
dev->current_page_code = cdb[2] & 0x3F;
|
||||
|
||||
alloc_length = len;
|
||||
|
||||
dev->temp_buffer = (uint8_t *) malloc(65536);
|
||||
@@ -909,7 +871,7 @@ scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb)
|
||||
if ((!max_len) || (*BufLen == 0)) {
|
||||
scsi_disk_set_phase(dev, SCSI_PHASE_STATUS);
|
||||
/* scsi_disk_log("SCSI HD %i: All done - callback set\n", dev->id); */
|
||||
dev->packet_status = CDROM_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->callback = 20 * SCSI_TIME;
|
||||
break;
|
||||
}
|
||||
@@ -1055,8 +1017,8 @@ atapi_out:
|
||||
static void
|
||||
scsi_disk_phase_data_in(scsi_disk_t *dev)
|
||||
{
|
||||
uint8_t *hdbufferb = SCSIDevices[dev->drv->scsi_id].CmdBuffer;
|
||||
int32_t *BufLen = &SCSIDevices[dev->drv->scsi_id].BufferLength;
|
||||
uint8_t *hdbufferb = scsi_devices[dev->drv->scsi_id].cmd_buffer;
|
||||
int32_t *BufLen = &scsi_devices[dev->drv->scsi_id].buffer_length;
|
||||
|
||||
if (!*BufLen) {
|
||||
scsi_disk_log("scsi_disk_phase_data_in(): Buffer length is 0\n");
|
||||
@@ -1108,9 +1070,9 @@ scsi_disk_phase_data_in(scsi_disk_t *dev)
|
||||
static void
|
||||
scsi_disk_phase_data_out(scsi_disk_t *dev)
|
||||
{
|
||||
uint8_t *hdbufferb = SCSIDevices[dev->drv->scsi_id].CmdBuffer;
|
||||
uint8_t *hdbufferb = scsi_devices[dev->drv->scsi_id].cmd_buffer;
|
||||
int i;
|
||||
int32_t *BufLen = &SCSIDevices[dev->drv->scsi_id].BufferLength;
|
||||
int32_t *BufLen = &scsi_devices[dev->drv->scsi_id].buffer_length;
|
||||
uint32_t last_sector = hdd_image_get_last_sector(dev->id);
|
||||
uint32_t c, h, s, last_to_write = 0;
|
||||
uint16_t block_desc_len, pos;
|
||||
@@ -1232,36 +1194,38 @@ scsi_disk_phase_data_out(scsi_disk_t *dev)
|
||||
|
||||
|
||||
/* If the result is 1, issue an IRQ, otherwise not. */
|
||||
void
|
||||
scsi_disk_callback(scsi_disk_t *dev)
|
||||
static void
|
||||
scsi_disk_callback(void *p)
|
||||
{
|
||||
scsi_disk_t *dev = (scsi_disk_t *) p;
|
||||
|
||||
switch(dev->packet_status) {
|
||||
case CDROM_PHASE_IDLE:
|
||||
case PHASE_IDLE:
|
||||
scsi_disk_log("SCSI HD %i: PHASE_IDLE\n", dev->id);
|
||||
dev->phase = 1;
|
||||
dev->status = READY_STAT | DRQ_STAT | (dev->status & ERR_STAT);
|
||||
return;
|
||||
case CDROM_PHASE_COMPLETE:
|
||||
case PHASE_COMPLETE:
|
||||
scsi_disk_log("SCSI HD %i: PHASE_COMPLETE\n", dev->id);
|
||||
dev->status = READY_STAT;
|
||||
dev->phase = 3;
|
||||
dev->packet_status = 0xFF;
|
||||
return;
|
||||
case CDROM_PHASE_DATA_OUT_DMA:
|
||||
case PHASE_DATA_OUT_DMA:
|
||||
scsi_disk_log("SCSI HD %i: PHASE_DATA_OUT_DMA\n", dev->id);
|
||||
scsi_disk_phase_data_out(dev);
|
||||
dev->packet_status = CDROM_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->status = READY_STAT;
|
||||
dev->phase = 3;
|
||||
return;
|
||||
case CDROM_PHASE_DATA_IN_DMA:
|
||||
case PHASE_DATA_IN_DMA:
|
||||
scsi_disk_log("SCSI HD %i: PHASE_DATA_IN_DMA\n", dev->id);
|
||||
scsi_disk_phase_data_in(dev);
|
||||
dev->packet_status = CDROM_PHASE_COMPLETE;
|
||||
dev->packet_status = PHASE_COMPLETE;
|
||||
dev->status = READY_STAT;
|
||||
dev->phase = 3;
|
||||
return;
|
||||
case CDROM_PHASE_ERROR:
|
||||
case PHASE_ERROR:
|
||||
scsi_disk_log("SCSI HD %i: PHASE_ERROR\n", dev->id);
|
||||
dev->status = READY_STAT | ERR_STAT;
|
||||
dev->phase = 3;
|
||||
@@ -1283,20 +1247,47 @@ void
|
||||
scsi_disk_hard_reset(void)
|
||||
{
|
||||
int c;
|
||||
scsi_device_t *sd;
|
||||
|
||||
for (c = 0; c < HDD_NUM; c++) {
|
||||
if (hdd[c].bus == HDD_BUS_SCSI) {
|
||||
scsi_disk_log("SCSI disk hard_reset drive=%d\n", c);
|
||||
|
||||
/* Make sure to ignore any SCSI disk that has an out of range ID. */
|
||||
if (hdd[c].scsi_id > SCSI_ID_MAX)
|
||||
continue;
|
||||
|
||||
/* Make sure to ignore any SCSI disk whose image file name is empty. */
|
||||
if (wcslen(hdd[c].fn) == 0)
|
||||
continue;
|
||||
|
||||
/* Make sure to ignore any SCSI disk whose image fails to load. */
|
||||
if (! hdd_image_load(c))
|
||||
continue;
|
||||
|
||||
if (!scsi_disk[c]) {
|
||||
scsi_disk[c] = (scsi_disk_t *) malloc(sizeof(scsi_disk_t));
|
||||
memset(scsi_disk[c], 0, sizeof(scsi_disk_t));
|
||||
}
|
||||
|
||||
/* SCSI disk, attach to the SCSI bus. */
|
||||
sd = &scsi_devices[hdd[c].scsi_id];
|
||||
|
||||
sd->p = scsi_disk[c];
|
||||
sd->command = scsi_disk_command;
|
||||
sd->callback = scsi_disk_callback;
|
||||
sd->err_stat_to_scsi = scsi_disk_err_stat_to_scsi;
|
||||
sd->request_sense = scsi_disk_request_sense_for_scsi;
|
||||
sd->reset = scsi_disk_reset;
|
||||
sd->read_capacity = scsi_disk_read_capacity;
|
||||
sd->type = SCSI_FIXED_DISK;
|
||||
|
||||
scsi_disk[c]->id = c;
|
||||
scsi_disk[c]->drv = &hdd[c];
|
||||
|
||||
scsi_disk_mode_sense_load(scsi_disk[c]);
|
||||
|
||||
scsi_disk_log("SCSI disk %i attached to SCSI ID %i\n", c, hdd[c].scsi_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*
|
||||
* Emulation of SCSI fixed and removable disks.
|
||||
*
|
||||
* Version: @(#)scsi_disk.h 1.0.5 2018/06/02
|
||||
* Version: @(#)scsi_disk.h 1.0.6 2018/10/10
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2017,2018 Miran Grca.
|
||||
@@ -18,43 +18,33 @@ typedef struct {
|
||||
|
||||
hard_disk_t *drv;
|
||||
|
||||
/* Stuff for SCSI hard disks. */
|
||||
uint8_t status, phase,
|
||||
error, id,
|
||||
uint8_t *temp_buffer,
|
||||
pad[16], /* This is atapi_cdb in ATAPI-supporting devices,
|
||||
and pad in SCSI-only devices. */
|
||||
current_cdb[16],
|
||||
sense[256];
|
||||
|
||||
uint16_t request_length;
|
||||
uint8_t status, phase,
|
||||
error, id,
|
||||
pad0, pad1,
|
||||
pad2, pad3;
|
||||
|
||||
int requested_blocks, block_total,
|
||||
packet_status, callback,
|
||||
block_descriptor_len,
|
||||
total_length, do_page_save;
|
||||
uint16_t request_length, pad4;
|
||||
|
||||
int requested_blocks, packet_status,
|
||||
total_length, do_page_save,
|
||||
unit_attention;
|
||||
|
||||
uint32_t sector_pos, sector_len,
|
||||
packet_len;
|
||||
packet_len, pos;
|
||||
|
||||
uint64_t current_page_code;
|
||||
|
||||
uint8_t *temp_buffer;
|
||||
int64_t callback;
|
||||
} scsi_disk_t;
|
||||
|
||||
|
||||
extern scsi_disk_t *scsi_disk[HDD_NUM];
|
||||
extern uint8_t scsi_disks[16];
|
||||
|
||||
|
||||
extern void scsi_loadhd(int scsi_id, int id);
|
||||
extern void scsi_disk_global_init(void);
|
||||
extern void scsi_disk_hard_reset(void);
|
||||
extern void scsi_disk_close(void);
|
||||
|
||||
extern int scsi_disk_read_capacity(scsi_disk_t *dev, uint8_t *cdb, uint8_t *buffer, uint32_t *len);
|
||||
extern int scsi_disk_err_stat_to_scsi(scsi_disk_t *dev);
|
||||
extern int scsi_disk_phase_to_scsi(scsi_disk_t *dev);
|
||||
extern int find_hdd_for_scsi_id(uint8_t scsi_id);
|
||||
extern void build_scsi_disk_map(void);
|
||||
extern void scsi_disk_reset(scsi_disk_t *dev);
|
||||
extern void scsi_disk_request_sense_for_scsi(scsi_disk_t *dev, uint8_t *buffer, uint8_t alloc_length);
|
||||
extern void scsi_disk_command(scsi_disk_t *dev, uint8_t *cdb);
|
||||
extern void scsi_disk_callback(scsi_disk_t *dev);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Implementation of the NCR 5380 series of SCSI Host Adapters
|
||||
* made by NCR. These controllers were designed for the ISA bus.
|
||||
*
|
||||
* Version: @(#)scsi_ncr5380.c 1.0.20 2018/10/08
|
||||
* Version: @(#)scsi_ncr5380.c 1.0.22 2018/10/09
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* TheCollector1995, <mariogplayer@gmail.com>
|
||||
@@ -280,19 +280,19 @@ ncr_wait_process(ncr5380_t *ncr_dev)
|
||||
if (ncr->wait_data) {
|
||||
ncr->wait_data--;
|
||||
if (!ncr->wait_data) {
|
||||
dev = &SCSIDevices[ncr->target_id];
|
||||
dev = &scsi_devices[ncr->target_id];
|
||||
SET_BUS_STATE(ncr, ncr->new_phase);
|
||||
|
||||
if (ncr->new_phase == SCSI_PHASE_DATA_IN) {
|
||||
ncr_log("Data In bus phase\n");
|
||||
ncr->tx_data = dev->CmdBuffer[ncr->data_pos++];
|
||||
ncr->tx_data = dev->cmd_buffer[ncr->data_pos++];
|
||||
ncr->state = STATE_DATAIN;
|
||||
ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->tx_data) | BUS_DBP;
|
||||
} else if (ncr->new_phase == SCSI_PHASE_STATUS) {
|
||||
ncr_log("Status bus phase\n");
|
||||
ncr->cur_bus |= BUS_REQ;
|
||||
ncr->state = STATE_STATUS;
|
||||
ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(dev->Status) | BUS_DBP;
|
||||
ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(dev->status) | BUS_DBP;
|
||||
} else if (ncr->new_phase == SCSI_PHASE_MESSAGE_IN) {
|
||||
ncr_log("Message In bus phase\n");
|
||||
ncr->state = STATE_MESSAGEIN;
|
||||
@@ -799,7 +799,7 @@ scsiat_out(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
ncr5380_t *ncr_dev = (ncr5380_t *)priv;
|
||||
ncr_t *ncr = &ncr_dev->ncr;
|
||||
scsi_device_t *dev = &SCSIDevices[ncr->target_id];
|
||||
scsi_device_t *dev = &scsi_devices[ncr->target_id];
|
||||
|
||||
ncr_log("SCSI AT write=0x%03x, val=%02x\n", port, val);
|
||||
switch (port & 0x0f) {
|
||||
@@ -852,7 +852,7 @@ scsiat_out(uint16_t port, uint8_t val, void *priv)
|
||||
if (ncr->unk_08 & 0x01)
|
||||
{
|
||||
ncr_dev->block_count_loaded = 1;
|
||||
ncr_dev->block_count = dev->BufferLength / 128;
|
||||
ncr_dev->block_count = dev->buffer_length / 128;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -875,8 +875,8 @@ ncr_callback(void *priv)
|
||||
{
|
||||
ncr5380_t *ncr_dev = (ncr5380_t *)priv;
|
||||
ncr_t *ncr = &ncr_dev->ncr;
|
||||
scsi_device_t *dev = &SCSIDevices[ncr->target_id];
|
||||
int c = 0;
|
||||
scsi_device_t *dev = &scsi_devices[ncr->target_id];
|
||||
int req_len, c = 0;
|
||||
int64_t p;
|
||||
uint8_t temp, data;
|
||||
|
||||
@@ -887,7 +887,7 @@ ncr_callback(void *priv)
|
||||
if (((ncr->state == STATE_DATAIN) || (ncr->state == STATE_DATAOUT)) && (ncr->dma_mode != DMA_IDLE))
|
||||
ncr_dev->timer_period = (int64_t) ncr_dev->period;
|
||||
else
|
||||
ncr_dev->timer_period += 10LL * TIMER_USEC;
|
||||
ncr_dev->timer_period += 40LL * TIMER_USEC;
|
||||
|
||||
if (ncr->dma_mode == DMA_IDLE) {
|
||||
ncr->bus_host = get_bus_host(ncr);
|
||||
@@ -909,7 +909,7 @@ ncr_callback(void *priv)
|
||||
ncr_log("Select - target ID = %i\n", ncr->target_id);
|
||||
|
||||
/*Once the device has been found and selected, mark it as busy*/
|
||||
if ((ncr->target_id != -1) && scsi_device_present(ncr->target_id)) {
|
||||
if ((ncr->target_id != -1) && scsi_device_present(&scsi_devices[ncr->target_id])) {
|
||||
ncr->cur_bus |= BUS_BSY;
|
||||
ncr_log("Device found at ID %i\n", ncr->target_id);
|
||||
ncr_log("Current Bus BSY=%02x\n", ncr->cur_bus);
|
||||
@@ -943,35 +943,36 @@ ncr_callback(void *priv)
|
||||
/*Reset data position to default*/
|
||||
ncr->data_pos = 0;
|
||||
|
||||
dev = &SCSIDevices[ncr->target_id];
|
||||
dev = &scsi_devices[ncr->target_id];
|
||||
|
||||
ncr_log("SCSI Command 0x%02X for ID %d, status code=%02x\n", ncr->command[0], ncr->target_id, dev->Status);
|
||||
ncr_log("SCSI Command 0x%02X for ID %d, status code=%02x\n", ncr->command[0], ncr->target_id, dev->status);
|
||||
|
||||
dev->BufferLength = -1;
|
||||
dev->buffer_length = -1;
|
||||
|
||||
/*Now, execute the given SCSI command*/
|
||||
scsi_device_command_phase0(ncr->target_id, ncr->command);
|
||||
scsi_device_command_phase0(dev, ncr->command);
|
||||
|
||||
ncr_log("SCSI ID %i: Command %02X: Buffer Length %i, SCSI Phase %02X\n", ncr->target_id, ncr->command[0], dev->BufferLength, dev->Phase);
|
||||
ncr_log("SCSI ID %i: Command %02X: Buffer Length %i, SCSI Phase %02X\n", ncr->target_id, ncr->command[0], dev->buffer_length, dev->phase);
|
||||
|
||||
if (dev->Status != SCSI_STATUS_OK) {
|
||||
if (dev->status != SCSI_STATUS_OK) {
|
||||
ncr->new_phase = SCSI_PHASE_STATUS;
|
||||
ncr->wait_data = 4;
|
||||
return;
|
||||
}
|
||||
|
||||
/*If the SCSI phase is Data In or Data Out, allocate the SCSI buffer based on the transfer length of the command*/
|
||||
if (dev->BufferLength && (dev->Phase == SCSI_PHASE_DATA_IN || dev->Phase == SCSI_PHASE_DATA_OUT)) {
|
||||
dev->CmdBuffer = (uint8_t *) malloc(dev->BufferLength);
|
||||
if (dev->buffer_length && (dev->phase == SCSI_PHASE_DATA_IN || dev->phase == SCSI_PHASE_DATA_OUT)) {
|
||||
dev->cmd_buffer = (uint8_t *) malloc(dev->buffer_length);
|
||||
|
||||
p = scsi_device_get_callback(ncr->target_id);
|
||||
p = scsi_device_get_callback(dev);
|
||||
req_len = MIN(64, dev->buffer_length);
|
||||
if (p <= 0LL)
|
||||
ncr_dev->period = 0.2 * ((double) TIMER_USEC) * ((double) MIN(64, dev->BufferLength));
|
||||
ncr_dev->period = 0.2 * ((double) TIMER_USEC) * ((double) req_len);
|
||||
else
|
||||
ncr_dev->period = (p / ((double) dev->BufferLength)) * ((double) MIN(64, dev->BufferLength));
|
||||
ncr_dev->period = (p / ((double) dev->buffer_length)) * ((double) req_len);
|
||||
}
|
||||
|
||||
if (dev->Phase == SCSI_PHASE_DATA_OUT) {
|
||||
if (dev->phase == SCSI_PHASE_DATA_OUT) {
|
||||
/* Write direction commands have delayed execution - only execute them after the bus has gotten all the data from the host. */
|
||||
ncr_log("Next state is data out\n");
|
||||
ncr->new_phase = SCSI_PHASE_DATA_OUT;
|
||||
@@ -979,23 +980,23 @@ ncr_callback(void *priv)
|
||||
ncr->clear_req = 4;
|
||||
} else {
|
||||
/* Other command - execute immediately. */
|
||||
ncr->new_phase = dev->Phase;
|
||||
ncr->new_phase = dev->phase;
|
||||
|
||||
if (ncr->new_phase == SCSI_PHASE_DATA_IN)
|
||||
scsi_device_command_phase1(ncr->target_id);
|
||||
scsi_device_command_phase1(dev);
|
||||
|
||||
ncr->wait_data = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ncr->state == STATE_DATAIN) {
|
||||
dev = &SCSIDevices[ncr->target_id];
|
||||
dev = &scsi_devices[ncr->target_id];
|
||||
ncr_log("Data In ACK=%02x\n", ncr->bus_host & BUS_ACK);
|
||||
if (ncr->bus_host & BUS_ACK) {
|
||||
if (ncr->data_pos >= dev->BufferLength) {
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (ncr->data_pos >= dev->buffer_length) {
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
ncr->cur_bus &= ~BUS_REQ;
|
||||
@@ -1003,7 +1004,7 @@ ncr_callback(void *priv)
|
||||
ncr->wait_data = 4;
|
||||
ncr->wait_complete = 8;
|
||||
} else {
|
||||
ncr->tx_data = dev->CmdBuffer[ncr->data_pos++];
|
||||
ncr->tx_data = dev->cmd_buffer[ncr->data_pos++];
|
||||
ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->tx_data) | BUS_DBP | BUS_REQ;
|
||||
ncr->clear_req = 3;
|
||||
ncr->cur_bus &= ~BUS_REQ;
|
||||
@@ -1011,18 +1012,18 @@ ncr_callback(void *priv)
|
||||
}
|
||||
}
|
||||
} else if (ncr->state == STATE_DATAOUT) {
|
||||
dev = &SCSIDevices[ncr->target_id];
|
||||
dev = &scsi_devices[ncr->target_id];
|
||||
|
||||
ncr_log("Data Out ACK=%02x\n", ncr->bus_host & BUS_ACK);
|
||||
if (ncr->bus_host & BUS_ACK) {
|
||||
dev->CmdBuffer[ncr->data_pos++] = BUS_GETDATA(ncr->bus_host);
|
||||
dev->cmd_buffer[ncr->data_pos++] = BUS_GETDATA(ncr->bus_host);
|
||||
|
||||
if (ncr->data_pos >= dev->BufferLength) {
|
||||
scsi_device_command_phase1(ncr->target_id);
|
||||
if (ncr->data_pos >= dev->buffer_length) {
|
||||
scsi_device_command_phase1(dev);
|
||||
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
ncr->cur_bus &= ~BUS_REQ;
|
||||
@@ -1073,10 +1074,10 @@ ncr_callback(void *priv)
|
||||
temp = BUS_GETDATA(ncr->bus_host);
|
||||
ncr->bus_host = get_bus_host(ncr);
|
||||
|
||||
if (ncr->data_pos >= dev->BufferLength) {
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (ncr->data_pos >= dev->buffer_length) {
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
ncr->cur_bus &= ~BUS_REQ;
|
||||
@@ -1084,7 +1085,7 @@ ncr_callback(void *priv)
|
||||
ncr->wait_data = 4;
|
||||
ncr->wait_complete = 8;
|
||||
} else {
|
||||
ncr->tx_data = dev->CmdBuffer[ncr->data_pos++];
|
||||
ncr->tx_data = dev->cmd_buffer[ncr->data_pos++];
|
||||
ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->tx_data) | BUS_DBP | BUS_REQ;
|
||||
ncr->clear_req = 3;
|
||||
ncr->cur_bus &= ~BUS_REQ;
|
||||
@@ -1139,14 +1140,14 @@ ncr_callback(void *priv)
|
||||
ncr->bus_host = get_bus_host(ncr) & ~BUS_DATAMASK;
|
||||
ncr->bus_host |= BUS_SETDATA(data);
|
||||
|
||||
dev->CmdBuffer[ncr->data_pos++] = BUS_GETDATA(ncr->bus_host);
|
||||
dev->cmd_buffer[ncr->data_pos++] = BUS_GETDATA(ncr->bus_host);
|
||||
|
||||
if (ncr->data_pos >= dev->BufferLength) {
|
||||
scsi_device_command_phase1(ncr->target_id);
|
||||
if (ncr->data_pos >= dev->buffer_length) {
|
||||
scsi_device_command_phase1(dev);
|
||||
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
ncr->cur_bus &= ~BUS_REQ;
|
||||
@@ -1196,10 +1197,10 @@ ncr_callback(void *priv)
|
||||
temp = BUS_GETDATA(ncr->bus_host);
|
||||
ncr->bus_host = get_bus_host(ncr);
|
||||
|
||||
if (ncr->data_pos >= dev->BufferLength) {
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (ncr->data_pos >= dev->buffer_length) {
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
ncr->cur_bus &= ~BUS_REQ;
|
||||
@@ -1207,7 +1208,7 @@ ncr_callback(void *priv)
|
||||
ncr->wait_data = 4;
|
||||
ncr->wait_complete = 8;
|
||||
} else {
|
||||
ncr->tx_data = dev->CmdBuffer[ncr->data_pos++];
|
||||
ncr->tx_data = dev->cmd_buffer[ncr->data_pos++];
|
||||
ncr->cur_bus = (ncr->cur_bus & ~BUS_DATAMASK) | BUS_SETDATA(ncr->tx_data) | BUS_DBP | BUS_REQ;
|
||||
ncr->clear_req = 3;
|
||||
ncr->cur_bus &= ~BUS_REQ;
|
||||
@@ -1248,14 +1249,14 @@ ncr_callback(void *priv)
|
||||
ncr->bus_host = get_bus_host(ncr) & ~BUS_DATAMASK;
|
||||
ncr->bus_host |= BUS_SETDATA(data);
|
||||
|
||||
dev->CmdBuffer[ncr->data_pos++] = BUS_GETDATA(ncr->bus_host);
|
||||
dev->cmd_buffer[ncr->data_pos++] = BUS_GETDATA(ncr->bus_host);
|
||||
|
||||
if (ncr->data_pos >= dev->BufferLength) {
|
||||
scsi_device_command_phase1(ncr->target_id);
|
||||
if (ncr->data_pos >= dev->buffer_length) {
|
||||
scsi_device_command_phase1(dev);
|
||||
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
ncr->cur_bus &= ~BUS_REQ;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* NCR and later Symbios and LSI. This controller was designed
|
||||
* for the PCI bus.
|
||||
*
|
||||
* Version: @(#)scsi_ncr53c810.c 1.0.14 2018/05/28
|
||||
* Version: @(#)scsi_ncr53c810.c 1.0.15 2018/10/09
|
||||
*
|
||||
* Authors: Paul Brook (QEMU)
|
||||
* Artyom Tarasenko (QEMU)
|
||||
@@ -391,8 +391,10 @@ ncr53c810_soft_reset(ncr53c810_t *dev)
|
||||
dev->gpreg0 = 0;
|
||||
dev->sstop = 1;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
scsi_device_reset(i);
|
||||
/* This is *NOT* a wide SCSI controller, so do not touch
|
||||
SCSI devices with ID's >= 8. */
|
||||
for (i = 0; i < 8; i++)
|
||||
scsi_device_reset(&scsi_devices[i]);
|
||||
}
|
||||
|
||||
|
||||
@@ -595,11 +597,9 @@ ncr53c810_do_dma(ncr53c810_t *dev, int out, uint8_t id)
|
||||
uint32_t addr, tdbc;
|
||||
int count;
|
||||
|
||||
scsi_device_t *sd;
|
||||
scsi_device_t *sd = &scsi_devices[id];
|
||||
|
||||
sd = &SCSIDevices[id];
|
||||
|
||||
if ((!scsi_device_present(id))) {
|
||||
if ((!scsi_device_present(sd))) {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Device not present when attempting to do DMA\n", id, dev->current_lun, dev->last_command);
|
||||
return;
|
||||
}
|
||||
@@ -610,7 +610,7 @@ ncr53c810_do_dma(ncr53c810_t *dev, int out, uint8_t id)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Make sure count is never bigger than BufferLength. */
|
||||
/* Make sure count is never bigger than buffer_length. */
|
||||
count = tdbc = dev->dbc;
|
||||
if (count > dev->temp_buf_len)
|
||||
count = dev->temp_buf_len;
|
||||
@@ -622,13 +622,13 @@ ncr53c810_do_dma(ncr53c810_t *dev, int out, uint8_t id)
|
||||
dev->dbc -= count;
|
||||
|
||||
if (out)
|
||||
ncr53c810_read(dev, addr, sd->CmdBuffer+dev->buffer_pos, count);
|
||||
ncr53c810_read(dev, addr, sd->cmd_buffer + dev->buffer_pos, count);
|
||||
else {
|
||||
if (!dev->buffer_pos) {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: SCSI Command Phase 1 on PHASE_DI\n", id, dev->current_lun, dev->last_command);
|
||||
scsi_device_command_phase1(dev->current->tag);
|
||||
scsi_device_command_phase1(&scsi_devices[dev->current->tag]);
|
||||
}
|
||||
ncr53c810_write(dev, addr, sd->CmdBuffer+dev->buffer_pos, count);
|
||||
ncr53c810_write(dev, addr, sd->cmd_buffer + dev->buffer_pos, count);
|
||||
}
|
||||
|
||||
dev->temp_buf_len -= count;
|
||||
@@ -637,13 +637,13 @@ ncr53c810_do_dma(ncr53c810_t *dev, int out, uint8_t id)
|
||||
if (dev->temp_buf_len <= 0) {
|
||||
if (out) {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: SCSI Command Phase 1 on PHASE_DO\n", id, dev->current_lun, dev->last_command);
|
||||
scsi_device_command_phase1(id);
|
||||
scsi_device_command_phase1(&scsi_devices[id]);
|
||||
}
|
||||
if (sd->CmdBuffer != NULL) {
|
||||
free(sd->CmdBuffer);
|
||||
sd->CmdBuffer = NULL;
|
||||
if (sd->cmd_buffer != NULL) {
|
||||
free(sd->cmd_buffer);
|
||||
sd->cmd_buffer = NULL;
|
||||
}
|
||||
ncr53c810_command_complete(dev, sd->Status);
|
||||
ncr53c810_command_complete(dev, sd->status);
|
||||
} else {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Resume SCRIPTS\n", id, dev->current_lun, dev->last_command);
|
||||
dev->sstop = 0;
|
||||
@@ -683,8 +683,8 @@ ncr53c810_do_command(ncr53c810_t *dev, uint8_t id)
|
||||
dev->sfbr = buf[0];
|
||||
dev->command_complete = 0;
|
||||
|
||||
sd = &SCSIDevices[id];
|
||||
if (!scsi_device_present(id)) {
|
||||
sd = &scsi_devices[id];
|
||||
if (!scsi_device_present(sd)) {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: Bad Selection\n", id, dev->current_lun, buf[0]);
|
||||
ncr53c810_bad_selection(dev, id);
|
||||
return 0;
|
||||
@@ -693,46 +693,46 @@ ncr53c810_do_command(ncr53c810_t *dev, uint8_t id)
|
||||
dev->current = (ncr53c810_request*)malloc(sizeof(ncr53c810_request));
|
||||
dev->current->tag = id;
|
||||
|
||||
sd->BufferLength = -1;
|
||||
sd->buffer_length = -1;
|
||||
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: DBC=%i\n", id, dev->current_lun, buf[0], dev->dbc);
|
||||
dev->last_command = buf[0];
|
||||
|
||||
scsi_device_command_phase0(dev->current->tag, buf);
|
||||
scsi_device_command_phase0(&scsi_devices[dev->current->tag], buf);
|
||||
dev->hba_private = (void *)dev->current;
|
||||
|
||||
dev->waiting = 0;
|
||||
dev->buffer_pos = 0;
|
||||
|
||||
dev->temp_buf_len = sd->BufferLength;
|
||||
dev->temp_buf_len = sd->buffer_length;
|
||||
|
||||
if (sd->BufferLength > 0) {
|
||||
sd->CmdBuffer = (uint8_t *)malloc(sd->BufferLength);
|
||||
dev->current->dma_len = sd->BufferLength;
|
||||
if (sd->buffer_length > 0) {
|
||||
sd->cmd_buffer = (uint8_t *)malloc(sd->buffer_length);
|
||||
dev->current->dma_len = sd->buffer_length;
|
||||
}
|
||||
|
||||
if ((sd->Phase == SCSI_PHASE_DATA_IN) && (sd->BufferLength > 0)) {
|
||||
if ((sd->phase == SCSI_PHASE_DATA_IN) && (sd->buffer_length > 0)) {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DI\n", id, dev->current_lun, buf[0]);
|
||||
ncr53c810_set_phase(dev, PHASE_DI);
|
||||
p = scsi_device_get_callback(dev->current->tag);
|
||||
p = scsi_device_get_callback(&scsi_devices[dev->current->tag]);
|
||||
if (p <= 0LL) {
|
||||
period = ((double) sd->BufferLength) * 0.1 * ((double) TIMER_USEC); /* Fast SCSI: 10000000 bytes per second */
|
||||
period = ((double) sd->buffer_length) * 0.1 * ((double) TIMER_USEC); /* Fast SCSI: 10000000 bytes per second */
|
||||
dev->timer_period += (int64_t) period;
|
||||
} else
|
||||
dev->timer_period += p;
|
||||
return 1;
|
||||
} else if ((sd->Phase == SCSI_PHASE_DATA_OUT) && (sd->BufferLength > 0)) {
|
||||
} else if ((sd->phase == SCSI_PHASE_DATA_OUT) && (sd->buffer_length > 0)) {
|
||||
ncr53c810_log("(ID=%02i LUN=%02i) SCSI Command 0x%02x: PHASE_DO\n", id, buf[0]);
|
||||
ncr53c810_set_phase(dev, PHASE_DO);
|
||||
p = scsi_device_get_callback(dev->current->tag);
|
||||
p = scsi_device_get_callback(&scsi_devices[dev->current->tag]);
|
||||
if (p <= 0LL) {
|
||||
period = ((double) sd->BufferLength) * 0.1 * ((double) TIMER_USEC); /* Fast SCSI: 10000000 bytes per second */
|
||||
period = ((double) sd->buffer_length) * 0.1 * ((double) TIMER_USEC); /* Fast SCSI: 10000000 bytes per second */
|
||||
dev->timer_period += (int64_t) period;
|
||||
} else
|
||||
dev->timer_period += p;
|
||||
return 1;
|
||||
} else {
|
||||
ncr53c810_command_complete(dev, sd->Status);
|
||||
ncr53c810_command_complete(dev, sd->status);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -832,7 +832,7 @@ ncr53c810_do_msgout(ncr53c810_t *dev, uint8_t id)
|
||||
uint32_t current_tag;
|
||||
scsi_device_t *sd;
|
||||
|
||||
sd = &SCSIDevices[id];
|
||||
sd = &scsi_devices[id];
|
||||
|
||||
current_tag = id;
|
||||
|
||||
@@ -884,9 +884,9 @@ ncr53c810_do_msgout(ncr53c810_t *dev, uint8_t id)
|
||||
case 0x0d:
|
||||
/* The ABORT TAG message clears the current I/O process only. */
|
||||
ncr53c810_log("MSG: ABORT TAG tag=0x%x\n", current_tag);
|
||||
if (sd->CmdBuffer) {
|
||||
free(sd->CmdBuffer);
|
||||
sd->CmdBuffer = NULL;
|
||||
if (sd->cmd_buffer) {
|
||||
free(sd->cmd_buffer);
|
||||
sd->cmd_buffer = NULL;
|
||||
}
|
||||
ncr53c810_disconnect(dev);
|
||||
break;
|
||||
@@ -907,9 +907,9 @@ ncr53c810_do_msgout(ncr53c810_t *dev, uint8_t id)
|
||||
ncr53c810_log("MSG: BUS DEVICE RESET tag=0x%x\n", current_tag);
|
||||
|
||||
/* clear the current I/O process */
|
||||
if (sd->CmdBuffer) {
|
||||
free(sd->CmdBuffer);
|
||||
sd->CmdBuffer = NULL;
|
||||
if (sd->cmd_buffer) {
|
||||
free(sd->cmd_buffer);
|
||||
sd->cmd_buffer = NULL;
|
||||
}
|
||||
ncr53c810_disconnect(dev);
|
||||
break;
|
||||
@@ -1078,7 +1078,7 @@ again:
|
||||
}
|
||||
dev->sstat0 |= NCR_SSTAT0_WOA;
|
||||
dev->scntl1 &= ~NCR_SCNTL1_IARB;
|
||||
if (!scsi_device_present(id)) {
|
||||
if (!scsi_device_present(&scsi_devices[id])) {
|
||||
ncr53c810_bad_selection(dev, id);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* series of SCSI Host Adapters made by Mylex.
|
||||
* These controllers were designed for various buses.
|
||||
*
|
||||
* Version: @(#)scsi_x54x.c 1.0.22 2018/10/02
|
||||
* Version: @(#)scsi_x54x.c 1.0.23 2018/10/09
|
||||
*
|
||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -155,9 +155,8 @@ clear_irq(x54x_t *dev)
|
||||
static void
|
||||
target_check(uint8_t id)
|
||||
{
|
||||
if (! scsi_device_valid(id)) {
|
||||
if (! scsi_device_valid(&scsi_devices[id]))
|
||||
fatal("BIOS INT13 device on ID %02i has disappeared\n", id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -237,9 +236,10 @@ x54x_bios_command_08(uint8_t id, uint8_t *buffer)
|
||||
uint8_t rcbuf[8] = { 0,0,0,0,0,0,0,0 };
|
||||
uint32_t len = 0;
|
||||
int i, ret, sc;
|
||||
scsi_device_t *sd = &scsi_devices[id];
|
||||
|
||||
ret = scsi_device_read_capacity(id, cdb, rcbuf, &len);
|
||||
sc = completion_code(scsi_device_sense(id));
|
||||
ret = scsi_device_read_capacity(sd, cdb, rcbuf, &len);
|
||||
sc = completion_code(scsi_device_sense(sd));
|
||||
if (ret == 0) return(sc);
|
||||
|
||||
memset(buffer, 0x00, 6);
|
||||
@@ -261,15 +261,16 @@ x54x_bios_command_15(uint8_t id, uint8_t *buffer)
|
||||
uint8_t rcbuf[8] = { 0,0,0,0,0,0,0,0 };
|
||||
uint32_t len = 0;
|
||||
int i, ret, sc;
|
||||
scsi_device_t *sd = &scsi_devices[id];
|
||||
|
||||
ret = scsi_device_read_capacity(id, cdb, rcbuf, &len);
|
||||
sc = completion_code(scsi_device_sense(id));
|
||||
ret = scsi_device_read_capacity(sd, cdb, rcbuf, &len);
|
||||
sc = completion_code(scsi_device_sense(sd));
|
||||
|
||||
memset(buffer, 0x00, 6);
|
||||
for (i=0; i<4; i++)
|
||||
buffer[i] = (ret == 0) ? 0 : rcbuf[i];
|
||||
|
||||
scsi_device_type_data(id, &(buffer[4]), &(buffer[5]));
|
||||
scsi_device_type_data(sd, &(buffer[4]), &(buffer[5]));
|
||||
|
||||
x54x_log("BIOS Command 0x15: %02X %02X %02X %02X %02X %02X\n",
|
||||
buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);
|
||||
@@ -308,15 +309,15 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
||||
}
|
||||
|
||||
/* Get pointer to selected device. */
|
||||
dev = &SCSIDevices[cmd->id];
|
||||
dev->BufferLength = 0;
|
||||
dev = &scsi_devices[cmd->id];
|
||||
dev->buffer_length = 0;
|
||||
|
||||
if (! scsi_device_present(cmd->id)) {
|
||||
if (! scsi_device_present(dev)) {
|
||||
x54x_log("BIOS Target ID %i has no device attached\n", cmd->id);
|
||||
return(0x80);
|
||||
}
|
||||
|
||||
if ((dev->LunType == SCSI_CDROM) && !x54x->cdrom_boot) {
|
||||
if ((dev->type == SCSI_REMOVABLE_CDROM) && !x54x->cdrom_boot) {
|
||||
x54x_log("BIOS Target ID %i is CD-ROM on unsupported BIOS\n", cmd->id);
|
||||
return(0x80);
|
||||
}
|
||||
@@ -326,9 +327,9 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
||||
x54x_log("BIOS Data Buffer write: length %d, pointer 0x%04X\n",
|
||||
sector_len, dma_address);
|
||||
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
switch(cmd->command) {
|
||||
@@ -343,20 +344,20 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
||||
* length for SCSI sense, and no command-specific
|
||||
* indication is given.
|
||||
*/
|
||||
dev->BufferLength = 14;
|
||||
dev->CmdBuffer = (uint8_t *)malloc(14);
|
||||
memset(dev->CmdBuffer, 0x00, 14);
|
||||
dev->buffer_length = 14;
|
||||
dev->cmd_buffer = (uint8_t *)malloc(14);
|
||||
memset(dev->cmd_buffer, 0x00, 14);
|
||||
|
||||
if (sector_len > 0) {
|
||||
x54x_log("BIOS DMA: Reading 14 bytes at %08X\n",
|
||||
dma_address);
|
||||
DMAPageWrite(dma_address,
|
||||
scsi_device_sense(cmd->id), 14);
|
||||
scsi_device_sense(dev), 14);
|
||||
}
|
||||
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
return(0);
|
||||
@@ -364,7 +365,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
||||
case 0x02: /* Read Desired Sectors to Memory */
|
||||
target_check(cmd->id);
|
||||
|
||||
dev->BufferLength = -1;
|
||||
dev->buffer_length = -1;
|
||||
|
||||
cdb[0] = GPCMD_READ_10;
|
||||
cdb[1] = (cmd->lun & 7) << 5;
|
||||
@@ -378,33 +379,33 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
||||
x54x_log("BIOS CMD(READ, %08lx, %d)\n", lba, cmd->secount);
|
||||
#endif
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
scsi_device_command_phase0(dev, cdb);
|
||||
|
||||
if (dev->Phase == SCSI_PHASE_STATUS)
|
||||
if (dev->phase == SCSI_PHASE_STATUS)
|
||||
goto skip_read_phase1;
|
||||
|
||||
dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength);
|
||||
dev->cmd_buffer = (uint8_t *)malloc(dev->buffer_length);
|
||||
|
||||
scsi_device_command_phase1(cmd->id);
|
||||
scsi_device_command_phase1(dev);
|
||||
if (sector_len > 0) {
|
||||
x54x_log("BIOS DMA: Reading %i bytes at %08X\n",
|
||||
dev->BufferLength, dma_address);
|
||||
dev->buffer_length, dma_address);
|
||||
DMAPageWrite(dma_address,
|
||||
dev->CmdBuffer, dev->BufferLength);
|
||||
dev->cmd_buffer, dev->buffer_length);
|
||||
}
|
||||
|
||||
skip_read_phase1:
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
return(completion_code(scsi_device_sense(cmd->id)));
|
||||
return(completion_code(scsi_device_sense(dev)));
|
||||
|
||||
case 0x03: /* Write Desired Sectors from Memory */
|
||||
target_check(cmd->id);
|
||||
|
||||
dev->BufferLength = -1;
|
||||
dev->buffer_length = -1;
|
||||
|
||||
cdb[0] = GPCMD_WRITE_10;
|
||||
cdb[1] = (cmd->lun & 7) << 5;
|
||||
@@ -418,29 +419,29 @@ skip_read_phase1:
|
||||
x54x_log("BIOS CMD(WRITE, %08lx, %d)\n", lba, cmd->secount);
|
||||
#endif
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
scsi_device_command_phase0(dev, cdb);
|
||||
|
||||
if (dev->Phase == SCSI_PHASE_STATUS)
|
||||
if (dev->phase == SCSI_PHASE_STATUS)
|
||||
goto skip_write_phase1;
|
||||
|
||||
dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength);
|
||||
dev->cmd_buffer = (uint8_t *)malloc(dev->buffer_length);
|
||||
|
||||
if (sector_len > 0) {
|
||||
x54x_log("BIOS DMA: Reading %i bytes at %08X\n",
|
||||
dev->BufferLength, dma_address);
|
||||
dev->buffer_length, dma_address);
|
||||
DMAPageRead(dma_address,
|
||||
dev->CmdBuffer, dev->BufferLength);
|
||||
dev->cmd_buffer, dev->buffer_length);
|
||||
}
|
||||
|
||||
scsi_device_command_phase1(cmd->id);
|
||||
scsi_device_command_phase1(dev);
|
||||
|
||||
skip_write_phase1:
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
return(completion_code(scsi_device_sense(cmd->id)));
|
||||
return(completion_code(scsi_device_sense(dev)));
|
||||
|
||||
case 0x04: /* Verify Desired Sectors */
|
||||
target_check(cmd->id);
|
||||
@@ -454,9 +455,9 @@ skip_write_phase1:
|
||||
cdb[7] = 0;
|
||||
cdb[8] = sector_len;
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
scsi_device_command_phase0(dev, cdb);
|
||||
|
||||
return(completion_code(scsi_device_sense(cmd->id)));
|
||||
return(completion_code(scsi_device_sense(dev)));
|
||||
|
||||
case 0x05: /* Format Track, invalid since SCSI has no tracks */
|
||||
//FIXME: add a longer delay here --FvK
|
||||
@@ -472,26 +473,26 @@ skip_write_phase1:
|
||||
cdb[0] = GPCMD_FORMAT_UNIT;
|
||||
cdb[1] = (cmd->lun & 7) << 5;
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
scsi_device_command_phase0(dev, cdb);
|
||||
|
||||
return(completion_code(scsi_device_sense(cmd->id)));
|
||||
return(completion_code(scsi_device_sense(dev)));
|
||||
|
||||
case 0x08: /* Read Drive Parameters */
|
||||
target_check(cmd->id);
|
||||
|
||||
dev->BufferLength = 6;
|
||||
dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength);
|
||||
memset(dev->CmdBuffer, 0x00, dev->BufferLength);
|
||||
dev->buffer_length = 6;
|
||||
dev->cmd_buffer = (uint8_t *)malloc(dev->buffer_length);
|
||||
memset(dev->cmd_buffer, 0x00, dev->buffer_length);
|
||||
|
||||
ret = x54x_bios_command_08(cmd->id, dev->CmdBuffer);
|
||||
ret = x54x_bios_command_08(cmd->id, dev->cmd_buffer);
|
||||
|
||||
x54x_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address);
|
||||
DMAPageWrite(dma_address,
|
||||
dev->CmdBuffer, 4 /* dev->BufferLength */);
|
||||
dev->cmd_buffer, 4 /* dev->buffer_length */);
|
||||
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
@@ -510,9 +511,9 @@ skip_write_phase1:
|
||||
cdb[4] = (lba >> 8) & 0xff;
|
||||
cdb[5] = lba & 0xff;
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
scsi_device_command_phase0(dev, cdb);
|
||||
|
||||
return((dev->Status == SCSI_STATUS_OK) ? 1 : 0);
|
||||
return((dev->status == SCSI_STATUS_OK) ? 1 : 0);
|
||||
|
||||
case 0x0d: /* Alternate Disk Reset, in practice it's a nop */
|
||||
//FIXME: add a longer delay here --FvK
|
||||
@@ -524,9 +525,9 @@ skip_write_phase1:
|
||||
cdb[0] = GPCMD_TEST_UNIT_READY;
|
||||
cdb[1] = (cmd->lun & 7) << 5;
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
scsi_device_command_phase0(dev, cdb);
|
||||
|
||||
return(completion_code(scsi_device_sense(cmd->id)));
|
||||
return(completion_code(scsi_device_sense(dev)));
|
||||
|
||||
case 0x11: /* Recalibrate */
|
||||
target_check(cmd->id);
|
||||
@@ -534,9 +535,9 @@ skip_write_phase1:
|
||||
cdb[0] = GPCMD_REZERO_UNIT;
|
||||
cdb[1] = (cmd->lun & 7) << 5;
|
||||
|
||||
scsi_device_command_phase0(cmd->id, cdb);
|
||||
scsi_device_command_phase0(dev, cdb);
|
||||
|
||||
return(completion_code(scsi_device_sense(cmd->id)));
|
||||
return(completion_code(scsi_device_sense(dev)));
|
||||
|
||||
case 0x14: /* Controller Diagnostic */
|
||||
//FIXME: add a longer delay here --FvK
|
||||
@@ -545,19 +546,19 @@ skip_write_phase1:
|
||||
case 0x15: /* Read DASD Type */
|
||||
target_check(cmd->id);
|
||||
|
||||
dev->BufferLength = 6;
|
||||
dev->CmdBuffer = (uint8_t *)malloc(dev->BufferLength);
|
||||
memset(dev->CmdBuffer, 0x00, dev->BufferLength);
|
||||
dev->buffer_length = 6;
|
||||
dev->cmd_buffer = (uint8_t *)malloc(dev->buffer_length);
|
||||
memset(dev->cmd_buffer, 0x00, dev->buffer_length);
|
||||
|
||||
ret = x54x_bios_command_15(cmd->id, dev->CmdBuffer);
|
||||
ret = x54x_bios_command_15(cmd->id, dev->cmd_buffer);
|
||||
|
||||
x54x_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address);
|
||||
DMAPageWrite(dma_address,
|
||||
dev->CmdBuffer, 4 /* dev->BufferLength */);
|
||||
dev->cmd_buffer, 4 /* dev->buffer_length */);
|
||||
|
||||
if (dev->CmdBuffer != NULL) {
|
||||
free(dev->CmdBuffer);
|
||||
dev->CmdBuffer = NULL;
|
||||
if (dev->cmd_buffer != NULL) {
|
||||
free(dev->cmd_buffer);
|
||||
dev->cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
@@ -761,7 +762,7 @@ x54x_set_residue(Req_t *req, int32_t TransferLength)
|
||||
{
|
||||
uint32_t Residue = 0;
|
||||
addr24 Residue24;
|
||||
int32_t BufLen = SCSIDevices[req->TargetID].BufferLength;
|
||||
int32_t BufLen = scsi_devices[req->TargetID].buffer_length;
|
||||
|
||||
if ((req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) ||
|
||||
(req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) {
|
||||
@@ -792,7 +793,7 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir)
|
||||
uint32_t DataPointer, DataLength;
|
||||
uint32_t SGEntryLength = (Is24bit ? sizeof(SGE) : sizeof(SGE32));
|
||||
uint32_t Address, i;
|
||||
int32_t BufLen = SCSIDevices[req->TargetID].BufferLength;
|
||||
int32_t BufLen = scsi_devices[req->TargetID].buffer_length;
|
||||
uint8_t read_from_host = (dir && ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT) || (req->CmdBlock.common.ControlByte == 0x00)));
|
||||
uint8_t write_to_host = (!dir && ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_IN) || (req->CmdBlock.common.ControlByte == 0x00)));
|
||||
int sg_pos = 0;
|
||||
@@ -824,11 +825,11 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir)
|
||||
|
||||
if (read_from_host && DataToTransfer) {
|
||||
x54x_log("Reading S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address);
|
||||
DMAPageRead(Address, &(SCSIDevices[req->TargetID].CmdBuffer[sg_pos]), DataToTransfer);
|
||||
DMAPageRead(Address, &(scsi_devices[req->TargetID].cmd_buffer[sg_pos]), DataToTransfer);
|
||||
}
|
||||
else if (write_to_host && DataToTransfer) {
|
||||
x54x_log("Writing S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address);
|
||||
DMAPageWrite(Address, &(SCSIDevices[req->TargetID].CmdBuffer[sg_pos]), DataToTransfer);
|
||||
DMAPageWrite(Address, &(scsi_devices[req->TargetID].cmd_buffer[sg_pos]), DataToTransfer);
|
||||
}
|
||||
else
|
||||
x54x_log("No action on S/G segment %i: length %i, pointer %08X\n", i, DataToTransfer, Address);
|
||||
@@ -848,9 +849,9 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir)
|
||||
|
||||
if ((DataLength > 0) && (BufLen > 0) && (req->CmdBlock.common.ControlByte < 0x03)) {
|
||||
if (read_from_host)
|
||||
DMAPageRead(Address, SCSIDevices[req->TargetID].CmdBuffer, MIN(BufLen, (int) DataLength));
|
||||
DMAPageRead(Address, scsi_devices[req->TargetID].cmd_buffer, MIN(BufLen, (int) DataLength));
|
||||
else if (write_to_host)
|
||||
DMAPageWrite(Address, SCSIDevices[req->TargetID].CmdBuffer, MIN(BufLen, (int) DataLength));
|
||||
DMAPageWrite(Address, scsi_devices[req->TargetID].cmd_buffer, MIN(BufLen, (int) DataLength));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -860,23 +861,23 @@ x54x_buf_dma_transfer(Req_t *req, int Is24bit, int TransferLength, int dir)
|
||||
void
|
||||
x54x_buf_alloc(uint8_t id, int length)
|
||||
{
|
||||
if (SCSIDevices[id].CmdBuffer != NULL) {
|
||||
free(SCSIDevices[id].CmdBuffer);
|
||||
SCSIDevices[id].CmdBuffer = NULL;
|
||||
if (scsi_devices[id].cmd_buffer != NULL) {
|
||||
free(scsi_devices[id].cmd_buffer);
|
||||
scsi_devices[id].cmd_buffer = NULL;
|
||||
}
|
||||
|
||||
x54x_log("Allocating data buffer (%i bytes)\n", length);
|
||||
SCSIDevices[id].CmdBuffer = (uint8_t *) malloc(length);
|
||||
memset(SCSIDevices[id].CmdBuffer, 0, length);
|
||||
scsi_devices[id].cmd_buffer = (uint8_t *) malloc(length);
|
||||
memset(scsi_devices[id].cmd_buffer, 0, length);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
x54x_buf_free(uint8_t id)
|
||||
{
|
||||
if (SCSIDevices[id].CmdBuffer != NULL) {
|
||||
free(SCSIDevices[id].CmdBuffer);
|
||||
SCSIDevices[id].CmdBuffer = NULL;
|
||||
if (scsi_devices[id].cmd_buffer != NULL) {
|
||||
free(scsi_devices[id].cmd_buffer);
|
||||
scsi_devices[id].cmd_buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -920,7 +921,7 @@ SenseBufferFree(Req_t *req, int Copy)
|
||||
uint8_t temp_sense[256];
|
||||
|
||||
if (SenseLength && Copy) {
|
||||
scsi_device_request_sense(req->TargetID, temp_sense, SenseLength);
|
||||
scsi_device_request_sense(&scsi_devices[req->TargetID], temp_sense, SenseLength);
|
||||
|
||||
/*
|
||||
* The sense address, in 32-bit mode, is located in the
|
||||
@@ -945,24 +946,22 @@ static void
|
||||
x54x_scsi_cmd(x54x_t *dev)
|
||||
{
|
||||
Req_t *req = &dev->Req;
|
||||
uint8_t id, lun;
|
||||
uint8_t id, lun, phase, bit24 = !!req->Is24bit;
|
||||
uint8_t temp_cdb[12];
|
||||
uint32_t i;
|
||||
int target_cdb_len = 12;
|
||||
int target_data_len;
|
||||
uint8_t bit24 = !!req->Is24bit;
|
||||
uint32_t i, SenseBufferAddress;
|
||||
int target_data_len, target_cdb_len = 12;
|
||||
int32_t *BufLen;
|
||||
uint8_t phase;
|
||||
uint32_t SenseBufferAddress;
|
||||
int64_t p;
|
||||
scsi_device_t *sd;
|
||||
|
||||
id = req->TargetID;
|
||||
sd = &scsi_devices[id];
|
||||
lun = req->LUN;
|
||||
|
||||
target_cdb_len = 12;
|
||||
target_data_len = x54x_get_length(req, bit24);
|
||||
|
||||
if (!scsi_device_valid(id))
|
||||
if (!scsi_device_valid(sd))
|
||||
fatal("SCSI target on %02i has disappeared\n", id);
|
||||
|
||||
x54x_log("target_data_len = %i\n", target_data_len);
|
||||
@@ -985,14 +984,14 @@ x54x_scsi_cmd(x54x_t *dev)
|
||||
|
||||
dev->Residue = 0;
|
||||
|
||||
BufLen = scsi_device_get_buf_len(id);
|
||||
BufLen = scsi_device_get_buf_len(sd);
|
||||
*BufLen = target_data_len;
|
||||
|
||||
x54x_log("Command buffer: %08X\n", SCSIDevices[id].CmdBuffer);
|
||||
x54x_log("Command buffer: %08X\n", scsi_devices[id].cmd_buffer);
|
||||
|
||||
scsi_device_command_phase0(id, temp_cdb);
|
||||
scsi_device_command_phase0(sd, temp_cdb);
|
||||
|
||||
phase = SCSIDevices[id].Phase;
|
||||
phase = sd->phase;
|
||||
|
||||
x54x_log("Control byte: %02X\n", (req->CmdBlock.common.ControlByte == 0x03));
|
||||
|
||||
@@ -1001,14 +1000,14 @@ x54x_scsi_cmd(x54x_t *dev)
|
||||
/* Request sense in non-data mode - sense goes to sense buffer. */
|
||||
*BufLen = ConvertSenseLength(req->CmdBlock.common.RequestSenseLength);
|
||||
x54x_buf_alloc(id, *BufLen);
|
||||
scsi_device_command_phase1(id);
|
||||
if ((SCSIDevices[id].Status != SCSI_STATUS_OK) && (*BufLen > 0)) {
|
||||
scsi_device_command_phase1(sd);
|
||||
if ((sd->status != SCSI_STATUS_OK) && (*BufLen > 0)) {
|
||||
SenseBufferAddress = SenseBufferPointer(req);
|
||||
DMAPageWrite(SenseBufferAddress, SCSIDevices[id].CmdBuffer, *BufLen);
|
||||
DMAPageWrite(SenseBufferAddress, scsi_devices[id].cmd_buffer, *BufLen);
|
||||
x54x_add_to_period(*BufLen);
|
||||
}
|
||||
} else {
|
||||
p = scsi_device_get_callback(id);
|
||||
p = scsi_device_get_callback(sd);
|
||||
if (p <= 0LL)
|
||||
x54x_add_to_period(*BufLen);
|
||||
else
|
||||
@@ -1016,14 +1015,14 @@ x54x_scsi_cmd(x54x_t *dev)
|
||||
x54x_buf_alloc(id, MIN(target_data_len, *BufLen));
|
||||
if (phase == SCSI_PHASE_DATA_OUT)
|
||||
x54x_buf_dma_transfer(req, bit24, target_data_len, 1);
|
||||
scsi_device_command_phase1(id);
|
||||
scsi_device_command_phase1(sd);
|
||||
if (phase == SCSI_PHASE_DATA_IN)
|
||||
x54x_buf_dma_transfer(req, bit24, target_data_len, 0);
|
||||
|
||||
SenseBufferFree(req, (SCSIDevices[id].Status != SCSI_STATUS_OK));
|
||||
SenseBufferFree(req, (sd->status != SCSI_STATUS_OK));
|
||||
}
|
||||
} else
|
||||
SenseBufferFree(req, (SCSIDevices[id].Status != SCSI_STATUS_OK));
|
||||
SenseBufferFree(req, (sd->status != SCSI_STATUS_OK));
|
||||
|
||||
x54x_set_residue(req, target_data_len);
|
||||
|
||||
@@ -1031,15 +1030,15 @@ x54x_scsi_cmd(x54x_t *dev)
|
||||
|
||||
x54x_log("Request complete\n");
|
||||
|
||||
if (SCSIDevices[id].Status == SCSI_STATUS_OK) {
|
||||
if (sd->status == SCSI_STATUS_OK) {
|
||||
x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock,
|
||||
CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS);
|
||||
} else if (SCSIDevices[id].Status == SCSI_STATUS_CHECK_CONDITION) {
|
||||
} else if (sd->status == SCSI_STATUS_CHECK_CONDITION) {
|
||||
x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock,
|
||||
CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR);
|
||||
}
|
||||
|
||||
x54x_log("SCSIDevices[%02i].Status = %02X\n", id, SCSIDevices[id].Status);
|
||||
x54x_log("scsi_devices[%02i].Status = %02X\n", id, sd->status);
|
||||
}
|
||||
|
||||
|
||||
@@ -1058,6 +1057,7 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
|
||||
{
|
||||
Req_t *req = &dev->Req;
|
||||
uint8_t id, lun;
|
||||
scsi_device_t *sd;
|
||||
|
||||
/* Fetch data from the Command Control Block. */
|
||||
DMAPageRead(CCBPointer, (uint8_t *)&req->CmdBlock, sizeof(CCB32));
|
||||
@@ -1069,6 +1069,7 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
|
||||
req->LUN = dev->Mbx24bit ? req->CmdBlock.old.Lun : req->CmdBlock.new.Lun;
|
||||
|
||||
id = req->TargetID;
|
||||
sd = &scsi_devices[id];
|
||||
lun = req->LUN;
|
||||
if ((id > dev->max_id) || (lun > 7)) {
|
||||
x54x_log("SCSI Target ID %i or LUN %i is not valid\n",id,lun);
|
||||
@@ -1081,10 +1082,10 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
|
||||
|
||||
x54x_log("Scanning SCSI Target ID %i\n", id);
|
||||
|
||||
SCSIDevices[id].Status = SCSI_STATUS_OK;
|
||||
sd->status = SCSI_STATUS_OK;
|
||||
|
||||
/* If there is no device at ID:0, timeout the selection - the LUN is then checked later. */
|
||||
if (! scsi_device_present(id)) {
|
||||
if (! scsi_device_present(sd)) {
|
||||
x54x_log("SCSI Target ID %i and LUN %i have no device attached\n",id,lun);
|
||||
x54x_mbi_setup(dev, CCBPointer, &req->CmdBlock,
|
||||
CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR);
|
||||
@@ -1106,7 +1107,7 @@ x54x_req_setup(x54x_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
|
||||
}
|
||||
if (req->CmdBlock.common.Opcode == 0x81) {
|
||||
x54x_log("Bus reset opcode\n");
|
||||
scsi_device_reset(id);
|
||||
scsi_device_reset(sd);
|
||||
x54x_mbi_setup(dev, req->CCBPointer, &req->CmdBlock,
|
||||
CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS);
|
||||
x54x_log("%s: Callback: Send incoming mailbox\n", dev->name);
|
||||
@@ -1443,7 +1444,7 @@ x54x_reset(x54x_t *dev)
|
||||
|
||||
/* Reset all devices on controller reset. */
|
||||
for (i = 0; i < 16; i++)
|
||||
scsi_device_reset(i);
|
||||
scsi_device_reset(&scsi_devices[i]);
|
||||
|
||||
if (dev->ven_reset)
|
||||
dev->ven_reset(dev);
|
||||
@@ -1500,7 +1501,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
|
||||
if (val & CTRL_SCRST) {
|
||||
/* Reset all devices on SCSI bus reset. */
|
||||
for (i = 0; i < 16; i++)
|
||||
scsi_device_reset(i);
|
||||
scsi_device_reset(&scsi_devices[i]);
|
||||
}
|
||||
|
||||
if (val & CTRL_IRST) {
|
||||
@@ -1677,7 +1678,7 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
|
||||
if (i == host_id) continue;
|
||||
|
||||
/* TODO: Query device for LUN's. */
|
||||
if (scsi_device_present(i))
|
||||
if (scsi_device_present(&scsi_devices[i]))
|
||||
dev->DataBuf[i] |= 1;
|
||||
}
|
||||
dev->DataReplyLeft = i;
|
||||
@@ -1685,9 +1686,9 @@ x54x_out(uint16_t port, uint8_t val, void *priv)
|
||||
|
||||
case CMD_RETCONF: /* return Configuration */
|
||||
if (dev->ven_get_dma)
|
||||
dev->DataBuf[0] = (1<<dev->ven_get_dma(dev));
|
||||
dev->DataBuf[0] = (1 << dev->ven_get_dma(dev));
|
||||
else
|
||||
dev->DataBuf[0] = (1<<dev->DmaChannel);
|
||||
dev->DataBuf[0] = (1 << dev->DmaChannel);
|
||||
|
||||
if (dev->ven_get_irq)
|
||||
irq = dev->ven_get_irq(dev);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* MIDI device core module.
|
||||
*
|
||||
* Version: @(#)midi.c 1.0.0 2018/09/06
|
||||
* Version: @(#)midi.c 1.0.1 2018/10/10
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -179,6 +179,11 @@ midi_init(midi_device_t* device)
|
||||
void
|
||||
midi_close(void)
|
||||
{
|
||||
if (midi && midi->m_device) {
|
||||
free(midi->m_device);
|
||||
midi->m_device = NULL;
|
||||
}
|
||||
|
||||
if (midi) {
|
||||
free(midi);
|
||||
midi = NULL;
|
||||
|
||||
@@ -61,7 +61,6 @@ static int (*f_fluid_synth_sysex)(void *synth, const char *data, int len, char
|
||||
static int (*f_fluid_synth_pitch_bend)(void *synth, int chan, int val);
|
||||
static int (*f_fluid_synth_program_change)(void *synth, int chan, int program);
|
||||
static int (*f_fluid_synth_sfload)(void *synth, const char *filename, int reset_presets);
|
||||
static int (*f_fluid_synth_sfunload)(void *synth, unsigned int id, int reset_presets);
|
||||
static int (*f_fluid_synth_set_interp_method)(void *synth, int chan, int interp_method);
|
||||
static void (*f_fluid_synth_set_reverb)(void *synth, double roomsize, double damping, double width, double level);
|
||||
static void (*f_fluid_synth_set_reverb_on)(void *synth, int on);
|
||||
@@ -84,7 +83,6 @@ static dllimp_t fluidsynth_imports[] = {
|
||||
{ "fluid_synth_pitch_bend", &f_fluid_synth_pitch_bend },
|
||||
{ "fluid_synth_program_change", &f_fluid_synth_program_change },
|
||||
{ "fluid_synth_sfload", &f_fluid_synth_sfload },
|
||||
{ "fluid_synth_sfunload", &f_fluid_synth_sfunload },
|
||||
{ "fluid_synth_set_interp_method", &f_fluid_synth_set_interp_method },
|
||||
{ "fluid_synth_set_reverb", &f_fluid_synth_set_reverb },
|
||||
{ "fluid_synth_set_reverb_on", &f_fluid_synth_set_reverb_on },
|
||||
@@ -104,13 +102,14 @@ typedef struct fluidsynth
|
||||
int samplerate;
|
||||
int sound_font;
|
||||
|
||||
thread_t* thread_h;
|
||||
event_t* event;
|
||||
thread_t *thread_h;
|
||||
event_t *event, *start_event;
|
||||
int buf_size;
|
||||
float* buffer;
|
||||
int16_t* buffer_int16;
|
||||
int midi_pos;
|
||||
|
||||
int on;
|
||||
} fluidsynth_t;
|
||||
|
||||
fluidsynth_t fsdev;
|
||||
@@ -136,9 +135,14 @@ static void fluidsynth_thread(void *param)
|
||||
fluidsynth_t* data = (fluidsynth_t*)param;
|
||||
int buf_pos = 0;
|
||||
int buf_size = data->buf_size / BUFFER_SEGMENTS;
|
||||
while (1)
|
||||
|
||||
thread_set_event(data->start_event);
|
||||
|
||||
while (data->on)
|
||||
{
|
||||
thread_wait_event(data->event, -1);
|
||||
thread_reset_event(data->event);
|
||||
|
||||
if (sound_is_float)
|
||||
{
|
||||
float *buf = (float*)((uint8_t*)data->buffer + buf_pos);
|
||||
@@ -237,6 +241,8 @@ void fluidsynth_sysex(uint8_t* data, unsigned int len)
|
||||
void* fluidsynth_init(const device_t *info)
|
||||
{
|
||||
fluidsynth_t* data = &fsdev;
|
||||
midi_device_t* dev;
|
||||
|
||||
memset(data, 0, sizeof(fluidsynth_t));
|
||||
|
||||
/* Try loading the DLL. */
|
||||
@@ -324,12 +330,10 @@ void* fluidsynth_init(const device_t *info)
|
||||
data->buffer = NULL;
|
||||
data->buffer_int16 = malloc(data->buf_size);
|
||||
}
|
||||
data->event = thread_create_event();
|
||||
data->thread_h = thread_create(fluidsynth_thread, data);
|
||||
|
||||
al_set_midi(data->samplerate, data->buf_size);
|
||||
|
||||
midi_device_t* dev = malloc(sizeof(midi_device_t));
|
||||
dev = malloc(sizeof(midi_device_t));
|
||||
memset(dev, 0, sizeof(midi_device_t));
|
||||
|
||||
dev->play_msg = fluidsynth_msg;
|
||||
@@ -338,6 +342,16 @@ void* fluidsynth_init(const device_t *info)
|
||||
|
||||
midi_init(dev);
|
||||
|
||||
data->on = 1;
|
||||
|
||||
data->start_event = thread_create_event();
|
||||
|
||||
data->event = thread_create_event();
|
||||
data->thread_h = thread_create(fluidsynth_thread, data);
|
||||
|
||||
thread_wait_event(data->start_event, -1);
|
||||
thread_reset_event(data->start_event);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
@@ -347,10 +361,9 @@ void fluidsynth_close(void* p)
|
||||
|
||||
fluidsynth_t* data = &fsdev;
|
||||
|
||||
if (data->sound_font != -1) {
|
||||
f_fluid_synth_sfunload(data->synth, data->sound_font, 1);
|
||||
data->sound_font = -1;
|
||||
}
|
||||
data->on = 0;
|
||||
thread_set_event(data->event);
|
||||
thread_wait(data->thread_h, -1);
|
||||
|
||||
if (data->synth) {
|
||||
f_delete_fluid_synth(data->synth);
|
||||
@@ -362,8 +375,6 @@ void fluidsynth_close(void* p)
|
||||
data->settings = NULL;
|
||||
}
|
||||
|
||||
midi_close();
|
||||
|
||||
if (data->buffer)
|
||||
{
|
||||
free(data->buffer);
|
||||
|
||||
@@ -83,6 +83,8 @@ int cm32l_available()
|
||||
|
||||
static thread_t *thread_h = NULL;
|
||||
static event_t *event = NULL;
|
||||
static event_t *start_event = NULL;
|
||||
static int mt32_on = 0;
|
||||
|
||||
#define RENDER_RATE 100
|
||||
#define BUFFER_SEGMENTS 10
|
||||
@@ -119,13 +121,19 @@ static void mt32_thread(void *param)
|
||||
{
|
||||
int buf_pos = 0;
|
||||
int bsize = buf_size / BUFFER_SEGMENTS;
|
||||
while (1)
|
||||
float *buf;
|
||||
int16_t *buf16;
|
||||
|
||||
thread_set_event(start_event);
|
||||
|
||||
while (mt32_on)
|
||||
{
|
||||
thread_wait_event(event, -1);
|
||||
thread_reset_event(event);
|
||||
|
||||
if (sound_is_float)
|
||||
{
|
||||
float *buf = (float *) ((uint8_t*)buffer + buf_pos);
|
||||
buf = (float *) ((uint8_t*)buffer + buf_pos);
|
||||
memset(buf, 0, bsize);
|
||||
mt32_stream(buf, bsize / (2 * sizeof(float)));
|
||||
buf_pos += bsize;
|
||||
@@ -138,9 +146,9 @@ static void mt32_thread(void *param)
|
||||
}
|
||||
else
|
||||
{
|
||||
int16_t *buf = (int16_t *) ((uint8_t*)buffer_int16 + buf_pos);
|
||||
memset(buf, 0, bsize);
|
||||
mt32_stream_int16(buf, bsize / (2 * sizeof(int16_t)));
|
||||
buf16 = (int16_t *) ((uint8_t*)buffer_int16 + buf_pos);
|
||||
memset(buf16, 0, bsize);
|
||||
mt32_stream_int16(buf16, bsize / (2 * sizeof(int16_t)));
|
||||
buf_pos += bsize;
|
||||
if (buf_pos >= buf_size)
|
||||
{
|
||||
@@ -164,9 +172,12 @@ void mt32_sysex(uint8_t* data, unsigned int len)
|
||||
|
||||
void* mt32emu_init(wchar_t *control_rom, wchar_t *pcm_rom)
|
||||
{
|
||||
midi_device_t* dev;
|
||||
wchar_t s[512];
|
||||
char fn[512];
|
||||
|
||||
context = mt32emu_create_context(handler, NULL);
|
||||
|
||||
if (!rom_getfile(control_rom, s, 512)) return 0;
|
||||
wcstombs(fn, s, (wcslen(s) << 1) + 2);
|
||||
if (!mt32_check("mt32emu_add_rom_file", mt32emu_add_rom_file(context, fn), MT32EMU_RC_ADDED_CONTROL_ROM)) return 0;
|
||||
@@ -176,8 +187,6 @@ void* mt32emu_init(wchar_t *control_rom, wchar_t *pcm_rom)
|
||||
|
||||
if (!mt32_check("mt32emu_open_synth", mt32emu_open_synth(context), MT32EMU_RC_OK)) return 0;
|
||||
|
||||
event = thread_create_event();
|
||||
thread_h = thread_create(mt32_thread, 0);
|
||||
samplerate = mt32emu_get_actual_stereo_output_samplerate(context);
|
||||
/* buf_size = samplerate/RENDER_RATE*2; */
|
||||
if (sound_is_float)
|
||||
@@ -201,7 +210,7 @@ void* mt32emu_init(wchar_t *control_rom, wchar_t *pcm_rom)
|
||||
|
||||
al_set_midi(samplerate, buf_size);
|
||||
|
||||
midi_device_t* dev = malloc(sizeof(midi_device_t));
|
||||
dev = malloc(sizeof(midi_device_t));
|
||||
memset(dev, 0, sizeof(midi_device_t));
|
||||
|
||||
dev->play_msg = mt32_msg;
|
||||
@@ -210,6 +219,16 @@ void* mt32emu_init(wchar_t *control_rom, wchar_t *pcm_rom)
|
||||
|
||||
midi_init(dev);
|
||||
|
||||
mt32_on = 1;
|
||||
|
||||
start_event = thread_create_event();
|
||||
|
||||
event = thread_create_event();
|
||||
thread_h = thread_create(mt32_thread, 0);
|
||||
|
||||
thread_wait_event(start_event, -1);
|
||||
thread_reset_event(start_event);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
@@ -227,15 +246,15 @@ void mt32_close(void* p)
|
||||
{
|
||||
if (!p) return;
|
||||
|
||||
if (thread_h)
|
||||
thread_kill(thread_h);
|
||||
if (event)
|
||||
thread_destroy_event(event);
|
||||
mt32_on = 0;
|
||||
thread_set_event(event);
|
||||
thread_wait(thread_h, -1);
|
||||
|
||||
event = NULL;
|
||||
start_event = NULL;
|
||||
thread_h = NULL;
|
||||
|
||||
if (context)
|
||||
{
|
||||
if (context) {
|
||||
mt32emu_close_synth(context);
|
||||
mt32emu_free_context(context);
|
||||
}
|
||||
@@ -248,10 +267,6 @@ void mt32_close(void* p)
|
||||
if (buffer_int16)
|
||||
free(buffer_int16);
|
||||
buffer_int16 = NULL;
|
||||
|
||||
midi_close();
|
||||
|
||||
free((midi_device_t*)p);
|
||||
}
|
||||
|
||||
static const device_config_t mt32_config[] =
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Sound emulation core.
|
||||
*
|
||||
* Version: @(#)sound.c 1.0.20 2018/10/02
|
||||
* Version: @(#)sound.c 1.0.21 2018/10/09
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -26,7 +26,6 @@
|
||||
#include "../86box.h"
|
||||
#include "../device.h"
|
||||
#include "../timer.h"
|
||||
#include "../scsi/scsi_device.h"
|
||||
#include "../cdrom/cdrom.h"
|
||||
#include "../plat.h"
|
||||
#include "sound.h"
|
||||
@@ -188,68 +187,69 @@ void sound_set_cd_volume(unsigned int vol_l, unsigned int vol_r)
|
||||
|
||||
static void sound_cd_thread(void *param)
|
||||
{
|
||||
int i = 0;
|
||||
int c, has_audio, d, r, i = 0;
|
||||
int32_t audio_vol_l, audio_vol_r;
|
||||
|
||||
int channel_select[2];
|
||||
|
||||
float cd_buffer_temp[2] = {0.0, 0.0};
|
||||
float cd_buffer_temp2[2] = {0.0, 0.0};
|
||||
|
||||
int32_t cd_buffer_temp4[2] = {0, 0};
|
||||
|
||||
int c, has_audio;
|
||||
int d, r;
|
||||
|
||||
thread_set_event(sound_cd_start_event);
|
||||
|
||||
while (cdaudioon)
|
||||
{
|
||||
while (cdaudioon) {
|
||||
thread_wait_event(sound_cd_event, -1);
|
||||
thread_reset_event(sound_cd_event);
|
||||
|
||||
if (!soundon || !cdaudioon)
|
||||
return;
|
||||
for (c = 0; c < CD_BUFLEN*2; c += 2)
|
||||
{
|
||||
if (sound_is_float)
|
||||
{
|
||||
|
||||
for (c = 0; c < CD_BUFLEN*2; c += 2) {
|
||||
if (sound_is_float) {
|
||||
cd_out_buffer[c] = 0.0;
|
||||
cd_out_buffer[c+1] = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
cd_out_buffer_int16[c] = 0;
|
||||
cd_out_buffer_int16[c+1] = 0;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < CDROM_NUM; i++)
|
||||
{
|
||||
|
||||
for (i = 0; i < CDROM_NUM; i++) {
|
||||
has_audio = 0;
|
||||
if ((cdrom_drives[i].bus_type == CDROM_BUS_DISABLED) || !cdrom[i] || !cdrom[i]->handler)
|
||||
if ((cdrom_drives[i].bus_type == CDROM_BUS_DISABLED) || !cdrom_drives[i].handler)
|
||||
continue;
|
||||
if (cdrom[i]->handler->audio_callback)
|
||||
if (cdrom_drives[i].handler->audio_callback)
|
||||
{
|
||||
r = cdrom[i]->handler->audio_callback(i, cd_buffer[i], CD_BUFLEN*2);
|
||||
r = cdrom_drives[i].handler->audio_callback(i, cd_buffer[i], CD_BUFLEN*2);
|
||||
has_audio = (cdrom_drives[i].bus_type && cdrom_drives[i].sound_on/* && r*/);
|
||||
} else
|
||||
continue;
|
||||
if (soundon && has_audio)
|
||||
{
|
||||
int32_t audio_vol_l = cdrom_mode_sense_get_volume(cdrom[i], 0);
|
||||
int32_t audio_vol_r = cdrom_mode_sense_get_volume(cdrom[i], 1);
|
||||
int channel_select[2];
|
||||
|
||||
channel_select[0] = cdrom_mode_sense_get_channel(cdrom[i], 0);
|
||||
channel_select[1] = cdrom_mode_sense_get_channel(cdrom[i], 1);
|
||||
if (soundon && has_audio) {
|
||||
if (cdrom_drives[i].get_volume) {
|
||||
audio_vol_l = cdrom_drives[i].get_volume(cdrom_drives[i].p, 0);
|
||||
audio_vol_r = cdrom_drives[i].get_volume(cdrom_drives[i].p, 1);
|
||||
} else {
|
||||
audio_vol_l = 255;
|
||||
audio_vol_r = 255;
|
||||
}
|
||||
|
||||
if (!r)
|
||||
{
|
||||
for (c = 0; c < CD_BUFLEN*2; c += 2)
|
||||
{
|
||||
if (sound_is_float)
|
||||
{
|
||||
if (cdrom_drives[i].get_channel) {
|
||||
channel_select[0] = cdrom_drives[i].get_channel(cdrom_drives[i].p, 0);
|
||||
channel_select[1] = cdrom_drives[i].get_channel(cdrom_drives[i].p, 1);
|
||||
} else {
|
||||
channel_select[0] = 1;
|
||||
channel_select[1] = 2;
|
||||
}
|
||||
|
||||
if (!r) {
|
||||
for (c = 0; c < CD_BUFLEN*2; c += 2) {
|
||||
if (sound_is_float) {
|
||||
cd_out_buffer[c] += 0.0;
|
||||
cd_out_buffer[c+1] += 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
cd_out_buffer_int16[c] += 0;
|
||||
cd_out_buffer_int16[c+1] += 0;
|
||||
}
|
||||
@@ -257,8 +257,7 @@ static void sound_cd_thread(void *param)
|
||||
continue;
|
||||
}
|
||||
|
||||
for (c = 0; c < CD_BUFLEN*2; c += 2)
|
||||
{
|
||||
for (c = 0; c < CD_BUFLEN*2; c += 2) {
|
||||
/* First, transfer the CD audio data to the temporary buffer. */
|
||||
cd_buffer_temp[0] = (float) cd_buffer[i][c];
|
||||
cd_buffer_temp[1] = (float) cd_buffer[i][c+1];
|
||||
@@ -271,25 +270,17 @@ static void sound_cd_thread(void *param)
|
||||
|
||||
/*Apply ATAPI channel select*/
|
||||
cd_buffer_temp2[0] = cd_buffer_temp2[1] = 0.0;
|
||||
if (channel_select[0] & 1)
|
||||
{
|
||||
cd_buffer_temp2[0] += cd_buffer_temp[0];
|
||||
}
|
||||
if (channel_select[0] & 2)
|
||||
{
|
||||
cd_buffer_temp2[1] += cd_buffer_temp[0];
|
||||
}
|
||||
if (channel_select[1] & 1)
|
||||
{
|
||||
cd_buffer_temp2[0] += cd_buffer_temp[1];
|
||||
}
|
||||
if (channel_select[1] & 2)
|
||||
{
|
||||
cd_buffer_temp2[1] += cd_buffer_temp[1];
|
||||
}
|
||||
|
||||
if (sound_process_handlers_num)
|
||||
{
|
||||
if (channel_select[0] & 1)
|
||||
cd_buffer_temp2[0] += cd_buffer_temp[0];
|
||||
if (channel_select[0] & 2)
|
||||
cd_buffer_temp2[1] += cd_buffer_temp[0];
|
||||
if (channel_select[1] & 1)
|
||||
cd_buffer_temp2[0] += cd_buffer_temp[1];
|
||||
if (channel_select[1] & 2)
|
||||
cd_buffer_temp2[1] += cd_buffer_temp[1];
|
||||
|
||||
if (sound_process_handlers_num) {
|
||||
cd_buffer_temp4[0] = (int32_t) cd_buffer_temp2[0];
|
||||
cd_buffer_temp4[1] = (int32_t) cd_buffer_temp2[1];
|
||||
|
||||
@@ -298,9 +289,7 @@ static void sound_cd_thread(void *param)
|
||||
|
||||
cd_buffer_temp2[0] = (float) cd_buffer_temp4[0];
|
||||
cd_buffer_temp2[1] = (float) cd_buffer_temp4[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/*Apply sound card CD volume*/
|
||||
cd_buffer_temp2[0] *= (float) cd_vol_l;
|
||||
cd_buffer_temp2[0] /= 65535.0;
|
||||
@@ -309,13 +298,10 @@ static void sound_cd_thread(void *param)
|
||||
cd_buffer_temp2[1] /= 65535.0;
|
||||
}
|
||||
|
||||
if (sound_is_float)
|
||||
{
|
||||
if (sound_is_float) {
|
||||
cd_out_buffer[c] += (cd_buffer_temp2[0] / 32768.0);
|
||||
cd_out_buffer[c+1] += (cd_buffer_temp2[1] / 32768.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (cd_buffer_temp2[0] > 32767)
|
||||
cd_buffer_temp2[0] = 32767;
|
||||
if (cd_buffer_temp2[0] < -32768)
|
||||
@@ -331,6 +317,7 @@ static void sound_cd_thread(void *param)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sound_is_float)
|
||||
givealbuffer_cd(cd_out_buffer);
|
||||
else
|
||||
@@ -540,21 +527,15 @@ void sound_cd_thread_reset(void)
|
||||
int i = 0;
|
||||
int available_cdrom_drives = 0;
|
||||
|
||||
for (i = 0; i < CDROM_NUM; i++)
|
||||
{
|
||||
if (cdrom[i] && cdrom[i]->handler && cdrom[i]->handler->audio_stop)
|
||||
{
|
||||
cdrom[i]->handler->audio_stop(i);
|
||||
}
|
||||
for (i = 0; i < CDROM_NUM; i++) {
|
||||
if (cdrom_drives[i].handler && cdrom_drives[i].handler->audio_stop)
|
||||
cdrom_drives[i].handler->audio_stop(i);
|
||||
|
||||
if ((cdrom_drives[i].bus_type != CDROM_BUS_DISABLED) && cdrom[i])
|
||||
{
|
||||
if (cdrom_drives[i].bus_type != CDROM_BUS_DISABLED)
|
||||
available_cdrom_drives++;
|
||||
}
|
||||
}
|
||||
|
||||
if (available_cdrom_drives && !cd_thread_enable)
|
||||
{
|
||||
if (available_cdrom_drives && !cd_thread_enable) {
|
||||
cdaudioon = 1;
|
||||
|
||||
sound_cd_start_event = thread_create_event();
|
||||
@@ -564,9 +545,7 @@ void sound_cd_thread_reset(void)
|
||||
|
||||
thread_wait_event(sound_cd_start_event, -1);
|
||||
thread_reset_event(sound_cd_start_event);
|
||||
}
|
||||
else if (!available_cdrom_drives && cd_thread_enable)
|
||||
{
|
||||
} else if (!available_cdrom_drives && cd_thread_enable) {
|
||||
sound_cd_thread_end();
|
||||
}
|
||||
|
||||
|
||||
@@ -477,7 +477,7 @@ USBOBJ := usb.o
|
||||
endif
|
||||
|
||||
SCSIOBJ := scsi.o scsi_device.o \
|
||||
scsi_disk.o \
|
||||
scsi_cdrom.o scsi_disk.o \
|
||||
scsi_x54x.o \
|
||||
scsi_aha154x.o scsi_buslogic.o \
|
||||
scsi_ncr5380.o scsi_ncr53c810.o
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Platform support defintions for Win32.
|
||||
*
|
||||
* Version: @(#)win.h 1.0.19 2018/07/19
|
||||
* Version: @(#)win.h 1.0.20 2018/10/10
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -50,6 +50,8 @@
|
||||
#define WM_SHOWSETTINGS 0x8889
|
||||
#define WM_PAUSE 0x8890
|
||||
#define WM_SENDHWND 0x8891
|
||||
#define WM_HARDRESET 0x8892
|
||||
#define WM_SHUTDOWN 0x8893
|
||||
|
||||
#ifdef USE_VNC
|
||||
#define RENDERERS_NUM 5
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Handle the platform-side of CDROM drives.
|
||||
*
|
||||
* Version: @(#)win_cdrom.c 1.0.9 2018/10/02
|
||||
* Version: @(#)win_cdrom.c 1.0.10 2018/10/09
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -43,32 +43,35 @@
|
||||
void
|
||||
cdrom_eject(uint8_t id)
|
||||
{
|
||||
if (cdrom_drives[id].host_drive == 0) {
|
||||
cdrom_drive_t *drv = &cdrom_drives[id];
|
||||
cdrom_image_t *img = &cdrom_image[id];
|
||||
|
||||
if (drv->host_drive == 0) {
|
||||
/* Switch from empty to empty. Do nothing. */
|
||||
return;
|
||||
}
|
||||
|
||||
if (cdrom_image[id].prev_image_path) {
|
||||
free(cdrom_image[id].prev_image_path);
|
||||
cdrom_image[id].prev_image_path = NULL;
|
||||
if (img->prev_image_path) {
|
||||
free(img->prev_image_path);
|
||||
img->prev_image_path = NULL;
|
||||
}
|
||||
|
||||
if (cdrom_drives[id].host_drive == 200) {
|
||||
cdrom_image[id].prev_image_path = (wchar_t *) malloc(1024);
|
||||
wcscpy(cdrom_image[id].prev_image_path, cdrom_image[id].image_path);
|
||||
if (drv->host_drive == 200) {
|
||||
img->prev_image_path = (wchar_t *) malloc(1024);
|
||||
wcscpy(img->prev_image_path, img->image_path);
|
||||
}
|
||||
cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive;
|
||||
cdrom[id]->handler->exit(id);
|
||||
drv->prev_host_drive = drv->host_drive;
|
||||
drv->handler->exit(id);
|
||||
cdrom_close_handler(id);
|
||||
memset(cdrom_image[id].image_path, 0, 2048);
|
||||
memset(img->image_path, 0, 2048);
|
||||
cdrom_null_open(id);
|
||||
if (cdrom_drives[id].bus_type) {
|
||||
if (drv->insert) {
|
||||
/* Signal disc change to the emulated machine. */
|
||||
cdrom_insert(cdrom[id]);
|
||||
drv->insert(drv->p);
|
||||
}
|
||||
|
||||
ui_sb_check_menu_item(SB_CDROM|id, IDM_CDROM_IMAGE | id, MF_UNCHECKED);
|
||||
cdrom_drives[id].host_drive=0;
|
||||
drv->host_drive=0;
|
||||
ui_sb_check_menu_item(SB_CDROM|id, IDM_CDROM_EMPTY | id, MF_CHECKED);
|
||||
ui_sb_update_icon_state(SB_CDROM|id, 1);
|
||||
ui_sb_enable_menu_item(SB_CDROM|id, IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_ENABLED);
|
||||
@@ -81,31 +84,34 @@ cdrom_eject(uint8_t id)
|
||||
void
|
||||
cdrom_reload(uint8_t id)
|
||||
{
|
||||
if ((cdrom_drives[id].host_drive == cdrom_drives[id].prev_host_drive) || (cdrom_drives[id].prev_host_drive == 0) || (cdrom_drives[id].host_drive != 0)) {
|
||||
cdrom_drive_t *drv = &cdrom_drives[id];
|
||||
cdrom_image_t *img = &cdrom_image[id];
|
||||
|
||||
if ((drv->host_drive == drv->prev_host_drive) || !drv->prev_host_drive || drv->host_drive) {
|
||||
/* Switch from empty to empty. Do nothing. */
|
||||
return;
|
||||
}
|
||||
|
||||
cdrom_close_handler(id);
|
||||
memset(cdrom_image[id].image_path, 0, 2048);
|
||||
memset(img->image_path, 0, 2048);
|
||||
|
||||
if (cdrom_drives[id].prev_host_drive == 200) {
|
||||
wcscpy(cdrom_image[id].image_path, cdrom_image[id].prev_image_path);
|
||||
free(cdrom_image[id].prev_image_path);
|
||||
cdrom_image[id].prev_image_path = NULL;
|
||||
image_open(id, cdrom_image[id].image_path);
|
||||
if (cdrom_drives[id].bus_type) {
|
||||
if (drv->prev_host_drive == 200) {
|
||||
wcscpy(img->image_path, img->prev_image_path);
|
||||
free(img->prev_image_path);
|
||||
img->prev_image_path = NULL;
|
||||
image_open(id, img->image_path);
|
||||
if (drv->insert) {
|
||||
/* Signal disc change to the emulated machine. */
|
||||
cdrom_insert(cdrom[id]);
|
||||
drv->insert(drv->p);
|
||||
}
|
||||
if (wcslen(cdrom_image[id].image_path) == 0) {
|
||||
if (wcslen(img->image_path) == 0) {
|
||||
ui_sb_check_menu_item(SB_CDROM|id, IDM_CDROM_EMPTY | id, MF_CHECKED);
|
||||
cdrom_drives[id].host_drive = 0;
|
||||
drv->host_drive = 0;
|
||||
ui_sb_check_menu_item(SB_CDROM|id, IDM_CDROM_IMAGE | id, MF_UNCHECKED);
|
||||
ui_sb_update_icon_state(SB_CDROM|id, 1);
|
||||
} else {
|
||||
ui_sb_check_menu_item(SB_CDROM|id, IDM_CDROM_EMPTY | id, MF_UNCHECKED);
|
||||
cdrom_drives[id].host_drive = 200;
|
||||
drv->host_drive = 200;
|
||||
ui_sb_check_menu_item(SB_CDROM|id, IDM_CDROM_IMAGE | id, MF_CHECKED);
|
||||
ui_sb_update_icon_state(SB_CDROM|id, 0);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "../86box.h"
|
||||
#include "../device.h"
|
||||
#include "../video/video.h"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
* NOTES: This code should be re-merged into a single init() with a
|
||||
* 'fullscreen' argument, indicating FS mode is requested.
|
||||
*
|
||||
* Version: @(#)win_ddraw.cpp 1.0.10 2018/07/17
|
||||
* Version: @(#)win_ddraw.cpp 1.0.11 2018/10/10
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -178,7 +178,8 @@ SavePNG(wchar_t *szFilename, HBITMAP hBitmap)
|
||||
bmpInfo.bmiHeader.biSizeImage =
|
||||
bmpInfo.bmiHeader.biWidth*abs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8;
|
||||
|
||||
if ((pBuf = malloc(bmpInfo.bmiHeader.biSizeImage)) == NULL) {
|
||||
pBuf = malloc(bmpInfo.bmiHeader.biSizeImage);
|
||||
if (pBuf == NULL) {
|
||||
ddraw_log("[SavePNG] Unable to Allocate Bitmap Memory");
|
||||
fclose(fp);
|
||||
return;
|
||||
@@ -187,7 +188,8 @@ SavePNG(wchar_t *szFilename, HBITMAP hBitmap)
|
||||
if (ys2 <= 250) {
|
||||
bmpInfo.bmiHeader.biSizeImage <<= 1;
|
||||
|
||||
if ((pBuf2 = malloc(bmpInfo.bmiHeader.biSizeImage)) == NULL) {
|
||||
pBuf2 = malloc(bmpInfo.bmiHeader.biSizeImage);
|
||||
if (pBuf2 == NULL) {
|
||||
ddraw_log("[SavePNG] Unable to Allocate Secondary Bitmap Memory");
|
||||
free(pBuf);
|
||||
fclose(fp);
|
||||
@@ -207,7 +209,8 @@ SavePNG(wchar_t *szFilename, HBITMAP hBitmap)
|
||||
8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
|
||||
if ((b_rgb = (png_bytep *) malloc(sizeof(png_bytep) * bmpInfo.bmiHeader.biHeight)) == NULL) {
|
||||
b_rgb = (png_bytep *) malloc(sizeof(png_bytep) * bmpInfo.bmiHeader.biHeight);
|
||||
if (b_rgb == NULL) {
|
||||
ddraw_log("[SavePNG] Unable to Allocate RGB Bitmap Memory");
|
||||
free(pBuf2);
|
||||
free(pBuf);
|
||||
@@ -215,8 +218,9 @@ SavePNG(wchar_t *szFilename, HBITMAP hBitmap)
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < bmpInfo.bmiHeader.biHeight; i++)
|
||||
for (i = 0; i < bmpInfo.bmiHeader.biHeight; i++) {
|
||||
b_rgb[i] = (png_byte *) malloc(png_get_rowbytes(png_ptr, info_ptr));
|
||||
}
|
||||
|
||||
if (pBuf2) {
|
||||
DoubleLines((uint8_t *) pBuf2, (uint8_t *) pBuf);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Windows device configuration dialog implementation.
|
||||
*
|
||||
* Version: @(#)win_devconf.c 1.0.18 2018/04/01
|
||||
* Version: @(#)win_devconf.c 1.0.19 2018/10/10
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
@@ -459,10 +460,13 @@ deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
uint8_t deviceconfig_open(HWND hwnd, const device_t *device)
|
||||
{
|
||||
const device_config_t *config = device->config;
|
||||
uint16_t *data_block = malloc(16384);
|
||||
uint16_t *data_block;
|
||||
uint16_t *data;
|
||||
DLGTEMPLATE *dlg = (DLGTEMPLATE *)data_block;
|
||||
DLGTEMPLATE *dlg;
|
||||
DLGITEMTEMPLATE *item;
|
||||
|
||||
data_block = malloc(16384);
|
||||
dlg = (DLGTEMPLATE *)data_block;
|
||||
int y = 10;
|
||||
int id = IDC_CONFIG_BASE;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* we will not use that, but, instead, use a new window which
|
||||
* coverrs the entire desktop.
|
||||
*
|
||||
* Version: @(#)win_sdl.c 1.0.0 2018/05/26
|
||||
* Version: @(#)win_sdl.c 1.0.1 2018/10/10
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Michael Drüing, <michael@drueing.de>
|
||||
@@ -551,7 +551,8 @@ sdl_take_screenshot(const wchar_t *fn)
|
||||
8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
|
||||
if ((rgba = (unsigned char *)malloc(width * height * 4)) == NULL) {
|
||||
rgba = (unsigned char *) malloc(width * height * 4);
|
||||
if (rgba == NULL) {
|
||||
sdl_log("[sdl_take_screenshot] Unable to Allocate RGBA Bitmap Memory");
|
||||
fclose(fp);
|
||||
return;
|
||||
@@ -564,7 +565,8 @@ sdl_take_screenshot(const wchar_t *fn)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((b_rgb = (png_bytep *) malloc(sizeof(png_bytep) * height)) == NULL) {
|
||||
b_rgb = (png_bytep *) malloc(sizeof(png_bytep) * height);
|
||||
if (b_rgb == NULL) {
|
||||
sdl_log("[sdl_take_screenshot] Unable to Allocate RGB Bitmap Memory");
|
||||
free(rgba);
|
||||
fclose(fp);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Implement the application's Status Bar.
|
||||
*
|
||||
* Version: @(#)win_stbar.c 1.0.19 2018/10/02
|
||||
* Version: @(#)win_stbar.c 1.0.20 2018/10/09
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -286,7 +286,7 @@ StatusBarCreateCdromTip(int part)
|
||||
free(sbTips[part]);
|
||||
sbTips[part] = NULL;
|
||||
}
|
||||
sbTips[part] = (WCHAR *)malloc((wcslen(tempTip) << 1) + 2);
|
||||
sbTips[part] = (WCHAR *)malloc((wcslen(tempTip) << 1) + 4);
|
||||
wcscpy(sbTips[part], tempTip);
|
||||
}
|
||||
|
||||
@@ -882,12 +882,13 @@ StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
if (!cdrom_image[id].prev_image_path)
|
||||
cdrom_image[id].prev_image_path = (wchar_t *) malloc(1024);
|
||||
wcscpy(cdrom_image[id].prev_image_path, cdrom_image[id].image_path);
|
||||
cdrom[id]->handler->exit(id);
|
||||
cdrom_drives[id].handler->exit(id);
|
||||
cdrom_close_handler(id);
|
||||
memset(cdrom_image[id].image_path, 0, 2048);
|
||||
image_open(id, temp_path);
|
||||
/* Signal media change to the emulated machine. */
|
||||
cdrom_insert(cdrom[id]);
|
||||
if (cdrom_drives[id].insert)
|
||||
cdrom_drives[id].insert(cdrom_drives[id].p);
|
||||
CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED);
|
||||
cdrom_drives[id].host_drive = (wcslen(cdrom_image[id].image_path) == 0) ? 0 : 200;
|
||||
if (cdrom_drives[id].host_drive == 200) {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* user Interface module for WinAPI on Windows.
|
||||
*
|
||||
* Version: @(#)win_ui.c 1.0.31 2018/10/07
|
||||
* Version: @(#)win_ui.c 1.0.32 2018/10/10
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -644,6 +644,14 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
CheckMenuItem(menuMain, IDM_ACTION_PAUSE, dopause ? MF_CHECKED : MF_UNCHECKED);
|
||||
break;
|
||||
|
||||
case WM_HARDRESET:
|
||||
pc_reset(1);
|
||||
break;
|
||||
|
||||
case WM_SHUTDOWN:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
|
||||
case WM_SYSCOMMAND:
|
||||
/*
|
||||
* Disable ALT key *ALWAYS*,
|
||||
|
||||
Reference in New Issue
Block a user