Added three NCR5380-based SCSI controllers (in dev branch);
Two-phases SCSI disk write direction commands (needed for the NCR5380); Renamed cdrom_ioctl.c/h to win_cdrom_ioctl.c/h and moved them to win/; Moved some CD-ROM and floppy initialization blocks to the appropriate files.
This commit is contained in:
@@ -68,6 +68,9 @@ endif
|
|||||||
ifndef CIRRUS
|
ifndef CIRRUS
|
||||||
CIRRUS := n
|
CIRRUS := n
|
||||||
endif
|
endif
|
||||||
|
ifndef NCR_SCSI
|
||||||
|
NCR_SCSI := n
|
||||||
|
endif
|
||||||
ifndef NV_RIVA
|
ifndef NV_RIVA
|
||||||
NV_RIVA := n
|
NV_RIVA := n
|
||||||
endif
|
endif
|
||||||
@@ -87,6 +90,7 @@ endif
|
|||||||
ifeq ($(DEV_BUILD), y)
|
ifeq ($(DEV_BUILD), y)
|
||||||
DEV_BRANCH := y
|
DEV_BRANCH := y
|
||||||
CIRRUS := y
|
CIRRUS := y
|
||||||
|
NCR_SCSI := y
|
||||||
NV_RIVA := y
|
NV_RIVA := y
|
||||||
PAS16 := y
|
PAS16 := y
|
||||||
endif
|
endif
|
||||||
@@ -201,6 +205,11 @@ CFLAGS += -DUSE_CIRRUS
|
|||||||
DEVBROBJ += vid_cl_gd.o vid_cl_gd_blit.o vid_cl_ramdac.o
|
DEVBROBJ += vid_cl_gd.o vid_cl_gd_blit.o vid_cl_ramdac.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(NCR_SCSI), y)
|
||||||
|
CFLAGS += -DUSE_NCR
|
||||||
|
DEVBROBJ += scsi_bus.o scsi_ncr5380.o
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(NV_RIVA), y)
|
ifeq ($(NV_RIVA), y)
|
||||||
CFLAGS += -DUSE_RIVA
|
CFLAGS += -DUSE_RIVA
|
||||||
DEVBROBJ += vid_nv_riva128.o
|
DEVBROBJ += vid_nv_riva128.o
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
* Implementation of the CD-ROM drive with SCSI(-like)
|
* Implementation of the CD-ROM drive with SCSI(-like)
|
||||||
* commands, for both ATAPI and SCSI usage.
|
* commands, for both ATAPI and SCSI usage.
|
||||||
*
|
*
|
||||||
* Version: @(#)cdrom.c 1.0.9 2017/10/05
|
* Version: @(#)cdrom.c 1.0.11 2017/10/07
|
||||||
*
|
*
|
||||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||||
* Copyright 2016,2017 Miran Grca.
|
* Copyright 2016,2017 Miran Grca.
|
||||||
@@ -30,8 +30,11 @@
|
|||||||
#include "../disk/hdc.h"
|
#include "../disk/hdc.h"
|
||||||
#include "../disk/hdc_ide.h"
|
#include "../disk/hdc_ide.h"
|
||||||
#include "../win/win.h"
|
#include "../win/win.h"
|
||||||
|
#include "../win/win_cdrom_ioctl.h"
|
||||||
#include "../win/plat_iodev.h"
|
#include "../win/plat_iodev.h"
|
||||||
#include "cdrom.h"
|
#include "cdrom.h"
|
||||||
|
#include "cdrom_image.h"
|
||||||
|
#include "cdrom_null.h"
|
||||||
|
|
||||||
|
|
||||||
/* Bits of 'status' */
|
/* Bits of 'status' */
|
||||||
@@ -46,12 +49,6 @@
|
|||||||
#define ABRT_ERR 0x04 /* Command aborted */
|
#define ABRT_ERR 0x04 /* Command aborted */
|
||||||
#define MCR_ERR 0x08 /* Media change request */
|
#define MCR_ERR 0x08 /* Media change request */
|
||||||
|
|
||||||
#define MODE_SELECT_PHASE_IDLE 0
|
|
||||||
#define MODE_SELECT_PHASE_HEADER 1
|
|
||||||
#define MODE_SELECT_PHASE_BLOCK_DESC 2
|
|
||||||
#define MODE_SELECT_PHASE_PAGE_HEADER 3
|
|
||||||
#define MODE_SELECT_PHASE_PAGE 4
|
|
||||||
|
|
||||||
cdrom_t cdrom[CDROM_NUM];
|
cdrom_t cdrom[CDROM_NUM];
|
||||||
cdrom_drive_t cdrom_drives[CDROM_NUM];
|
cdrom_drive_t cdrom_drives[CDROM_NUM];
|
||||||
uint8_t atapi_cdrom_drives[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
uint8_t atapi_cdrom_drives[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||||
@@ -728,6 +725,7 @@ uint8_t cdrom_mode_sense_pages_saved[CDROM_NUM][0x40][0x40] =
|
|||||||
{ GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }
|
{ GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define ENABLE_CDROM_LOG 0
|
||||||
int cdrom_do_log = 0;
|
int cdrom_do_log = 0;
|
||||||
|
|
||||||
void cdrom_log(const char *format, ...)
|
void cdrom_log(const char *format, ...)
|
||||||
@@ -1510,11 +1508,7 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al
|
|||||||
}
|
}
|
||||||
if (cdrom_request_length_is_zero(id) || (len == 0) || (cdrom_current_mode(id) == 0))
|
if (cdrom_request_length_is_zero(id) || (len == 0) || (cdrom_current_mode(id) == 0))
|
||||||
{
|
{
|
||||||
if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)
|
if (cdrom_drives[id].bus_type != CDROM_BUS_SCSI)
|
||||||
{
|
|
||||||
SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
cdrom[id].init_length = 0;
|
cdrom[id].init_length = 0;
|
||||||
}
|
}
|
||||||
@@ -1526,11 +1520,7 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al
|
|||||||
{
|
{
|
||||||
if (direction == 0)
|
if (direction == 0)
|
||||||
{
|
{
|
||||||
if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)
|
if (cdrom_drives[id].bus_type != CDROM_BUS_SCSI)
|
||||||
{
|
|
||||||
SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength = alloc_len;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
cdrom[id].init_length = alloc_len;
|
cdrom[id].init_length = alloc_len;
|
||||||
}
|
}
|
||||||
@@ -1566,6 +1556,7 @@ static void cdrom_sense_clear(int id, int command)
|
|||||||
|
|
||||||
static void cdrom_cmd_error(uint8_t id)
|
static void cdrom_cmd_error(uint8_t id)
|
||||||
{
|
{
|
||||||
|
SCSIPhase = SCSI_PHASE_STATUS;
|
||||||
cdrom[id].error = ((cdrom_sense_key & 0xf) << 4) | ABRT_ERR;
|
cdrom[id].error = ((cdrom_sense_key & 0xf) << 4) | ABRT_ERR;
|
||||||
if (cdrom[id].unit_attention)
|
if (cdrom[id].unit_attention)
|
||||||
{
|
{
|
||||||
@@ -1580,6 +1571,7 @@ static void cdrom_cmd_error(uint8_t id)
|
|||||||
|
|
||||||
static void cdrom_unit_attention(uint8_t id)
|
static void cdrom_unit_attention(uint8_t id)
|
||||||
{
|
{
|
||||||
|
SCSIPhase = SCSI_PHASE_STATUS;
|
||||||
cdrom[id].error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR;
|
cdrom[id].error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR;
|
||||||
if (cdrom[id].unit_attention)
|
if (cdrom[id].unit_attention)
|
||||||
{
|
{
|
||||||
@@ -2247,12 +2239,14 @@ void cdrom_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length)
|
|||||||
|
|
||||||
if ((cdrom_sense_key > 0) && ((cdrom[id].cd_status < CD_STATUS_PLAYING) || (cdrom[id].cd_status == CD_STATUS_STOPPED)) && cdrom_playing_completed(id))
|
if ((cdrom_sense_key > 0) && ((cdrom[id].cd_status < CD_STATUS_PLAYING) || (cdrom[id].cd_status == CD_STATUS_STOPPED)) && cdrom_playing_completed(id))
|
||||||
{
|
{
|
||||||
|
SCSIPhase = SCSI_PHASE_STATUS;
|
||||||
buffer[2]=SENSE_ILLEGAL_REQUEST;
|
buffer[2]=SENSE_ILLEGAL_REQUEST;
|
||||||
buffer[12]=ASC_AUDIO_PLAY_OPERATION;
|
buffer[12]=ASC_AUDIO_PLAY_OPERATION;
|
||||||
buffer[13]=ASCQ_AUDIO_PLAY_OPERATION_COMPLETED;
|
buffer[13]=ASCQ_AUDIO_PLAY_OPERATION_COMPLETED;
|
||||||
}
|
}
|
||||||
else if ((cdrom_sense_key == 0) && (cdrom[id].cd_status >= CD_STATUS_PLAYING) && (cdrom[id].cd_status != CD_STATUS_STOPPED))
|
else if ((cdrom_sense_key == 0) && (cdrom[id].cd_status >= CD_STATUS_PLAYING) && (cdrom[id].cd_status != CD_STATUS_STOPPED))
|
||||||
{
|
{
|
||||||
|
SCSIPhase = SCSI_PHASE_STATUS;
|
||||||
buffer[2]=SENSE_ILLEGAL_REQUEST;
|
buffer[2]=SENSE_ILLEGAL_REQUEST;
|
||||||
buffer[12]=ASC_AUDIO_PLAY_OPERATION;
|
buffer[12]=ASC_AUDIO_PLAY_OPERATION;
|
||||||
buffer[13]=(cdrom[id].cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED;
|
buffer[13]=(cdrom[id].cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED;
|
||||||
@@ -2261,13 +2255,14 @@ void cdrom_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length)
|
|||||||
{
|
{
|
||||||
if (cdrom[id].unit_attention && (cdrom_sense_key == 0))
|
if (cdrom[id].unit_attention && (cdrom_sense_key == 0))
|
||||||
{
|
{
|
||||||
|
SCSIPhase = SCSI_PHASE_STATUS;
|
||||||
buffer[2]=SENSE_UNIT_ATTENTION;
|
buffer[2]=SENSE_UNIT_ATTENTION;
|
||||||
buffer[12]=ASC_MEDIUM_MAY_HAVE_CHANGED;
|
buffer[12]=ASC_MEDIUM_MAY_HAVE_CHANGED;
|
||||||
buffer[13]=0;
|
buffer[13]=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* cdrom_log("CD-ROM %i: Reporting sense: %02X %02X %02X\n", id, cdbufferb[2], cdbufferb[12], cdbufferb[13]); */
|
cdrom_log("CD-ROM %i: Reporting sense: %02X %02X %02X\n", id, buffer[2], buffer[12], buffer[13]);
|
||||||
|
|
||||||
if (buffer[2] == SENSE_UNIT_ATTENTION)
|
if (buffer[2] == SENSE_UNIT_ATTENTION)
|
||||||
{
|
{
|
||||||
@@ -2327,7 +2322,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
|
|||||||
char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 };
|
char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 };
|
||||||
char device_identify_ex[15] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 };
|
char device_identify_ex[15] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 };
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
int CdbLength;
|
int CdbLength;
|
||||||
#endif
|
#endif
|
||||||
if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)
|
if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)
|
||||||
@@ -2360,10 +2355,10 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
|
|||||||
cdrom_log("CD-ROM %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, %i, Unit attention: %i\n", id, cdb[0], cdrom_sense_key, cdrom_asc, cdrom_ascq, ins, cdrom[id].unit_attention);
|
cdrom_log("CD-ROM %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, %i, Unit attention: %i\n", id, cdb[0], cdrom_sense_key, cdrom_asc, cdrom_ascq, ins, cdrom[id].unit_attention);
|
||||||
cdrom_log("CD-ROM %i: Request length: %04X\n", id, cdrom[id].request_length);
|
cdrom_log("CD-ROM %i: Request length: %04X\n", id, cdrom[id].request_length);
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
for (CdbLength = 1; CdbLength < cdrom[id].cdb_len; CdbLength++)
|
for (CdbLength = 1; CdbLength < cdrom[id].cdb_len; CdbLength++)
|
||||||
{
|
{
|
||||||
cdrom_log("CD-ROM %i: CDB[%d] = 0x%02X\n", id, CdbLength, cdb[CdbLength]);
|
cdrom_log("CD-ROM %i: CDB[%d] = %d\n", id, CdbLength, cdb[CdbLength]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -2380,6 +2375,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
|
|||||||
switch (cdb[0])
|
switch (cdb[0])
|
||||||
{
|
{
|
||||||
case GPCMD_TEST_UNIT_READY:
|
case GPCMD_TEST_UNIT_READY:
|
||||||
|
SCSIPhase = SCSI_PHASE_STATUS;
|
||||||
cdrom_command_complete(id);
|
cdrom_command_complete(id);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -2390,16 +2386,22 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
|
|||||||
}
|
}
|
||||||
cdrom[id].sector_pos = cdrom[id].sector_len = 0;
|
cdrom[id].sector_pos = cdrom[id].sector_len = 0;
|
||||||
cdrom_seek(id, 0);
|
cdrom_seek(id, 0);
|
||||||
|
SCSIPhase = SCSI_PHASE_STATUS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPCMD_REQUEST_SENSE:
|
case GPCMD_REQUEST_SENSE:
|
||||||
/* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE
|
/* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE
|
||||||
should forget about the not ready, and report unit attention straight away. */
|
should forget about the not ready, and report unit attention straight away. */
|
||||||
|
SCSIPhase = SCSI_PHASE_DATA_IN;
|
||||||
if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)
|
if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)
|
||||||
{
|
{
|
||||||
if (SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength < cdb[4])
|
if (SCSI_BufferLength == -1)
|
||||||
{
|
{
|
||||||
cdb[4] = SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength;
|
SCSI_BufferLength = cdb[4];
|
||||||
|
}
|
||||||
|
if (SCSI_BufferLength < cdb[4])
|
||||||
|
{
|
||||||
|
cdb[4] = SCSI_BufferLength;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cdrom_request_sense(id, cdbufferb, cdb[4]);
|
cdrom_request_sense(id, cdbufferb, cdb[4]);
|
||||||
@@ -2408,12 +2410,20 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
|
|||||||
|
|
||||||
case GPCMD_SET_SPEED:
|
case GPCMD_SET_SPEED:
|
||||||
case GPCMD_SET_SPEED_ALT:
|
case GPCMD_SET_SPEED_ALT:
|
||||||
|
SCSIPhase = SCSI_PHASE_DATA_IN;
|
||||||
cdrom_command_complete(id);
|
cdrom_command_complete(id);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPCMD_MECHANISM_STATUS:
|
case GPCMD_MECHANISM_STATUS:
|
||||||
|
SCSIPhase = SCSI_PHASE_DATA_IN;
|
||||||
|
|
||||||
len = (cdb[7] << 16) | (cdb[8] << 8) | cdb[9];
|
len = (cdb[7] << 16) | (cdb[8] << 8) | cdb[9];
|
||||||
|
|
||||||
|
if (SCSI_BufferLength == -1)
|
||||||
|
{
|
||||||
|
SCSI_BufferLength = len;
|
||||||
|
}
|
||||||
|
|
||||||
memset(cdbufferb, 0, 8);
|
memset(cdbufferb, 0, 8);
|
||||||
cdbufferb[5] = 1;
|
cdbufferb[5] = 1;
|
||||||
|
|
||||||
@@ -2423,6 +2433,8 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
|
|||||||
case GPCMD_READ_TOC_PMA_ATIP:
|
case GPCMD_READ_TOC_PMA_ATIP:
|
||||||
cdrom[id].toctimes++;
|
cdrom[id].toctimes++;
|
||||||
|
|
||||||
|
SCSIPhase = SCSI_PHASE_DATA_IN;
|
||||||
|
|
||||||
max_len = cdb[7];
|
max_len = cdb[7];
|
||||||
max_len <<= 8;
|
max_len <<= 8;
|
||||||
max_len |= cdb[8];
|
max_len |= cdb[8];
|
||||||
@@ -2436,6 +2448,13 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
|
|||||||
cdrom_sense_key = cdrom_asc = cdrom_ascq = 0;
|
cdrom_sense_key = cdrom_asc = cdrom_ascq = 0;
|
||||||
goto cdrom_readtoc_fallback;
|
goto cdrom_readtoc_fallback;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (SCSI_BufferLength == -1)
|
||||||
|
{
|
||||||
|
SCSI_BufferLength = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
alloc_length = cdbufferb[0];
|
alloc_length = cdbufferb[0];
|
||||||
alloc_length <<= 8;
|
alloc_length <<= 8;
|
||||||
alloc_length |= cdbufferb[1];
|
alloc_length |= cdbufferb[1];
|
||||||
@@ -2481,6 +2500,11 @@ cdrom_readtoc_fallback:
|
|||||||
cdbufferb[1] = (len - 2) & 0xff;
|
cdbufferb[1] = (len - 2) & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SCSI_BufferLength == -1)
|
||||||
|
{
|
||||||
|
SCSI_BufferLength = len;
|
||||||
|
}
|
||||||
|
|
||||||
cdrom_data_command_finish(id, len, len, len, 0);
|
cdrom_data_command_finish(id, len, len, len, 0);
|
||||||
/* cdrom_log("CD-ROM %i: READ_TOC_PMA_ATIP format %02X, length %i (%i)\n", id, toc_format, ide->cylinder, cdbufferb[1]); */
|
/* cdrom_log("CD-ROM %i: READ_TOC_PMA_ATIP format %02X, length %i (%i)\n", id, toc_format, ide->cylinder, cdbufferb[1]); */
|
||||||
return;
|
return;
|
||||||
@@ -2492,6 +2516,8 @@ cdrom_readtoc_fallback:
|
|||||||
case GPCMD_READ_12:
|
case GPCMD_READ_12:
|
||||||
case GPCMD_READ_CD:
|
case GPCMD_READ_CD:
|
||||||
case GPCMD_READ_CD_MSF:
|
case GPCMD_READ_CD_MSF:
|
||||||
|
SCSIPhase = SCSI_PHASE_DATA_IN;
|
||||||
|
|
||||||
switch(cdb[0])
|
switch(cdb[0])
|
||||||
{
|
{
|
||||||
case GPCMD_READ_6:
|
case GPCMD_READ_6:
|
||||||
@@ -2531,6 +2557,7 @@ cdrom_readtoc_fallback:
|
|||||||
|
|
||||||
if (!cdrom[id].sector_len)
|
if (!cdrom[id].sector_len)
|
||||||
{
|
{
|
||||||
|
SCSIPhase = SCSI_PHASE_STATUS;
|
||||||
/* cdrom_log("CD-ROM %i: All done - callback set\n", id); */
|
/* cdrom_log("CD-ROM %i: All done - callback set\n", id); */
|
||||||
cdrom[id].packet_status = CDROM_PHASE_COMPLETE;
|
cdrom[id].packet_status = CDROM_PHASE_COMPLETE;
|
||||||
cdrom[id].callback = 20 * CDROM_TIME;
|
cdrom[id].callback = 20 * CDROM_TIME;
|
||||||
@@ -2555,6 +2582,12 @@ cdrom_readtoc_fallback:
|
|||||||
}
|
}
|
||||||
|
|
||||||
cdrom[id].packet_len = max_len * alloc_length;
|
cdrom[id].packet_len = max_len * alloc_length;
|
||||||
|
|
||||||
|
if (SCSI_BufferLength == -1)
|
||||||
|
{
|
||||||
|
SCSI_BufferLength = cdrom[id].packet_len;
|
||||||
|
}
|
||||||
|
|
||||||
if (cdrom[id].requested_blocks > 1)
|
if (cdrom[id].requested_blocks > 1)
|
||||||
{
|
{
|
||||||
cdrom_data_command_finish(id, alloc_length, alloc_length / cdrom[id].requested_blocks, alloc_length, 0);
|
cdrom_data_command_finish(id, alloc_length, alloc_length / cdrom[id].requested_blocks, alloc_length, 0);
|
||||||
@@ -2575,6 +2608,8 @@ cdrom_readtoc_fallback:
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case GPCMD_READ_HEADER:
|
case GPCMD_READ_HEADER:
|
||||||
|
SCSIPhase = SCSI_PHASE_DATA_IN;
|
||||||
|
|
||||||
if (cdrom_drives[id].handler->pass_through)
|
if (cdrom_drives[id].handler->pass_through)
|
||||||
{
|
{
|
||||||
ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb);
|
ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb);
|
||||||
@@ -2582,6 +2617,13 @@ cdrom_readtoc_fallback:
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (SCSI_BufferLength == -1)
|
||||||
|
{
|
||||||
|
SCSI_BufferLength = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2605,11 +2647,18 @@ cdrom_readtoc_fallback:
|
|||||||
len = 8;
|
len = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SCSI_BufferLength == -1)
|
||||||
|
{
|
||||||
|
SCSI_BufferLength = len;
|
||||||
|
}
|
||||||
|
|
||||||
cdrom_data_command_finish(id, len, len, len, 0);
|
cdrom_data_command_finish(id, len, len, len, 0);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case GPCMD_MODE_SENSE_6:
|
case GPCMD_MODE_SENSE_6:
|
||||||
case GPCMD_MODE_SENSE_10:
|
case GPCMD_MODE_SENSE_10:
|
||||||
|
SCSIPhase = SCSI_PHASE_DATA_IN;
|
||||||
|
|
||||||
if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)
|
if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)
|
||||||
{
|
{
|
||||||
block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1;
|
block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1;
|
||||||
@@ -2679,6 +2728,11 @@ cdrom_readtoc_fallback:
|
|||||||
alloc_length = len;
|
alloc_length = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SCSI_BufferLength == -1)
|
||||||
|
{
|
||||||
|
SCSI_BufferLength = alloc_length;
|
||||||
|
}
|
||||||
|
|
||||||
cdrom_log("CD-ROM %i: Reading mode page: %02X...\n", id, cdb[2]);
|
cdrom_log("CD-ROM %i: Reading mode page: %02X...\n", id, cdb[2]);
|
||||||
|
|
||||||
cdrom_data_command_finish(id, len, len, alloc_length, 0);
|
cdrom_data_command_finish(id, len, len, alloc_length, 0);
|
||||||
@@ -2686,6 +2740,8 @@ cdrom_readtoc_fallback:
|
|||||||
|
|
||||||
case GPCMD_MODE_SELECT_6:
|
case GPCMD_MODE_SELECT_6:
|
||||||
case GPCMD_MODE_SELECT_10:
|
case GPCMD_MODE_SELECT_10:
|
||||||
|
SCSIPhase = SCSI_PHASE_DATA_OUT;
|
||||||
|
|
||||||
if (cdb[0] == GPCMD_MODE_SELECT_6)
|
if (cdb[0] == GPCMD_MODE_SELECT_6)
|
||||||
{
|
{
|
||||||
len = cdb[4];
|
len = cdb[4];
|
||||||
@@ -2695,12 +2751,19 @@ cdrom_readtoc_fallback:
|
|||||||
len = (cdb[7] << 8) | cdb[8];
|
len = (cdb[7] << 8) | cdb[8];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SCSI_BufferLength == -1)
|
||||||
|
{
|
||||||
|
SCSI_BufferLength = len;
|
||||||
|
}
|
||||||
|
|
||||||
ret = cdrom_mode_select_init(id, cdb[0], len, cdb[1] & 1);
|
ret = cdrom_mode_select_init(id, cdb[0], len, cdb[1] & 1);
|
||||||
|
|
||||||
cdrom_data_command_finish(id, len, len, len, 1);
|
cdrom_data_command_finish(id, len, len, len, 1);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case GPCMD_GET_CONFIGURATION:
|
case GPCMD_GET_CONFIGURATION:
|
||||||
|
SCSIPhase = SCSI_PHASE_DATA_IN;
|
||||||
|
|
||||||
/* XXX: could result in alignment problems in some architectures */
|
/* XXX: could result in alignment problems in some architectures */
|
||||||
len = (cdb[7] << 8) | cdb[8];
|
len = (cdb[7] << 8) | cdb[8];
|
||||||
alloc_length = len;
|
alloc_length = len;
|
||||||
@@ -2750,10 +2813,17 @@ cdrom_readtoc_fallback:
|
|||||||
cdbufferb[2] = ((alloc_length - 4) >> 8) & 0xff;
|
cdbufferb[2] = ((alloc_length - 4) >> 8) & 0xff;
|
||||||
cdbufferb[3] = (alloc_length - 4) & 0xff;
|
cdbufferb[3] = (alloc_length - 4) & 0xff;
|
||||||
|
|
||||||
|
if (SCSI_BufferLength == -1)
|
||||||
|
{
|
||||||
|
SCSI_BufferLength = len;
|
||||||
|
}
|
||||||
|
|
||||||
cdrom_data_command_finish(id, len, len, alloc_length, 0);
|
cdrom_data_command_finish(id, len, len, alloc_length, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPCMD_GET_EVENT_STATUS_NOTIFICATION:
|
case GPCMD_GET_EVENT_STATUS_NOTIFICATION:
|
||||||
|
SCSIPhase = SCSI_PHASE_DATA_IN;
|
||||||
|
|
||||||
gesn_cdb = (void *) cdb;
|
gesn_cdb = (void *) cdb;
|
||||||
gesn_event_header = (void *) cdbufferb;
|
gesn_event_header = (void *) cdbufferb;
|
||||||
|
|
||||||
@@ -2802,10 +2872,17 @@ cdrom_readtoc_fallback:
|
|||||||
}
|
}
|
||||||
gesn_event_header->len = used_len - sizeof(*gesn_event_header);
|
gesn_event_header->len = used_len - sizeof(*gesn_event_header);
|
||||||
|
|
||||||
|
if (SCSI_BufferLength == -1)
|
||||||
|
{
|
||||||
|
SCSI_BufferLength = used_len;
|
||||||
|
}
|
||||||
|
|
||||||
cdrom_data_command_finish(id, used_len, used_len, used_len, 0);
|
cdrom_data_command_finish(id, used_len, used_len, used_len, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPCMD_READ_DISC_INFORMATION:
|
case GPCMD_READ_DISC_INFORMATION:
|
||||||
|
SCSIPhase = SCSI_PHASE_DATA_IN;
|
||||||
|
|
||||||
max_len = cdb[7];
|
max_len = cdb[7];
|
||||||
max_len <<= 8;
|
max_len <<= 8;
|
||||||
max_len |= cdb[8];
|
max_len |= cdb[8];
|
||||||
@@ -2839,10 +2916,18 @@ cdrom_readtoc_fallback:
|
|||||||
len=34;
|
len=34;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SCSI_BufferLength == -1)
|
||||||
|
{
|
||||||
|
SCSI_BufferLength = len;
|
||||||
|
}
|
||||||
|
|
||||||
cdrom_data_command_finish(id, len, len, max_len, 0);
|
cdrom_data_command_finish(id, len, len, max_len, 0);
|
||||||
|
SCSIPhase = BUS_IO;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPCMD_READ_TRACK_INFORMATION:
|
case GPCMD_READ_TRACK_INFORMATION:
|
||||||
|
SCSIPhase = SCSI_PHASE_DATA_IN;
|
||||||
|
|
||||||
max_len = cdb[7];
|
max_len = cdb[7];
|
||||||
max_len <<= 8;
|
max_len <<= 8;
|
||||||
max_len |= cdb[8];
|
max_len |= cdb[8];
|
||||||
@@ -2899,13 +2984,21 @@ cdrom_readtoc_fallback:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SCSI_BufferLength == -1)
|
||||||
|
{
|
||||||
|
SCSI_BufferLength = len;
|
||||||
|
}
|
||||||
|
|
||||||
cdrom_data_command_finish(id, len, len, max_len, 0);
|
cdrom_data_command_finish(id, len, len, max_len, 0);
|
||||||
|
SCSIPhase = BUS_IO;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPCMD_PLAY_AUDIO_10:
|
case GPCMD_PLAY_AUDIO_10:
|
||||||
case GPCMD_PLAY_AUDIO_12:
|
case GPCMD_PLAY_AUDIO_12:
|
||||||
case GPCMD_PLAY_AUDIO_MSF:
|
case GPCMD_PLAY_AUDIO_MSF:
|
||||||
case GPCMD_PLAY_AUDIO_TRACK_INDEX:
|
case GPCMD_PLAY_AUDIO_TRACK_INDEX:
|
||||||
|
SCSIPhase = SCSI_PHASE_STATUS;
|
||||||
|
|
||||||
switch(cdb[0])
|
switch(cdb[0])
|
||||||
{
|
{
|
||||||
case GPCMD_PLAY_AUDIO_10:
|
case GPCMD_PLAY_AUDIO_10:
|
||||||
@@ -2952,6 +3045,8 @@ cdrom_readtoc_fallback:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GPCMD_READ_SUBCHANNEL:
|
case GPCMD_READ_SUBCHANNEL:
|
||||||
|
SCSIPhase = SCSI_PHASE_DATA_IN;
|
||||||
|
|
||||||
max_len = cdb[7];
|
max_len = cdb[7];
|
||||||
max_len <<= 8;
|
max_len <<= 8;
|
||||||
max_len |= cdb[8];
|
max_len |= cdb[8];
|
||||||
@@ -3058,10 +3153,17 @@ cdrom_readtoc_fallback:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SCSI_BufferLength == -1)
|
||||||
|
{
|
||||||
|
SCSI_BufferLength = len;
|
||||||
|
}
|
||||||
|
|
||||||
cdrom_data_command_finish(id, len, len, max_len, 0);
|
cdrom_data_command_finish(id, len, len, max_len, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPCMD_READ_DVD_STRUCTURE:
|
case GPCMD_READ_DVD_STRUCTURE:
|
||||||
|
SCSIPhase = SCSI_PHASE_DATA_IN;
|
||||||
|
|
||||||
if (cdrom_drives[id].handler->pass_through)
|
if (cdrom_drives[id].handler->pass_through)
|
||||||
{
|
{
|
||||||
ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb);
|
ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb);
|
||||||
@@ -3069,6 +3171,13 @@ cdrom_readtoc_fallback:
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (SCSI_BufferLength == -1)
|
||||||
|
{
|
||||||
|
SCSI_BufferLength = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -3114,6 +3223,11 @@ cdrom_readtoc_fallback:
|
|||||||
{
|
{
|
||||||
ret = cdrom_read_dvd_structure(id, format, cdb, cdbufferb);
|
ret = cdrom_read_dvd_structure(id, format, cdb, cdbufferb);
|
||||||
|
|
||||||
|
if (SCSI_BufferLength == -1)
|
||||||
|
{
|
||||||
|
SCSI_BufferLength = alloc_length;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
cdrom_data_command_finish(id, len, len, alloc_length, 0);
|
cdrom_data_command_finish(id, len, len, alloc_length, 0);
|
||||||
@@ -3137,6 +3251,8 @@ cdrom_readtoc_fallback:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GPCMD_START_STOP_UNIT:
|
case GPCMD_START_STOP_UNIT:
|
||||||
|
SCSIPhase = SCSI_PHASE_STATUS;
|
||||||
|
|
||||||
switch(cdb[4] & 3)
|
switch(cdb[4] & 3)
|
||||||
{
|
{
|
||||||
case 0: /* Stop the disc. */
|
case 0: /* Stop the disc. */
|
||||||
@@ -3164,6 +3280,8 @@ cdrom_readtoc_fallback:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GPCMD_INQUIRY:
|
case GPCMD_INQUIRY:
|
||||||
|
SCSIPhase = SCSI_PHASE_DATA_IN;
|
||||||
|
|
||||||
max_len = cdb[3];
|
max_len = cdb[3];
|
||||||
max_len <<= 8;
|
max_len <<= 8;
|
||||||
max_len |= cdb[4];
|
max_len |= cdb[4];
|
||||||
@@ -3242,15 +3360,23 @@ atapi_out:
|
|||||||
cdbufferb[size_idx] = idx - preamble_len;
|
cdbufferb[size_idx] = idx - preamble_len;
|
||||||
len=idx;
|
len=idx;
|
||||||
|
|
||||||
|
if (SCSI_BufferLength == -1)
|
||||||
|
{
|
||||||
|
SCSI_BufferLength = len;
|
||||||
|
}
|
||||||
|
|
||||||
cdrom_data_command_finish(id, len, len, max_len, 0);
|
cdrom_data_command_finish(id, len, len, max_len, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPCMD_PREVENT_REMOVAL:
|
case GPCMD_PREVENT_REMOVAL:
|
||||||
|
SCSIPhase = SCSI_PHASE_STATUS;
|
||||||
cdrom_command_complete(id);
|
cdrom_command_complete(id);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPCMD_PAUSE_RESUME_ALT:
|
case GPCMD_PAUSE_RESUME_ALT:
|
||||||
case GPCMD_PAUSE_RESUME:
|
case GPCMD_PAUSE_RESUME:
|
||||||
|
SCSIPhase = SCSI_PHASE_STATUS;
|
||||||
|
|
||||||
if (cdb[8] & 1)
|
if (cdb[8] & 1)
|
||||||
{
|
{
|
||||||
if (cdrom_drives[id].handler->resume)
|
if (cdrom_drives[id].handler->resume)
|
||||||
@@ -3280,6 +3406,8 @@ atapi_out:
|
|||||||
|
|
||||||
case GPCMD_SEEK_6:
|
case GPCMD_SEEK_6:
|
||||||
case GPCMD_SEEK_10:
|
case GPCMD_SEEK_10:
|
||||||
|
SCSIPhase = SCSI_PHASE_STATUS;
|
||||||
|
|
||||||
switch(cdb[0])
|
switch(cdb[0])
|
||||||
{
|
{
|
||||||
case GPCMD_SEEK_6:
|
case GPCMD_SEEK_6:
|
||||||
@@ -3294,15 +3422,24 @@ atapi_out:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GPCMD_READ_CDROM_CAPACITY:
|
case GPCMD_READ_CDROM_CAPACITY:
|
||||||
|
SCSIPhase = SCSI_PHASE_DATA_IN;
|
||||||
|
|
||||||
if (cdrom_read_capacity(id, cdrom[id].current_cdb, cdbufferb, &len) == 0)
|
if (cdrom_read_capacity(id, cdrom[id].current_cdb, cdbufferb, &len) == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SCSI_BufferLength == -1)
|
||||||
|
{
|
||||||
|
SCSI_BufferLength = len;
|
||||||
|
}
|
||||||
|
|
||||||
cdrom_data_command_finish(id, len, len, len, 0);
|
cdrom_data_command_finish(id, len, len, len, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GPCMD_STOP_PLAY_SCAN:
|
case GPCMD_STOP_PLAY_SCAN:
|
||||||
|
SCSIPhase = SCSI_PHASE_STATUS;
|
||||||
|
|
||||||
if (cdrom_drives[id].handler->stop)
|
if (cdrom_drives[id].handler->stop)
|
||||||
{
|
{
|
||||||
cdrom_drives[id].handler->stop(id);
|
cdrom_drives[id].handler->stop(id);
|
||||||
@@ -3495,8 +3632,8 @@ int cdrom_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cdrom_log("Reading from SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSIDevices[scsi_id][scsi_lun].InitLength);
|
cdrom_log("Reading from SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSI_BufferLength);
|
||||||
memcpy(cdbufferb, SCSIDevices[scsi_id][scsi_lun].CmdBuffer, SCSIDevices[scsi_id][scsi_lun].InitLength);
|
memcpy(cdbufferb, SCSIDevices[scsi_id][scsi_lun].CmdBuffer, SCSI_BufferLength);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3525,7 +3662,7 @@ int cdrom_read_from_dma(uint8_t id)
|
|||||||
|
|
||||||
if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)
|
if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI)
|
||||||
{
|
{
|
||||||
in_data_length = SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength;
|
in_data_length = SCSI_BufferLength;
|
||||||
cdrom_log("CD-ROM %i: SCSI Input data length: %i\n", id, in_data_length);
|
cdrom_log("CD-ROM %i: SCSI Input data length: %i\n", id, in_data_length);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -3618,8 +3755,8 @@ int cdrom_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun)
|
|||||||
|
|
||||||
cdbufferb = (uint8_t *) cdrom[id].buffer;
|
cdbufferb = (uint8_t *) cdrom[id].buffer;
|
||||||
|
|
||||||
cdrom_log("Writing to SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSIDevices[scsi_id][scsi_lun].InitLength);
|
cdrom_log("Writing to SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSI_BufferLength);
|
||||||
memcpy(SCSIDevices[scsi_id][scsi_lun].CmdBuffer, cdbufferb, SCSIDevices[scsi_id][scsi_lun].InitLength);
|
memcpy(SCSIDevices[scsi_id][scsi_lun].CmdBuffer, cdbufferb, SCSI_BufferLength);
|
||||||
cdrom_log("CD-ROM %i: Data from CD buffer: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, cdbufferb[0], cdbufferb[1], cdbufferb[2], cdbufferb[3], cdbufferb[4], cdbufferb[5], cdbufferb[6], cdbufferb[7]);
|
cdrom_log("CD-ROM %i: Data from CD buffer: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, cdbufferb[0], cdbufferb[1], cdbufferb[2], cdbufferb[3], cdbufferb[4], cdbufferb[5], cdbufferb[6], cdbufferb[7]);
|
||||||
cdrom_log("CD-ROM %i: Data from SCSI DMA : %02X %02X %02X %02X %02X %02X %02X %02X\n", id, SCSIDevices[scsi_id][scsi_lun].CmdBuffer[0], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[1], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[2], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[3], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[4], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[5], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[6], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[7]);
|
cdrom_log("CD-ROM %i: Data from SCSI DMA : %02X %02X %02X %02X %02X %02X %02X %02X\n", id, SCSIDevices[scsi_id][scsi_lun].CmdBuffer[0], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[1], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[2], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[3], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[4], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[5], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[6], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[7]);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -3859,3 +3996,41 @@ void cdrom_write(uint8_t channel, uint32_t val, int length)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cdrom_hard_reset(void)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (i=0; i<CDROM_NUM; i++) {
|
||||||
|
if (cdrom_drives[i].host_drive == 200) {
|
||||||
|
image_reset(i);
|
||||||
|
}
|
||||||
|
else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z'))
|
||||||
|
{
|
||||||
|
ioctl_reset(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cdrom_general_init(void)
|
||||||
|
{
|
||||||
|
int c = 0;
|
||||||
|
|
||||||
|
cdrom_init_host_drives();
|
||||||
|
|
||||||
|
for (c=0; c<CDROM_NUM; c++) {
|
||||||
|
if (cdrom_drives[c].bus_type) {
|
||||||
|
SCSIReset(cdrom_drives[c].scsi_device_id, cdrom_drives[c].scsi_device_lun);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cdrom_drives[c].host_drive == 200) {
|
||||||
|
image_open(c, cdrom_image[c].image_path);
|
||||||
|
} else
|
||||||
|
if ((cdrom_drives[c].host_drive>='A') && (cdrom_drives[c].host_drive <= 'Z'))
|
||||||
|
{
|
||||||
|
ioctl_open(c, cdrom_drives[c].host_drive);
|
||||||
|
} else {
|
||||||
|
cdrom_null_open(c, cdrom_drives[c].host_drive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -242,5 +242,8 @@ int cdrom_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len
|
|||||||
#define cdrom_ascq cdrom[id].sense[13]
|
#define cdrom_ascq cdrom[id].sense[13]
|
||||||
#define cdrom_drive cdrom_drives[id].host_drive
|
#define cdrom_drive cdrom_drives[id].host_drive
|
||||||
|
|
||||||
|
void cdrom_hard_reset(void);
|
||||||
|
void cdrom_general_init(void);
|
||||||
|
|
||||||
|
|
||||||
#endif /*EMU_CDROM_H*/
|
#endif /*EMU_CDROM_H*/
|
||||||
|
|||||||
@@ -409,3 +409,18 @@ void floppy_stop(int drive)
|
|||||||
if (drives[drive].stop)
|
if (drives[drive].stop)
|
||||||
drives[drive].stop(drive);
|
drives[drive].stop(drive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void floppy_general_init(void)
|
||||||
|
{
|
||||||
|
floppy_init();
|
||||||
|
fdi_init();
|
||||||
|
img_init();
|
||||||
|
d86f_init();
|
||||||
|
td0_init();
|
||||||
|
imd_init();
|
||||||
|
|
||||||
|
floppy_load(0, floppyfns[0]);
|
||||||
|
floppy_load(1, floppyfns[1]);
|
||||||
|
floppy_load(2, floppyfns[2]);
|
||||||
|
floppy_load(3, floppyfns[3]);
|
||||||
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ extern void floppy_load(int drive, wchar_t *fn);
|
|||||||
extern void floppy_new(int drive, char *fn);
|
extern void floppy_new(int drive, char *fn);
|
||||||
extern void floppy_close(int drive);
|
extern void floppy_close(int drive);
|
||||||
extern void floppy_init(void);
|
extern void floppy_init(void);
|
||||||
|
extern void floppy_general_init(void);
|
||||||
extern void floppy_reset(void);
|
extern void floppy_reset(void);
|
||||||
extern void floppy_poll(int drive);
|
extern void floppy_poll(int drive);
|
||||||
extern void floppy_poll_0(void* priv);
|
extern void floppy_poll_0(void* priv);
|
||||||
|
|||||||
60
src/pc.c
60
src/pc.c
@@ -35,9 +35,6 @@
|
|||||||
#include "random.h"
|
#include "random.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "cdrom/cdrom.h"
|
#include "cdrom/cdrom.h"
|
||||||
#include "cdrom/cdrom_image.h"
|
|
||||||
#include "cdrom/cdrom_ioctl.h"
|
|
||||||
#include "cdrom/cdrom_null.h"
|
|
||||||
#include "disk/hdd.h"
|
#include "disk/hdd.h"
|
||||||
#include "disk/hdc.h"
|
#include "disk/hdc.h"
|
||||||
#include "disk/hdc_ide.h"
|
#include "disk/hdc_ide.h"
|
||||||
@@ -439,26 +436,7 @@ again2:
|
|||||||
|
|
||||||
ide_init_first();
|
ide_init_first();
|
||||||
|
|
||||||
#if 1
|
cdrom_general_init();
|
||||||
/* should be in cdrom.c */
|
|
||||||
cdrom_init_host_drives();
|
|
||||||
|
|
||||||
for (c=0; c<CDROM_NUM; c++) {
|
|
||||||
if (cdrom_drives[c].bus_type) {
|
|
||||||
SCSIReset(cdrom_drives[c].scsi_device_id, cdrom_drives[c].scsi_device_lun);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cdrom_drives[c].host_drive == 200) {
|
|
||||||
image_open(c, cdrom_image[c].image_path);
|
|
||||||
} else
|
|
||||||
if ((cdrom_drives[c].host_drive>='A') && (cdrom_drives[c].host_drive <= 'Z'))
|
|
||||||
{
|
|
||||||
ioctl_open(c, cdrom_drives[c].host_drive);
|
|
||||||
} else {
|
|
||||||
cdrom_null_open(c, cdrom_drives[c].host_drive);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
device_init();
|
device_init();
|
||||||
|
|
||||||
@@ -466,22 +444,9 @@ again2:
|
|||||||
|
|
||||||
sound_reset();
|
sound_reset();
|
||||||
|
|
||||||
#if 1
|
|
||||||
/* This should be in floppy.c and fdc.c --FvK */
|
|
||||||
fdc_init();
|
fdc_init();
|
||||||
|
|
||||||
floppy_init();
|
floppy_general_init();
|
||||||
fdi_init();
|
|
||||||
img_init();
|
|
||||||
d86f_init();
|
|
||||||
td0_init();
|
|
||||||
imd_init();
|
|
||||||
|
|
||||||
floppy_load(0, floppyfns[0]);
|
|
||||||
floppy_load(1, floppyfns[1]);
|
|
||||||
floppy_load(2, floppyfns[2]);
|
|
||||||
floppy_load(3, floppyfns[3]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sound_init();
|
sound_init();
|
||||||
|
|
||||||
@@ -489,14 +454,7 @@ again2:
|
|||||||
|
|
||||||
ide_reset();
|
ide_reset();
|
||||||
|
|
||||||
for (i=0; i<CDROM_NUM; i++) {
|
cdrom_hard_reset();
|
||||||
if (cdrom_drives[i].host_drive == 200) {
|
|
||||||
image_reset(i);
|
|
||||||
}
|
|
||||||
else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) {
|
|
||||||
ioctl_reset(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scsi_card_init();
|
scsi_card_init();
|
||||||
|
|
||||||
@@ -566,8 +524,6 @@ pc_reset_hard_close(void)
|
|||||||
void
|
void
|
||||||
pc_reset_hard_init(void)
|
pc_reset_hard_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
/* First, we reset the modules that are not part of the
|
/* First, we reset the modules that are not part of the
|
||||||
* actual machine, but which support some of the modules
|
* actual machine, but which support some of the modules
|
||||||
* that are.
|
* that are.
|
||||||
@@ -662,15 +618,7 @@ pc_reset_hard_init(void)
|
|||||||
shadowbios = 0;
|
shadowbios = 0;
|
||||||
cpu_cache_int_enabled = cpu_cache_ext_enabled = 0;
|
cpu_cache_int_enabled = cpu_cache_ext_enabled = 0;
|
||||||
|
|
||||||
for (i=0; i<CDROM_NUM; i++) {
|
cdrom_hard_reset();
|
||||||
if (cdrom_drives[i].host_drive == 200) {
|
|
||||||
image_reset(i);
|
|
||||||
}
|
|
||||||
else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z'))
|
|
||||||
{
|
|
||||||
ioctl_reset(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* Handling of the SCSI controllers.
|
* Handling of the SCSI controllers.
|
||||||
*
|
*
|
||||||
* Version: @(#)scsi.c 1.0.7 2017/10/03
|
* Version: @(#)scsi.c 1.0.8 2017/10/07
|
||||||
*
|
*
|
||||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||||
* Miran Grca, <mgrca8@gmail.com>
|
* Miran Grca, <mgrca8@gmail.com>
|
||||||
@@ -30,10 +30,15 @@
|
|||||||
#include "scsi.h"
|
#include "scsi.h"
|
||||||
#include "scsi_aha154x.h"
|
#include "scsi_aha154x.h"
|
||||||
#include "scsi_buslogic.h"
|
#include "scsi_buslogic.h"
|
||||||
|
#ifdef DEV_BRANCH
|
||||||
|
#ifdef USE_NCR
|
||||||
|
#include "scsi_ncr5380.h"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
scsi_device_t SCSIDevices[SCSI_ID_MAX][SCSI_LUN_MAX];
|
scsi_device_t SCSIDevices[SCSI_ID_MAX][SCSI_LUN_MAX];
|
||||||
uint8_t SCSIPhase = SCSI_PHASE_BUS_FREE;
|
uint8_t SCSIPhase = 0xff;
|
||||||
uint8_t SCSIStatus = SCSI_STATUS_OK;
|
uint8_t SCSIStatus = SCSI_STATUS_OK;
|
||||||
uint8_t scsi_cdrom_id = 3; /*common setting*/
|
uint8_t scsi_cdrom_id = 3; /*common setting*/
|
||||||
char scsi_fn[SCSI_NUM][512];
|
char scsi_fn[SCSI_NUM][512];
|
||||||
@@ -42,6 +47,8 @@ uint16_t scsi_hd_location[SCSI_NUM];
|
|||||||
int scsi_card_current = 0;
|
int scsi_card_current = 0;
|
||||||
int scsi_card_last = 0;
|
int scsi_card_last = 0;
|
||||||
|
|
||||||
|
uint32_t SCSI_BufferLength;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char name[64];
|
char name[64];
|
||||||
@@ -59,6 +66,13 @@ static SCSI_CARD scsi_cards[] = {
|
|||||||
{ "Adaptec AHA-1640", "aha1640", &aha1640_device, aha_device_reset },
|
{ "Adaptec AHA-1640", "aha1640", &aha1640_device, aha_device_reset },
|
||||||
{ "BusLogic BT-545C", "bt545c", &buslogic_device, BuslogicDeviceReset },
|
{ "BusLogic BT-545C", "bt545c", &buslogic_device, BuslogicDeviceReset },
|
||||||
{ "BusLogic BT-958D PCI", "bt958d", &buslogic_pci_device, BuslogicDeviceReset },
|
{ "BusLogic BT-958D PCI", "bt958d", &buslogic_pci_device, BuslogicDeviceReset },
|
||||||
|
#ifdef DEV_BRANCH
|
||||||
|
#ifdef USE_NCR
|
||||||
|
{ "Longshine LCS-6821N", "lcs6821n", &scsi_lcs6821n_device,NULL },
|
||||||
|
{ "Ranco RT1000B", "rt1000b", &scsi_rt1000b_device, NULL },
|
||||||
|
{ "Trantor T130B", "t130b", &scsi_t130b_device, NULL },
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
{ "", "", NULL, NULL },
|
{ "", "", NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* SCSI controller handler header.
|
* SCSI controller handler header.
|
||||||
*
|
*
|
||||||
* Version: @(#)scsi_h 1.0.6 2017/10/04
|
* Version: @(#)scsi_h 1.0.7 2017/10/07
|
||||||
*
|
*
|
||||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||||
* Miran Grca, <mgrca8@gmail.com>
|
* Miran Grca, <mgrca8@gmail.com>
|
||||||
@@ -211,15 +211,6 @@ extern uint8_t page_current;
|
|||||||
#define PAGE_CHANGEABLE 1
|
#define PAGE_CHANGEABLE 1
|
||||||
#define PAGE_CHANGED 2
|
#define PAGE_CHANGED 2
|
||||||
|
|
||||||
|
|
||||||
extern uint32_t DataLength;
|
|
||||||
extern uint32_t DataPointer;
|
|
||||||
|
|
||||||
extern int SectorLBA;
|
|
||||||
extern int SectorLen;
|
|
||||||
|
|
||||||
extern int MediaPresent;
|
|
||||||
|
|
||||||
extern uint8_t SCSIStatus;
|
extern uint8_t SCSIStatus;
|
||||||
extern uint8_t SCSIPhase;
|
extern uint8_t SCSIPhase;
|
||||||
extern uint8_t scsi_cdrom_id;
|
extern uint8_t scsi_cdrom_id;
|
||||||
@@ -242,21 +233,37 @@ extern int prev_status;
|
|||||||
|
|
||||||
#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f)
|
#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f)
|
||||||
|
|
||||||
#define SCSI_PHASE_DATAOUT ( 0 )
|
#define MSG_COMMAND_COMPLETE 0x00
|
||||||
#define SCSI_PHASE_DATAIN ( 1 )
|
|
||||||
#define SCSI_PHASE_COMMAND ( 2 )
|
|
||||||
#define SCSI_PHASE_STATUS ( 3 )
|
|
||||||
#define SCSI_PHASE_MESSAGE_OUT ( 6 )
|
|
||||||
#define SCSI_PHASE_MESSAGE_IN ( 7 )
|
|
||||||
#define SCSI_PHASE_BUS_FREE ( 8 )
|
|
||||||
#define SCSI_PHASE_SELECT ( 9 )
|
|
||||||
|
|
||||||
|
#define BUS_DBP 0x01
|
||||||
|
#define BUS_SEL 0x02
|
||||||
|
#define BUS_IO 0x04
|
||||||
|
#define BUS_CD 0x08
|
||||||
|
#define BUS_MSG 0x10
|
||||||
|
#define BUS_REQ 0x20
|
||||||
|
#define BUS_BSY 0x40
|
||||||
|
#define BUS_RST 0x80
|
||||||
|
#define BUS_ACK 0x200
|
||||||
|
#define BUS_ATN 0x200
|
||||||
|
#define BUS_ARB 0x8000
|
||||||
|
#define BUS_SETDATA(val) ((uint32_t)val << 16)
|
||||||
|
#define BUS_GETDATA(val) ((val >> 16) & 0xff)
|
||||||
|
#define BUS_DATAMASK 0xff0000
|
||||||
|
|
||||||
|
#define BUS_IDLE (1 << 31)
|
||||||
|
|
||||||
|
#define SCSI_PHASE_DATA_OUT 0
|
||||||
|
#define SCSI_PHASE_DATA_IN BUS_IO
|
||||||
|
#define SCSI_PHASE_COMMAND BUS_CD
|
||||||
|
#define SCSI_PHASE_STATUS (BUS_CD | BUS_IO)
|
||||||
|
#define SCSI_PHASE_MESSAGE_OUT (BUS_MSG | BUS_CD)
|
||||||
|
#define SCSI_PHASE_MESSAGE_IN (BUS_MSG | BUS_CD | BUS_IO)
|
||||||
|
|
||||||
|
extern uint32_t SCSI_BufferLength;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t *CmdBuffer;
|
uint8_t *CmdBuffer;
|
||||||
uint32_t CmdBufferLength;
|
|
||||||
int LunType;
|
int LunType;
|
||||||
uint32_t InitLength;
|
|
||||||
} scsi_device_t;
|
} scsi_device_t;
|
||||||
|
|
||||||
|
|
||||||
@@ -337,4 +344,10 @@ typedef struct {
|
|||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
|
||||||
|
#define MODE_SELECT_PHASE_IDLE 0
|
||||||
|
#define MODE_SELECT_PHASE_HEADER 1
|
||||||
|
#define MODE_SELECT_PHASE_BLOCK_DESC 2
|
||||||
|
#define MODE_SELECT_PHASE_PAGE_HEADER 3
|
||||||
|
#define MODE_SELECT_PHASE_PAGE 4
|
||||||
|
|
||||||
#endif /*EMU_SCSI_H*/
|
#endif /*EMU_SCSI_H*/
|
||||||
|
|||||||
@@ -12,11 +12,10 @@
|
|||||||
*
|
*
|
||||||
* NOTE: THIS IS CURRENTLY A MESS, but will be cleaned up as I go.
|
* NOTE: THIS IS CURRENTLY A MESS, but will be cleaned up as I go.
|
||||||
*
|
*
|
||||||
* Version: @(#)scsi_aha154x.c 1.0.21 2017/10/07
|
* Version: @(#)scsi_aha154x.c 1.0.22 2017/10/08
|
||||||
*
|
*
|
||||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||||
* Original Buslogic version by SA1988 and Miran Grca.
|
* Original Buslogic version by SA1988 and Miran Grca.
|
||||||
*
|
|
||||||
* Copyright 2017 Fred N. van Kempen.
|
* Copyright 2017 Fred N. van Kempen.
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -852,7 +851,7 @@ aha_buf_alloc(Req_t *req, int Is24bit)
|
|||||||
|
|
||||||
aha_log("Data to transfer (S/G) %d\n", DataToTransfer);
|
aha_log("Data to transfer (S/G) %d\n", DataToTransfer);
|
||||||
|
|
||||||
SCSIDevices[req->TargetID][req->LUN].InitLength = DataToTransfer;
|
SCSI_BufferLength = DataToTransfer;
|
||||||
|
|
||||||
aha_log("Allocating buffer for Scatter/Gather (%i bytes)\n", DataToTransfer);
|
aha_log("Allocating buffer for Scatter/Gather (%i bytes)\n", DataToTransfer);
|
||||||
SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataToTransfer);
|
SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataToTransfer);
|
||||||
@@ -891,7 +890,7 @@ aha_buf_alloc(Req_t *req, int Is24bit)
|
|||||||
req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) {
|
req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) {
|
||||||
Address = DataPointer;
|
Address = DataPointer;
|
||||||
|
|
||||||
SCSIDevices[req->TargetID][req->LUN].InitLength = DataLength;
|
SCSI_BufferLength = DataLength;
|
||||||
|
|
||||||
aha_log("Allocating buffer for direct transfer (%i bytes)\n", DataLength);
|
aha_log("Allocating buffer for direct transfer (%i bytes)\n", DataLength);
|
||||||
SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataLength);
|
SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataLength);
|
||||||
@@ -900,7 +899,7 @@ aha_buf_alloc(Req_t *req, int Is24bit)
|
|||||||
if (DataLength > 0) {
|
if (DataLength > 0) {
|
||||||
DMAPageRead(Address,
|
DMAPageRead(Address,
|
||||||
(char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer,
|
(char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer,
|
||||||
SCSIDevices[req->TargetID][req->LUN].InitLength);
|
SCSI_BufferLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -933,7 +932,7 @@ aha_buf_free(Req_t *req)
|
|||||||
|
|
||||||
if ((DataLength != 0) && (req->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY)) {
|
if ((DataLength != 0) && (req->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY)) {
|
||||||
aha_log("Data length not 0 with TEST UNIT READY: %i (%i)\n",
|
aha_log("Data length not 0 with TEST UNIT READY: %i (%i)\n",
|
||||||
DataLength, SCSIDevices[req->TargetID][req->LUN].InitLength);
|
DataLength, SCSI_BufferLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY) {
|
if (req->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY) {
|
||||||
@@ -988,9 +987,9 @@ aha_buf_free(Req_t *req)
|
|||||||
if ((req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) ||
|
if ((req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) ||
|
||||||
(req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) {
|
(req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) {
|
||||||
/* Should be 0 when scatter/gather? */
|
/* Should be 0 when scatter/gather? */
|
||||||
if (DataLength >= SCSIDevices[req->TargetID][req->LUN].InitLength) {
|
if (DataLength >= SCSI_BufferLength) {
|
||||||
Residual = DataLength;
|
Residual = DataLength;
|
||||||
Residual -= SCSIDevices[req->TargetID][req->LUN].InitLength;
|
Residual -= SCSI_BufferLength;
|
||||||
} else {
|
} else {
|
||||||
Residual = 0;
|
Residual = 0;
|
||||||
}
|
}
|
||||||
@@ -1143,7 +1142,7 @@ aha_req_setup(aha_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
|
|||||||
aha_log("Scanning SCSI Target ID %i\n", id);
|
aha_log("Scanning SCSI Target ID %i\n", id);
|
||||||
|
|
||||||
SCSIStatus = SCSI_STATUS_OK;
|
SCSIStatus = SCSI_STATUS_OK;
|
||||||
SCSIDevices[id][lun].InitLength = 0;
|
SCSI_BufferLength = 0;
|
||||||
|
|
||||||
aha_buf_alloc(req, req->Is24bit);
|
aha_buf_alloc(req, req->Is24bit);
|
||||||
|
|
||||||
@@ -2043,6 +2042,7 @@ aha_init(device_t *info)
|
|||||||
case AHA_154xC:
|
case AHA_154xC:
|
||||||
strcpy(dev->name, "AHA-154xC");
|
strcpy(dev->name, "AHA-154xC");
|
||||||
dev->bios_path = L"roms/scsi/adaptec/aha1542c102.bin";
|
dev->bios_path = L"roms/scsi/adaptec/aha1542c102.bin";
|
||||||
|
dev->nvr_path = L"aha1540c.nvr";
|
||||||
dev->bid = 'D';
|
dev->bid = 'D';
|
||||||
dev->rom_shram = 0x3F80; /* shadow RAM address base */
|
dev->rom_shram = 0x3F80; /* shadow RAM address base */
|
||||||
dev->rom_shramsz = 128; /* size of shadow RAM */
|
dev->rom_shramsz = 128; /* size of shadow RAM */
|
||||||
@@ -2119,8 +2119,6 @@ aha_close(void *priv)
|
|||||||
|
|
||||||
if (dev)
|
if (dev)
|
||||||
{
|
{
|
||||||
dev->MailboxCount = 0;
|
|
||||||
|
|
||||||
if (dev->evt) {
|
if (dev->evt) {
|
||||||
thread_destroy_event(dev->evt);
|
thread_destroy_event(dev->evt);
|
||||||
dev->evt = NULL;
|
dev->evt = NULL;
|
||||||
@@ -2249,9 +2247,15 @@ static device_config_t aha_154x_config[] = {
|
|||||||
|
|
||||||
device_t aha1540b_device = {
|
device_t aha1540b_device = {
|
||||||
"Adaptec AHA-1540B",
|
"Adaptec AHA-1540B",
|
||||||
0, AHA_154xB,
|
0,
|
||||||
aha_init, aha_close, NULL,
|
AHA_154xB,
|
||||||
NULL, NULL, NULL, NULL,
|
aha_init,
|
||||||
|
aha_close,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
aha_154x_config
|
aha_154x_config
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2259,8 +2263,13 @@ device_t aha1542c_device = {
|
|||||||
"Adaptec AHA-1542C",
|
"Adaptec AHA-1542C",
|
||||||
0,
|
0,
|
||||||
AHA_154xC,
|
AHA_154xC,
|
||||||
aha_init, aha_close, NULL,
|
aha_init,
|
||||||
NULL, NULL, NULL, NULL,
|
aha_close,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
aha_154x_config
|
aha_154x_config
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2268,8 +2277,13 @@ device_t aha1542cf_device = {
|
|||||||
"Adaptec AHA-1542CF",
|
"Adaptec AHA-1542CF",
|
||||||
0,
|
0,
|
||||||
AHA_154xCF,
|
AHA_154xCF,
|
||||||
aha_init, aha_close, NULL,
|
aha_init,
|
||||||
NULL, NULL, NULL, NULL,
|
aha_close,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
aha_154x_config
|
aha_154x_config
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2277,7 +2291,11 @@ device_t aha1640_device = {
|
|||||||
"Adaptec AHA-1640",
|
"Adaptec AHA-1640",
|
||||||
DEVICE_MCA,
|
DEVICE_MCA,
|
||||||
AHA_1640,
|
AHA_1640,
|
||||||
aha_init, aha_close, NULL,
|
aha_init,
|
||||||
NULL, NULL, NULL, NULL,
|
aha_close,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* The shared AHA and Buslogic SCSI BIOS command handler.
|
* The shared AHA and Buslogic SCSI BIOS command handler.
|
||||||
*
|
*
|
||||||
* Version: @(#)scsi_bios_command.c 1.0.3 2017/10/04
|
* Version: @(#)scsi_bios_command.c 1.0.4 2017/10/07
|
||||||
*
|
*
|
||||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||||
* Miran Grca, <mgrca8@gmail.com>
|
* Miran Grca, <mgrca8@gmail.com>
|
||||||
@@ -200,7 +200,7 @@ scsi_bios_command(uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
|||||||
|
|
||||||
/* Get pointer to selected device. */
|
/* Get pointer to selected device. */
|
||||||
dev = &SCSIDevices[cmd->id][cmd->lun];
|
dev = &SCSIDevices[cmd->id][cmd->lun];
|
||||||
dev->InitLength = 0;
|
SCSI_BufferLength = 0;
|
||||||
|
|
||||||
if (! scsi_device_present(cmd->id, cmd->lun)) {
|
if (! scsi_device_present(cmd->id, cmd->lun)) {
|
||||||
cmd_log("BIOS Target ID %i and LUN %i have no device attached\n",
|
cmd_log("BIOS Target ID %i and LUN %i have no device attached\n",
|
||||||
@@ -232,7 +232,7 @@ scsi_bios_command(uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
|||||||
* length for SCSI sense, and no command-specific
|
* length for SCSI sense, and no command-specific
|
||||||
* indication is given.
|
* indication is given.
|
||||||
*/
|
*/
|
||||||
dev->InitLength = 14;
|
SCSI_BufferLength = 14;
|
||||||
dev->CmdBuffer = (uint8_t *)malloc(14);
|
dev->CmdBuffer = (uint8_t *)malloc(14);
|
||||||
memset(dev->CmdBuffer, 0x00, 14);
|
memset(dev->CmdBuffer, 0x00, 14);
|
||||||
|
|
||||||
@@ -257,9 +257,9 @@ scsi_bios_command(uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
|||||||
case 0x02: /* Read Desired Sectors to Memory */
|
case 0x02: /* Read Desired Sectors to Memory */
|
||||||
target_check(cmd->id, cmd->lun);
|
target_check(cmd->id, cmd->lun);
|
||||||
|
|
||||||
dev->InitLength = sector_len << block_shift;
|
SCSI_BufferLength = sector_len << block_shift;
|
||||||
dev->CmdBuffer = (uint8_t *)malloc(dev->InitLength);
|
dev->CmdBuffer = (uint8_t *)malloc(SCSI_BufferLength);
|
||||||
memset(dev->CmdBuffer, 0x00, dev->InitLength);
|
memset(dev->CmdBuffer, 0x00, SCSI_BufferLength);
|
||||||
|
|
||||||
cdb[0] = GPCMD_READ_10;
|
cdb[0] = GPCMD_READ_10;
|
||||||
cdb[1] = (cmd->lun & 7) << 5;
|
cdb[1] = (cmd->lun & 7) << 5;
|
||||||
@@ -276,9 +276,9 @@ scsi_bios_command(uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
|||||||
scsi_device_command(cmd->id, cmd->lun, 12, cdb);
|
scsi_device_command(cmd->id, cmd->lun, 12, cdb);
|
||||||
if (sector_len > 0) {
|
if (sector_len > 0) {
|
||||||
cmd_log("BIOS DMA: Reading %i bytes at %08X\n",
|
cmd_log("BIOS DMA: Reading %i bytes at %08X\n",
|
||||||
dev->InitLength, dma_address);
|
SCSI_BufferLength, dma_address);
|
||||||
DMAPageWrite(dma_address,
|
DMAPageWrite(dma_address,
|
||||||
(char *)dev->CmdBuffer, dev->InitLength);
|
(char *)dev->CmdBuffer, SCSI_BufferLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->CmdBuffer != NULL) {
|
if (dev->CmdBuffer != NULL) {
|
||||||
@@ -291,15 +291,15 @@ scsi_bios_command(uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
|||||||
case 0x03: /* Write Desired Sectors from Memory */
|
case 0x03: /* Write Desired Sectors from Memory */
|
||||||
target_check(cmd->id, cmd->lun);
|
target_check(cmd->id, cmd->lun);
|
||||||
|
|
||||||
dev->InitLength = sector_len << block_shift;
|
SCSI_BufferLength = sector_len << block_shift;
|
||||||
dev->CmdBuffer = (uint8_t *)malloc(dev->InitLength);
|
dev->CmdBuffer = (uint8_t *)malloc(SCSI_BufferLength);
|
||||||
memset(dev->CmdBuffer, 0x00, dev->InitLength);
|
memset(dev->CmdBuffer, 0x00, SCSI_BufferLength);
|
||||||
|
|
||||||
if (sector_len > 0) {
|
if (sector_len > 0) {
|
||||||
cmd_log("BIOS DMA: Reading %i bytes at %08X\n",
|
cmd_log("BIOS DMA: Reading %i bytes at %08X\n",
|
||||||
dev->InitLength, dma_address);
|
SCSI_BufferLength, dma_address);
|
||||||
DMAPageRead(dma_address,
|
DMAPageRead(dma_address,
|
||||||
(char *)dev->CmdBuffer, dev->InitLength);
|
(char *)dev->CmdBuffer, SCSI_BufferLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
cdb[0] = GPCMD_WRITE_10;
|
cdb[0] = GPCMD_WRITE_10;
|
||||||
@@ -360,15 +360,15 @@ scsi_bios_command(uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
|||||||
case 0x08: /* Read Drive Parameters */
|
case 0x08: /* Read Drive Parameters */
|
||||||
target_check(cmd->id, cmd->lun);
|
target_check(cmd->id, cmd->lun);
|
||||||
|
|
||||||
dev->InitLength = 6;
|
SCSI_BufferLength = 6;
|
||||||
dev->CmdBuffer = (uint8_t *)malloc(dev->InitLength);
|
dev->CmdBuffer = (uint8_t *)malloc(SCSI_BufferLength);
|
||||||
memset(dev->CmdBuffer, 0x00, dev->InitLength);
|
memset(dev->CmdBuffer, 0x00, SCSI_BufferLength);
|
||||||
|
|
||||||
ret = scsi_bios_command_08(cmd->id, cmd->lun, dev->CmdBuffer);
|
ret = scsi_bios_command_08(cmd->id, cmd->lun, dev->CmdBuffer);
|
||||||
|
|
||||||
cmd_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address);
|
cmd_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address);
|
||||||
DMAPageWrite(dma_address,
|
DMAPageWrite(dma_address,
|
||||||
(char *)dev->CmdBuffer, dev->InitLength);
|
(char *)dev->CmdBuffer, SCSI_BufferLength);
|
||||||
|
|
||||||
if (dev->CmdBuffer != NULL) {
|
if (dev->CmdBuffer != NULL) {
|
||||||
free(dev->CmdBuffer);
|
free(dev->CmdBuffer);
|
||||||
@@ -385,7 +385,7 @@ scsi_bios_command(uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
|||||||
target_check(cmd->id, cmd->lun);
|
target_check(cmd->id, cmd->lun);
|
||||||
|
|
||||||
//FIXME: is this needed? Looks like a copy-paste leftover.. --FvK
|
//FIXME: is this needed? Looks like a copy-paste leftover.. --FvK
|
||||||
dev->InitLength = sector_len << block_shift;
|
SCSI_BufferLength = sector_len << block_shift;
|
||||||
|
|
||||||
cdb[0] = GPCMD_SEEK_10;
|
cdb[0] = GPCMD_SEEK_10;
|
||||||
cdb[1] = (cmd->lun & 7) << 5;
|
cdb[1] = (cmd->lun & 7) << 5;
|
||||||
@@ -429,15 +429,15 @@ scsi_bios_command(uint8_t max_id, BIOSCMD *cmd, int8_t islba)
|
|||||||
case 0x15: /* Read DASD Type */
|
case 0x15: /* Read DASD Type */
|
||||||
target_check(cmd->id, cmd->lun);
|
target_check(cmd->id, cmd->lun);
|
||||||
|
|
||||||
dev->InitLength = 6;
|
SCSI_BufferLength = 6;
|
||||||
dev->CmdBuffer = (uint8_t *)malloc(dev->InitLength);
|
dev->CmdBuffer = (uint8_t *)malloc(SCSI_BufferLength);
|
||||||
memset(dev->CmdBuffer, 0x00, dev->InitLength);
|
memset(dev->CmdBuffer, 0x00, SCSI_BufferLength);
|
||||||
|
|
||||||
ret = scsi_bios_command_15(cmd->id, cmd->lun, dev->CmdBuffer);
|
ret = scsi_bios_command_15(cmd->id, cmd->lun, dev->CmdBuffer);
|
||||||
|
|
||||||
cmd_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address);
|
cmd_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address);
|
||||||
DMAPageWrite(dma_address,
|
DMAPageWrite(dma_address,
|
||||||
(char *)dev->CmdBuffer, dev->InitLength);
|
(char *)dev->CmdBuffer, SCSI_BufferLength);
|
||||||
|
|
||||||
if (dev->CmdBuffer != NULL) {
|
if (dev->CmdBuffer != NULL) {
|
||||||
free(dev->CmdBuffer);
|
free(dev->CmdBuffer);
|
||||||
|
|||||||
363
src/scsi/scsi_bus.c
Normal file
363
src/scsi/scsi_bus.c
Normal file
@@ -0,0 +1,363 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* The generic SCSI bus operations handler.
|
||||||
|
*
|
||||||
|
* Version: @(#)scsi_bus.c 1.0.1 2017/10/04
|
||||||
|
*
|
||||||
|
* NOTES: For now ported from PCem with some modifications
|
||||||
|
* but at least it's a start.
|
||||||
|
*
|
||||||
|
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||||
|
*/
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include "../ibm.h"
|
||||||
|
#include "scsi.h"
|
||||||
|
#include "scsi_device.h"
|
||||||
|
|
||||||
|
#define STATE_IDLE 0
|
||||||
|
#define STATE_COMMAND 1
|
||||||
|
#define STATE_COMMANDWAIT 2
|
||||||
|
#define STATE_DATAIN 3
|
||||||
|
#define STATE_DATAOUT 4
|
||||||
|
#define STATE_STATUS 5
|
||||||
|
#define STATE_MESSAGEIN 6
|
||||||
|
#define STATE_PHASESEL 7
|
||||||
|
|
||||||
|
#define SET_BUS_STATE(bus, state) bus->bus_out = (bus->bus_out & ~(SCSI_PHASE_MESSAGE_IN)) | (state & (SCSI_PHASE_MESSAGE_IN))
|
||||||
|
|
||||||
|
uint32_t SCSI_BufferLength;
|
||||||
|
|
||||||
|
#define ENABLE_SCSI_BUS_LOG 0
|
||||||
|
int scsi_bus_do_log = 0;
|
||||||
|
|
||||||
|
|
||||||
|
void scsi_bus_log(const char *format, ...)
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_SCSI_BUS_LOG
|
||||||
|
if (scsi_bus_do_log)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
vprintf(format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* get the length of a SCSI command based on its command byte type */
|
||||||
|
static int get_cmd_len(int cbyte)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
int group;
|
||||||
|
|
||||||
|
group = (cbyte>>5) & 7;
|
||||||
|
|
||||||
|
if (group == 0) len = 6;
|
||||||
|
if (group == 1 || group == 2) len = 10;
|
||||||
|
if (group == 5) len = 12;
|
||||||
|
|
||||||
|
//scsi_bus_log("Command group %d, length %d\n", group, len);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_dev_id(uint8_t data)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
|
for (c = 0; c < SCSI_ID_MAX; c++)
|
||||||
|
{
|
||||||
|
if (data & (1 << c))
|
||||||
|
{
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scsi_bus_update(scsi_bus_t *bus, int bus_assert)
|
||||||
|
{
|
||||||
|
scsi_device_t *dev;
|
||||||
|
uint8_t lun = 0;
|
||||||
|
|
||||||
|
dev = &SCSIDevices[bus->dev_id][0];
|
||||||
|
|
||||||
|
if (bus_assert & BUS_ARB)
|
||||||
|
bus->state = STATE_IDLE;
|
||||||
|
|
||||||
|
dev->CmdBuffer = (uint8_t *)bus->buffer;
|
||||||
|
|
||||||
|
switch (bus->state)
|
||||||
|
{
|
||||||
|
case STATE_IDLE:
|
||||||
|
scsi_bus_log("State Idle\n");
|
||||||
|
bus->clear_req = bus->change_state_delay = bus->new_req_delay = 0;
|
||||||
|
if ((bus_assert & BUS_SEL) && !(bus_assert & BUS_BSY))
|
||||||
|
{
|
||||||
|
uint8_t sel_data = BUS_GETDATA(bus_assert);
|
||||||
|
|
||||||
|
bus->dev_id = get_dev_id(sel_data);
|
||||||
|
if (scsi_device_present(bus->dev_id, 0))
|
||||||
|
{
|
||||||
|
bus->bus_out |= BUS_BSY;
|
||||||
|
bus->state = STATE_PHASESEL;
|
||||||
|
}
|
||||||
|
//scsi_bus_log("Device id %i\n", bus->dev_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_PHASESEL:
|
||||||
|
scsi_bus_log("State Phase Sel\n");
|
||||||
|
if (!(bus_assert & BUS_SEL))
|
||||||
|
{
|
||||||
|
if (!(bus_assert & BUS_ATN))
|
||||||
|
{
|
||||||
|
if (scsi_device_present(bus->dev_id, 0))
|
||||||
|
{
|
||||||
|
bus->state = STATE_COMMAND;
|
||||||
|
bus->bus_out = BUS_BSY | BUS_REQ;
|
||||||
|
bus->command_pos = 0;
|
||||||
|
SET_BUS_STATE(bus, SCSI_PHASE_COMMAND);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bus->state = STATE_IDLE;
|
||||||
|
bus->bus_out = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fatal("dropped sel %x\n", bus_assert & BUS_ATN);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_COMMAND:
|
||||||
|
if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK))
|
||||||
|
{
|
||||||
|
scsi_bus_log("State Command\n");
|
||||||
|
bus->command[bus->command_pos++] = BUS_GETDATA(bus_assert);
|
||||||
|
|
||||||
|
bus->clear_req = 3;
|
||||||
|
bus->new_state = bus->bus_out & SCSI_PHASE_MESSAGE_IN;
|
||||||
|
bus->bus_out &= ~BUS_REQ;
|
||||||
|
|
||||||
|
if (get_cmd_len(bus->command[0]) == bus->command_pos)
|
||||||
|
{
|
||||||
|
lun = (bus->command[1] >> 5) & 7;
|
||||||
|
bus->data_pos = 0;
|
||||||
|
|
||||||
|
scsi_bus_log("Command 0x%02X\n", bus->command[0]);
|
||||||
|
|
||||||
|
SCSI_BufferLength = -1;
|
||||||
|
scsi_device_command_phase0(bus->dev_id, lun, get_cmd_len(bus->command[0]), bus->command);
|
||||||
|
|
||||||
|
if (SCSIPhase == SCSI_PHASE_DATA_OUT)
|
||||||
|
{
|
||||||
|
/* Write direction commands have delayed execution - only execute them after the bus has gotten all the data from the host. */
|
||||||
|
scsi_bus_log("Next state is data out\n");
|
||||||
|
|
||||||
|
bus->state = STATE_COMMANDWAIT;
|
||||||
|
bus->clear_req = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Other command - execute immediately. */
|
||||||
|
scsi_bus_log("Next state is defined by command\n");
|
||||||
|
bus->new_state = SCSIPhase;
|
||||||
|
|
||||||
|
bus->change_state_delay = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_COMMANDWAIT:
|
||||||
|
bus->new_state = SCSI_PHASE_DATA_OUT;
|
||||||
|
bus->change_state_delay = 4;
|
||||||
|
bus->clear_req = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_DATAIN:
|
||||||
|
if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK))
|
||||||
|
{
|
||||||
|
scsi_bus_log("State Data In\n");
|
||||||
|
|
||||||
|
/* This seems to be read, so we first execute the command, then we return the bytes to the host. */
|
||||||
|
|
||||||
|
if (bus->data_pos >= SCSI_BufferLength)
|
||||||
|
{
|
||||||
|
bus->bus_out &= ~BUS_REQ;
|
||||||
|
bus->new_state = SCSI_PHASE_STATUS;
|
||||||
|
bus->change_state_delay = 4;
|
||||||
|
bus->new_req_delay = 8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint8_t val = dev->CmdBuffer[bus->data_pos++];
|
||||||
|
|
||||||
|
bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(val) | BUS_DBP | BUS_REQ;
|
||||||
|
bus->clear_req = 3;
|
||||||
|
bus->bus_out &= ~BUS_REQ;
|
||||||
|
bus->new_state = SCSI_PHASE_DATA_IN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_DATAOUT:
|
||||||
|
if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK))
|
||||||
|
{
|
||||||
|
scsi_bus_log("State Data Out\n");
|
||||||
|
|
||||||
|
/* This is write, so first get the data from the host, then execute the last phase of the command. */
|
||||||
|
dev->CmdBuffer[bus->data_pos++] = BUS_GETDATA(bus_assert);
|
||||||
|
|
||||||
|
if (bus->data_pos >= SCSI_BufferLength)
|
||||||
|
{
|
||||||
|
/* pclog("%04X bytes written (%02X %02X)\n", bus->data_pos, bus->command[0], bus->command[1]); */
|
||||||
|
scsi_bus_log("Actually executing write command\n");
|
||||||
|
lun = (bus->command[1] >> 5) & 7;
|
||||||
|
bus->bus_out &= ~BUS_REQ;
|
||||||
|
scsi_device_command_phase1(bus->dev_id, lun);
|
||||||
|
bus->new_state = SCSI_PHASE_STATUS;
|
||||||
|
bus->change_state_delay = 4;
|
||||||
|
bus->new_req_delay = 8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bus->bus_out |= BUS_REQ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_STATUS:
|
||||||
|
scsi_bus_log("State Status\n");
|
||||||
|
|
||||||
|
if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK))
|
||||||
|
{
|
||||||
|
/* pclog("Preparing for message in\n"); */
|
||||||
|
bus->bus_out &= ~BUS_REQ;
|
||||||
|
bus->new_state = SCSI_PHASE_MESSAGE_IN;
|
||||||
|
bus->change_state_delay = 4;
|
||||||
|
bus->new_req_delay = 8;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_MESSAGEIN:
|
||||||
|
scsi_bus_log("State Message In\n");
|
||||||
|
|
||||||
|
if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK))
|
||||||
|
{
|
||||||
|
bus->bus_out &= ~BUS_REQ;
|
||||||
|
bus->new_state = BUS_IDLE;
|
||||||
|
bus->change_state_delay = 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bus->bus_in = bus_assert;
|
||||||
|
|
||||||
|
return bus->bus_out | bus->bus_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scsi_bus_read(scsi_bus_t *bus)
|
||||||
|
{
|
||||||
|
scsi_device_t *dev;
|
||||||
|
|
||||||
|
dev = &SCSIDevices[bus->dev_id][0];
|
||||||
|
|
||||||
|
dev->CmdBuffer = (uint8_t *)bus->buffer;
|
||||||
|
|
||||||
|
if (bus->clear_req)
|
||||||
|
{
|
||||||
|
bus->clear_req--;
|
||||||
|
if (!bus->clear_req)
|
||||||
|
{
|
||||||
|
scsi_bus_log("Clear REQ\n");
|
||||||
|
|
||||||
|
SET_BUS_STATE(bus, bus->new_state);
|
||||||
|
bus->bus_out |= BUS_REQ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bus->change_state_delay)
|
||||||
|
{
|
||||||
|
bus->change_state_delay--;
|
||||||
|
if (!bus->change_state_delay)
|
||||||
|
{
|
||||||
|
uint8_t val;
|
||||||
|
|
||||||
|
scsi_bus_log("Change state delay\n");
|
||||||
|
|
||||||
|
SET_BUS_STATE(bus, bus->new_state);
|
||||||
|
|
||||||
|
switch (bus->bus_out & SCSI_PHASE_MESSAGE_IN)
|
||||||
|
{
|
||||||
|
case SCSI_PHASE_DATA_IN:
|
||||||
|
scsi_bus_log("Phase data in\n");
|
||||||
|
bus->state = STATE_DATAIN;
|
||||||
|
val = dev->CmdBuffer[bus->data_pos++];
|
||||||
|
bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(val) | BUS_DBP;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCSI_PHASE_DATA_OUT:
|
||||||
|
scsi_bus_log("Phase data out\n");
|
||||||
|
if (bus->new_state & BUS_IDLE)
|
||||||
|
{
|
||||||
|
bus->state = STATE_IDLE;
|
||||||
|
bus->bus_out &= ~BUS_BSY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bus->state = STATE_DATAOUT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCSI_PHASE_STATUS:
|
||||||
|
scsi_bus_log("Phase status\n");
|
||||||
|
bus->state = STATE_STATUS;
|
||||||
|
bus->bus_out |= BUS_REQ;
|
||||||
|
bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(SCSIStatus) | BUS_DBP;
|
||||||
|
/* pclog("SCSI Status (command %02X): %02X (%08X)\n", bus->command[0], SCSIStatus, bus->bus_out); */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SCSI_PHASE_MESSAGE_IN:
|
||||||
|
scsi_bus_log("Phase message in\n");
|
||||||
|
/* pclog("Message in\n"); */
|
||||||
|
bus->state = STATE_MESSAGEIN;
|
||||||
|
bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(0) | BUS_DBP;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
fatal("change_state_delay bad state %x\n", bus->bus_out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bus->new_req_delay)
|
||||||
|
{
|
||||||
|
bus->new_req_delay--;
|
||||||
|
if (!bus->new_req_delay)
|
||||||
|
{
|
||||||
|
bus->bus_out |= BUS_REQ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bus->bus_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scsi_bus_match(scsi_bus_t *bus, int bus_assert)
|
||||||
|
{
|
||||||
|
return (bus_assert & (BUS_CD | BUS_IO | BUS_MSG)) == (bus->bus_out & (BUS_CD | BUS_IO | BUS_MSG));
|
||||||
|
}
|
||||||
@@ -10,12 +10,11 @@
|
|||||||
* 0 - BT-545C ISA;
|
* 0 - BT-545C ISA;
|
||||||
* 1 - BT-958D PCI (but BT-545C ISA on non-PCI machines)
|
* 1 - BT-958D PCI (but BT-545C ISA on non-PCI machines)
|
||||||
*
|
*
|
||||||
* Version: @(#)scsi_buslogic.c 1.0.17 2017/10/07
|
* Version: @(#)scsi_buslogic.c 1.0.18 2017/10/08
|
||||||
*
|
*
|
||||||
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
* Authors: TheCollector1995, <mariogplayer@gmail.com>
|
||||||
* Miran Grca, <mgrca8@gmail.com>
|
* Miran Grca, <mgrca8@gmail.com>
|
||||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||||
*
|
|
||||||
* Copyright 2016,2017 Miran Grca.
|
* Copyright 2016,2017 Miran Grca.
|
||||||
* Copyright 2017 Fred N. van Kempen.
|
* Copyright 2017 Fred N. van Kempen.
|
||||||
*/
|
*/
|
||||||
@@ -42,7 +41,7 @@
|
|||||||
#include "scsi_buslogic.h"
|
#include "scsi_buslogic.h"
|
||||||
|
|
||||||
|
|
||||||
#define BUSLOGIC_RESET_DURATION_US UINT64_C(50)
|
#define BUSLOGIC_RESET_DURATION_US UINT64_C(5000)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1020,7 +1019,7 @@ BuslogicDataBufferAllocate(Req_t *req, int Is24bit)
|
|||||||
|
|
||||||
pclog("Data to transfer (S/G) %d\n", DataToTransfer);
|
pclog("Data to transfer (S/G) %d\n", DataToTransfer);
|
||||||
|
|
||||||
SCSIDevices[req->TargetID][req->LUN].InitLength = DataToTransfer;
|
SCSI_BufferLength = DataToTransfer;
|
||||||
|
|
||||||
SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataToTransfer);
|
SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataToTransfer);
|
||||||
memset(SCSIDevices[req->TargetID][req->LUN].CmdBuffer, 0, DataToTransfer);
|
memset(SCSIDevices[req->TargetID][req->LUN].CmdBuffer, 0, DataToTransfer);
|
||||||
@@ -1060,7 +1059,7 @@ BuslogicDataBufferAllocate(Req_t *req, int Is24bit)
|
|||||||
req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) {
|
req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) {
|
||||||
uint32_t Address = DataPointer;
|
uint32_t Address = DataPointer;
|
||||||
|
|
||||||
SCSIDevices[req->TargetID][req->LUN].InitLength = DataLength;
|
SCSI_BufferLength = DataLength;
|
||||||
|
|
||||||
SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataLength);
|
SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataLength);
|
||||||
memset(SCSIDevices[req->TargetID][req->LUN].CmdBuffer, 0, DataLength);
|
memset(SCSIDevices[req->TargetID][req->LUN].CmdBuffer, 0, DataLength);
|
||||||
@@ -1068,7 +1067,7 @@ BuslogicDataBufferAllocate(Req_t *req, int Is24bit)
|
|||||||
if (DataLength > 0) {
|
if (DataLength > 0) {
|
||||||
DMAPageRead(Address,
|
DMAPageRead(Address,
|
||||||
(char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer,
|
(char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer,
|
||||||
SCSIDevices[req->TargetID][req->LUN].InitLength);
|
SCSI_BufferLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1100,7 +1099,7 @@ BuslogicDataBufferFree(Req_t *req)
|
|||||||
|
|
||||||
if ((DataLength != 0) && (req->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY)) {
|
if ((DataLength != 0) && (req->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY)) {
|
||||||
pclog("Data length not 0 with TEST UNIT READY: %i (%i)\n",
|
pclog("Data length not 0 with TEST UNIT READY: %i (%i)\n",
|
||||||
DataLength, SCSIDevices[req->TargetID][req->LUN].InitLength);
|
DataLength, SCSI_BufferLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY) {
|
if (req->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY) {
|
||||||
@@ -1157,9 +1156,9 @@ BuslogicDataBufferFree(Req_t *req)
|
|||||||
if ((req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) ||
|
if ((req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) ||
|
||||||
(req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) {
|
(req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) {
|
||||||
/* Should be 0 when scatter/gather? */
|
/* Should be 0 when scatter/gather? */
|
||||||
if (DataLength >= SCSIDevices[req->TargetID][req->LUN].InitLength) {
|
if (DataLength >= SCSI_BufferLength) {
|
||||||
Residual = DataLength;
|
Residual = DataLength;
|
||||||
Residual -= SCSIDevices[req->TargetID][req->LUN].InitLength;
|
Residual -= SCSI_BufferLength;
|
||||||
} else {
|
} else {
|
||||||
Residual = 0;
|
Residual = 0;
|
||||||
}
|
}
|
||||||
@@ -1219,7 +1218,7 @@ BuslogicSCSIBIOSDataBufferAllocate(ESCMD *ESCSICmd, uint8_t TargetID, uint8_t LU
|
|||||||
{
|
{
|
||||||
uint32_t Address = DataPointer;
|
uint32_t Address = DataPointer;
|
||||||
|
|
||||||
SCSIDevices[TargetID][LUN].InitLength = DataLength;
|
SCSI_BufferLength = DataLength;
|
||||||
|
|
||||||
SCSIDevices[TargetID][LUN].CmdBuffer = (uint8_t *) malloc(DataLength);
|
SCSIDevices[TargetID][LUN].CmdBuffer = (uint8_t *) malloc(DataLength);
|
||||||
memset(SCSIDevices[TargetID][LUN].CmdBuffer, 0, DataLength);
|
memset(SCSIDevices[TargetID][LUN].CmdBuffer, 0, DataLength);
|
||||||
@@ -1227,7 +1226,7 @@ BuslogicSCSIBIOSDataBufferAllocate(ESCMD *ESCSICmd, uint8_t TargetID, uint8_t LU
|
|||||||
if (DataLength > 0) {
|
if (DataLength > 0) {
|
||||||
DMAPageRead(Address,
|
DMAPageRead(Address,
|
||||||
(char *)SCSIDevices[TargetID][LUN].CmdBuffer,
|
(char *)SCSIDevices[TargetID][LUN].CmdBuffer,
|
||||||
SCSIDevices[TargetID][LUN].InitLength);
|
SCSI_BufferLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1245,7 +1244,7 @@ BuslogicSCSIBIOSDataBufferFree(ESCMD *ESCSICmd, uint8_t TargetID, uint8_t LUN)
|
|||||||
|
|
||||||
if ((DataLength != 0) && (ESCSICmd->CDB[0] == GPCMD_TEST_UNIT_READY)) {
|
if ((DataLength != 0) && (ESCSICmd->CDB[0] == GPCMD_TEST_UNIT_READY)) {
|
||||||
pclog("Data length not 0 with TEST UNIT READY: %i (%i)\n",
|
pclog("Data length not 0 with TEST UNIT READY: %i (%i)\n",
|
||||||
DataLength, SCSIDevices[TargetID][LUN].InitLength);
|
DataLength, SCSI_BufferLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ESCSICmd->CDB[0] == GPCMD_TEST_UNIT_READY) {
|
if (ESCSICmd->CDB[0] == GPCMD_TEST_UNIT_READY) {
|
||||||
@@ -1268,9 +1267,9 @@ BuslogicSCSIBIOSDataBufferFree(ESCMD *ESCSICmd, uint8_t TargetID, uint8_t LUN)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Should be 0 when scatter/gather? */
|
/* Should be 0 when scatter/gather? */
|
||||||
if (DataLength >= SCSIDevices[TargetID][LUN].InitLength) {
|
if (DataLength >= SCSI_BufferLength) {
|
||||||
Residual = DataLength;
|
Residual = DataLength;
|
||||||
Residual -= SCSIDevices[TargetID][LUN].InitLength;
|
Residual -= SCSI_BufferLength;
|
||||||
} else {
|
} else {
|
||||||
Residual = 0;
|
Residual = 0;
|
||||||
}
|
}
|
||||||
@@ -1306,7 +1305,7 @@ BuslogicSCSIBIOSRequestSetup(Buslogic_t *bl, uint8_t *CmdBuf, uint8_t *DataInBuf
|
|||||||
pclog("Scanning SCSI Target ID %i\n", ESCSICmd->TargetId);
|
pclog("Scanning SCSI Target ID %i\n", ESCSICmd->TargetId);
|
||||||
|
|
||||||
SCSIStatus = SCSI_STATUS_OK;
|
SCSIStatus = SCSI_STATUS_OK;
|
||||||
SCSIDevices[ESCSICmd->TargetId][ESCSICmd->LogicalUnit].InitLength = 0;
|
SCSI_BufferLength = 0;
|
||||||
|
|
||||||
BuslogicSCSIBIOSDataBufferAllocate(ESCSICmd, ESCSICmd->TargetId, ESCSICmd->LogicalUnit);
|
BuslogicSCSIBIOSDataBufferAllocate(ESCSICmd, ESCSICmd->TargetId, ESCSICmd->LogicalUnit);
|
||||||
|
|
||||||
@@ -2404,7 +2403,7 @@ BuslogicSCSIRequestSetup(Buslogic_t *bl, uint32_t CCBPointer, Mailbox32_t *Mailb
|
|||||||
pclog("BuslogicSCSIRequestSetup(): Scanning SCSI Target ID %i\n", Id);
|
pclog("BuslogicSCSIRequestSetup(): Scanning SCSI Target ID %i\n", Id);
|
||||||
|
|
||||||
SCSIStatus = SCSI_STATUS_OK;
|
SCSIStatus = SCSI_STATUS_OK;
|
||||||
SCSIDevices[Id][Lun].InitLength = 0;
|
SCSI_BufferLength = 0;
|
||||||
|
|
||||||
BuslogicDataBufferAllocate(req, req->Is24bit);
|
BuslogicDataBufferAllocate(req, req->Is24bit);
|
||||||
|
|
||||||
@@ -2880,6 +2879,7 @@ Buslogic_Init(device_t *info)
|
|||||||
|
|
||||||
bl = malloc(sizeof(Buslogic_t));
|
bl = malloc(sizeof(Buslogic_t));
|
||||||
memset(bl, 0x00, sizeof(Buslogic_t));
|
memset(bl, 0x00, sizeof(Buslogic_t));
|
||||||
|
|
||||||
bl->chip = info->local;
|
bl->chip = info->local;
|
||||||
if ((bl->chip == CHIP_BUSLOGIC_PCI) && !PCI)
|
if ((bl->chip == CHIP_BUSLOGIC_PCI) && !PCI)
|
||||||
{
|
{
|
||||||
@@ -3019,13 +3019,11 @@ Buslogic_Init(device_t *info)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Buslogic_Close(void *p)
|
BuslogicClose(void *p)
|
||||||
{
|
{
|
||||||
Buslogic_t *bl = (Buslogic_t *)p;
|
Buslogic_t *bl = (Buslogic_t *)p;
|
||||||
if (bl)
|
if (bl)
|
||||||
{
|
{
|
||||||
bl->MailboxCount = 0;
|
|
||||||
|
|
||||||
if (bl->evt)
|
if (bl->evt)
|
||||||
{
|
{
|
||||||
thread_destroy_event(bl->evt);
|
thread_destroy_event(bl->evt);
|
||||||
@@ -3130,8 +3128,13 @@ device_t buslogic_device = {
|
|||||||
"Buslogic BT-545C ISA",
|
"Buslogic BT-545C ISA",
|
||||||
0,
|
0,
|
||||||
CHIP_BUSLOGIC_ISA,
|
CHIP_BUSLOGIC_ISA,
|
||||||
Buslogic_Init, Buslogic_Close, NULL,
|
Buslogic_Init,
|
||||||
NULL, NULL, NULL, NULL,
|
BuslogicClose,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
BuslogicConfig
|
BuslogicConfig
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3139,7 +3142,12 @@ device_t buslogic_pci_device = {
|
|||||||
"Buslogic BT-958D PCI",
|
"Buslogic BT-958D PCI",
|
||||||
0,
|
0,
|
||||||
CHIP_BUSLOGIC_PCI,
|
CHIP_BUSLOGIC_PCI,
|
||||||
Buslogic_Init, Buslogic_Close, NULL,
|
Buslogic_Init,
|
||||||
NULL, NULL, NULL, NULL,
|
BuslogicClose,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
BuslogicConfig
|
BuslogicConfig
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* The generic SCSI device command handler.
|
* The generic SCSI device command handler.
|
||||||
*
|
*
|
||||||
* Version: @(#)scsi_device.c 1.0.5 2017/10/04
|
* Version: @(#)scsi_device.c 1.0.6 2017/10/07
|
||||||
*
|
*
|
||||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||||
@@ -277,7 +277,7 @@ int scsi_device_block_shift(uint8_t scsi_id, uint8_t scsi_lun)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void scsi_device_command(uint8_t scsi_id, uint8_t scsi_lun, int cdb_len, uint8_t *cdb)
|
void scsi_device_command_common(uint8_t scsi_id, uint8_t scsi_lun, int cdb_len, uint8_t *cdb, int multi_phase)
|
||||||
{
|
{
|
||||||
uint8_t phase = 0;
|
uint8_t phase = 0;
|
||||||
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||||
@@ -321,13 +321,51 @@ void scsi_device_command(uint8_t scsi_id, uint8_t scsi_lun, int cdb_len, uint8_t
|
|||||||
scsi_device_target_phase_callback(lun_type, id);
|
scsi_device_target_phase_callback(lun_type, id);
|
||||||
} else {
|
} else {
|
||||||
/* Command first phase complete - call the callback to execute the second phase. */
|
/* Command first phase complete - call the callback to execute the second phase. */
|
||||||
|
if (multi_phase || (SCSIPhase != SCSI_PHASE_DATA_OUT))
|
||||||
|
{
|
||||||
scsi_device_target_phase_callback(lun_type, id);
|
scsi_device_target_phase_callback(lun_type, id);
|
||||||
SCSIStatus = scsi_device_target_err_stat_to_scsi(lun_type, id);
|
SCSIStatus = scsi_device_target_err_stat_to_scsi(lun_type, id);
|
||||||
/* Command second phase complete - call the callback to complete the command. */
|
/* Command second phase complete - call the callback to complete the command. */
|
||||||
scsi_device_target_phase_callback(lun_type, id);
|
scsi_device_target_phase_callback(lun_type, id);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Error (Check Condition) - call the phase callback to complete the command. */
|
/* Error (Check Condition) - call the phase callback to complete the command. */
|
||||||
scsi_device_target_phase_callback(lun_type, id);
|
scsi_device_target_phase_callback(lun_type, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scsi_device_command(uint8_t scsi_id, uint8_t scsi_lun, int cdb_len, uint8_t *cdb)
|
||||||
|
{
|
||||||
|
scsi_device_command_common(scsi_id, scsi_lun, cdb_len, cdb, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scsi_device_command_phase0(uint8_t scsi_id, uint8_t scsi_lun, int cdb_len, uint8_t *cdb)
|
||||||
|
{
|
||||||
|
scsi_device_command_common(scsi_id, scsi_lun, cdb_len, cdb, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scsi_device_command_phase1(uint8_t scsi_id, uint8_t scsi_lun)
|
||||||
|
{
|
||||||
|
uint8_t lun_type = SCSIDevices[scsi_id][scsi_lun].LunType;
|
||||||
|
|
||||||
|
uint8_t id = 0;
|
||||||
|
|
||||||
|
switch (lun_type)
|
||||||
|
{
|
||||||
|
case SCSI_DISK:
|
||||||
|
id = scsi_hard_disks[scsi_id][scsi_lun];
|
||||||
|
break;
|
||||||
|
case SCSI_CDROM:
|
||||||
|
id = scsi_cdrom_drives[scsi_id][scsi_lun];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
id = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
scsi_device_target_phase_callback(lun_type, id);
|
||||||
|
SCSIStatus = scsi_device_target_err_stat_to_scsi(lun_type, id);
|
||||||
|
/* Command second phase complete - call the callback to complete the command. */
|
||||||
|
scsi_device_target_phase_callback(lun_type, id);
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
* Definitions for the generic SCSI device command handler.
|
* Definitions for the generic SCSI device command handler.
|
||||||
*
|
*
|
||||||
* Version: @(#)scsi_device.h 1.0.2 2017/08/22
|
* Version: @(#)scsi_device.h 1.0.3 2017/10/04
|
||||||
*
|
*
|
||||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||||
@@ -16,6 +16,22 @@
|
|||||||
#ifndef SCSI_DEVICE_H
|
#ifndef SCSI_DEVICE_H
|
||||||
# define SCSI_DEVICE_H
|
# define SCSI_DEVICE_H
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int state;
|
||||||
|
int new_state;
|
||||||
|
int clear_req;
|
||||||
|
uint32_t bus_in, bus_out;
|
||||||
|
int dev_id;
|
||||||
|
|
||||||
|
int command_pos;
|
||||||
|
uint8_t command[20];
|
||||||
|
int data_pos;
|
||||||
|
uint8_t buffer[390144];
|
||||||
|
|
||||||
|
int change_state_delay;
|
||||||
|
int new_req_delay;
|
||||||
|
} scsi_bus_t;
|
||||||
|
|
||||||
extern uint8_t *scsi_device_sense(uint8_t id, uint8_t lun);
|
extern uint8_t *scsi_device_sense(uint8_t id, uint8_t lun);
|
||||||
extern void scsi_device_type_data(uint8_t id, uint8_t lun,
|
extern void scsi_device_type_data(uint8_t id, uint8_t lun,
|
||||||
@@ -32,6 +48,13 @@ extern int scsi_device_cdb_length(uint8_t id, uint8_t lun);
|
|||||||
extern int scsi_device_block_shift(uint8_t id, uint8_t lun);
|
extern int scsi_device_block_shift(uint8_t id, uint8_t lun);
|
||||||
extern void scsi_device_command(uint8_t id, uint8_t lun, int cdb_len,
|
extern void scsi_device_command(uint8_t id, uint8_t lun, int cdb_len,
|
||||||
uint8_t *cdb);
|
uint8_t *cdb);
|
||||||
|
extern void scsi_device_command_phase0(uint8_t scsi_id, uint8_t scsi_lun,
|
||||||
|
int cdb_len, uint8_t *cdb);
|
||||||
|
extern void scsi_device_command_phase1(uint8_t scsi_id, uint8_t scsi_lun);
|
||||||
|
|
||||||
|
extern int scsi_bus_update(scsi_bus_t *bus, int bus_assert);
|
||||||
|
extern int scsi_bus_read(scsi_bus_t *bus);
|
||||||
|
extern int scsi_bus_match(scsi_bus_t *bus, int bus_assert);
|
||||||
|
|
||||||
|
|
||||||
#endif /*SCSI_DEVICE_H*/
|
#endif /*SCSI_DEVICE_H*/
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -41,6 +41,19 @@ typedef struct {
|
|||||||
int old_len;
|
int old_len;
|
||||||
int request_pos;
|
int request_pos;
|
||||||
uint8_t hd_cdb[16];
|
uint8_t hd_cdb[16];
|
||||||
|
|
||||||
|
uint64_t current_page_code;
|
||||||
|
int current_page_len;
|
||||||
|
|
||||||
|
int current_page_pos;
|
||||||
|
|
||||||
|
int mode_select_phase;
|
||||||
|
|
||||||
|
int total_length;
|
||||||
|
int written_length;
|
||||||
|
|
||||||
|
int do_page_save;
|
||||||
|
int block_descriptor_len;
|
||||||
} scsi_hard_disk_t;
|
} scsi_hard_disk_t;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
852
src/scsi/scsi_ncr5380.c
Normal file
852
src/scsi/scsi_ncr5380.c
Normal file
@@ -0,0 +1,852 @@
|
|||||||
|
/*
|
||||||
|
* 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 NCR 5380 series of SCSI Host Adapters
|
||||||
|
* made by NCR. These controllers were designed for
|
||||||
|
* the ISA bus.
|
||||||
|
*
|
||||||
|
* Version: @(#)scsi_ncr5380.c 1.0.0 2017/10/04
|
||||||
|
*
|
||||||
|
* Authors: Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||||
|
* TheCollector1995, <mariogplayer@gmail.com>
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include "../ibm.h"
|
||||||
|
#include "../io.h"
|
||||||
|
#include "../mca.h"
|
||||||
|
#include "../mem.h"
|
||||||
|
#include "../mca.h"
|
||||||
|
#include "../rom.h"
|
||||||
|
#include "../nvr.h"
|
||||||
|
#include "../dma.h"
|
||||||
|
#include "../pic.h"
|
||||||
|
#include "../timer.h"
|
||||||
|
#include "../device.h"
|
||||||
|
#include "../win/plat_thread.h"
|
||||||
|
#include "scsi.h"
|
||||||
|
#include "scsi_device.h"
|
||||||
|
#include "scsi_ncr5380.h"
|
||||||
|
|
||||||
|
#define NCR_CURDATA 0 /* current SCSI data (read only) */
|
||||||
|
#define NCR_OUTDATA 0 /* output data (write only) */
|
||||||
|
#define NCR_INITCOMMAND 1 /* initiator command (read/write) */
|
||||||
|
#define NCR_MODE 2 /* mode (read/write) */
|
||||||
|
#define NCR_TARGETCMD 3 /* target command (read/write) */
|
||||||
|
#define NCR_SELENABLE 4 /* select enable (write only) */
|
||||||
|
#define NCR_BUSSTATUS 4 /* bus status (read only) */
|
||||||
|
#define NCR_STARTDMA 5 /* start DMA send (write only) */
|
||||||
|
#define NCR_BUSANDSTAT 5 /* bus and status (read only) */
|
||||||
|
#define NCR_DMATARGET 6 /* DMA target (write only) */
|
||||||
|
#define NCR_INPUTDATA 6 /* input data (read only) */
|
||||||
|
#define NCR_DMAINIRECV 7 /* DMA initiator receive (write only) */
|
||||||
|
#define NCR_RESETPARITY 7 /* reset parity/interrupt (read only) */
|
||||||
|
|
||||||
|
#define POLL_TIME_US 10
|
||||||
|
#define MAX_BYTES_TRANSFERRED_PER_POLL 50
|
||||||
|
/*10us poll period with 50 bytes transferred per poll = 5MB/sec*/
|
||||||
|
|
||||||
|
#pragma pack(push,1)
|
||||||
|
typedef struct ncr5380_t
|
||||||
|
{
|
||||||
|
uint8_t icr;
|
||||||
|
uint8_t mode;
|
||||||
|
uint8_t tcr;
|
||||||
|
uint8_t ser;
|
||||||
|
uint8_t isr;
|
||||||
|
|
||||||
|
int target_bsy;
|
||||||
|
int target_req;
|
||||||
|
uint8_t target_id;
|
||||||
|
|
||||||
|
uint8_t bus_status;
|
||||||
|
|
||||||
|
int dma_mode;
|
||||||
|
|
||||||
|
scsi_bus_t bus;
|
||||||
|
} ncr5380_t;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#pragma pack(push,1)
|
||||||
|
typedef struct lcs6821n_t
|
||||||
|
{
|
||||||
|
rom_t bios_rom;
|
||||||
|
|
||||||
|
mem_mapping_t mapping;
|
||||||
|
|
||||||
|
uint8_t block_count;
|
||||||
|
int block_count_loaded;
|
||||||
|
|
||||||
|
uint8_t status_ctrl;
|
||||||
|
|
||||||
|
uint8_t buffer[0x80];
|
||||||
|
int buffer_pos;
|
||||||
|
int buffer_host_pos;
|
||||||
|
|
||||||
|
uint8_t int_ram[0x40];
|
||||||
|
uint8_t ext_ram[0x600];
|
||||||
|
|
||||||
|
ncr5380_t ncr;
|
||||||
|
|
||||||
|
int ncr5380_dma_enabled;
|
||||||
|
|
||||||
|
int dma_callback;
|
||||||
|
int dma_enabled;
|
||||||
|
|
||||||
|
int ncr_busy;
|
||||||
|
} lcs6821n_t;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#define ICR_DBP 0x01
|
||||||
|
#define ICR_ATN 0x02
|
||||||
|
#define ICR_SEL 0x04
|
||||||
|
#define ICR_BSY 0x08
|
||||||
|
#define ICR_ACK 0x10
|
||||||
|
#define ICR_ARB_LOST 0x20
|
||||||
|
#define ICR_ARB_IN_PROGRESS 0x40
|
||||||
|
|
||||||
|
#define MODE_ARBITRATE 0x01
|
||||||
|
#define MODE_DMA 0x02
|
||||||
|
#define MODE_MONITOR_BUSY 0x04
|
||||||
|
#define MODE_ENA_EOP_INT 0x08
|
||||||
|
|
||||||
|
#define STATUS_ACK 0x01
|
||||||
|
#define STATUS_BUSY_ERROR 0x04
|
||||||
|
#define STATUS_INT 0x10
|
||||||
|
#define STATUS_DRQ 0x40
|
||||||
|
#define STATUS_END_OF_DMA 0x80
|
||||||
|
|
||||||
|
#define TCR_IO 0x01
|
||||||
|
#define TCR_CD 0x02
|
||||||
|
#define TCR_MSG 0x04
|
||||||
|
#define TCR_REQ 0x08
|
||||||
|
#define TCR_LAST_BYTE_SENT 0x80
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
DMA_IDLE = 0,
|
||||||
|
DMA_SEND,
|
||||||
|
DMA_TARGET_RECEIVE,
|
||||||
|
DMA_INITIATOR_RECEIVE
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef ENABLE_NCR5380_LOG
|
||||||
|
int ncr5380_do_log = ENABLE_NCR5380_LOG;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
ncr5380_log(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
#if ENABLE_NCR5380_LOG
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
if (ncr5380_do_log) {
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vprintf(fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ncr53c400_dma_changed(void *p, int mode, int enable)
|
||||||
|
{
|
||||||
|
lcs6821n_t *scsi = (lcs6821n_t *)p;
|
||||||
|
|
||||||
|
scsi->ncr5380_dma_enabled = (mode && enable);
|
||||||
|
|
||||||
|
scsi->dma_enabled = (scsi->ncr5380_dma_enabled && scsi->block_count_loaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ncr5380_reset(ncr5380_t *ncr)
|
||||||
|
{
|
||||||
|
memset(ncr, 0, sizeof(ncr5380_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t get_bus_host(ncr5380_t *ncr)
|
||||||
|
{
|
||||||
|
uint32_t bus_host = 0;
|
||||||
|
|
||||||
|
if (ncr->icr & ICR_DBP)
|
||||||
|
bus_host |= BUS_DBP;
|
||||||
|
if (ncr->icr & ICR_SEL)
|
||||||
|
bus_host |= BUS_SEL;
|
||||||
|
if (ncr->icr & ICR_ATN)
|
||||||
|
bus_host |= BUS_ATN;
|
||||||
|
if (ncr->tcr & TCR_IO)
|
||||||
|
bus_host |= BUS_IO;
|
||||||
|
if (ncr->tcr & TCR_CD)
|
||||||
|
bus_host |= BUS_CD;
|
||||||
|
if (ncr->tcr & TCR_MSG)
|
||||||
|
bus_host |= BUS_MSG;
|
||||||
|
if (ncr->tcr & TCR_REQ)
|
||||||
|
bus_host |= BUS_REQ;
|
||||||
|
if (ncr->icr & ICR_BSY)
|
||||||
|
bus_host |= BUS_BSY;
|
||||||
|
if (ncr->icr & ICR_ACK)
|
||||||
|
bus_host |= BUS_ACK;
|
||||||
|
if (ncr->mode & MODE_ARBITRATE)
|
||||||
|
bus_host |= BUS_ARB;
|
||||||
|
return bus_host | BUS_SETDATA(SCSI_BufferLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ncr5380_write(uint16_t port, uint8_t val, void *priv)
|
||||||
|
{
|
||||||
|
lcs6821n_t *scsi = (lcs6821n_t *)priv;
|
||||||
|
ncr5380_t *ncr = &scsi->ncr;
|
||||||
|
int bus_host = 0;
|
||||||
|
|
||||||
|
//ncr5380_log("ncr5380_write: addr=%06x val=%02x %04x:%04x\n", port, val, CS,cpu_state.pc);
|
||||||
|
switch (port & 7)
|
||||||
|
{
|
||||||
|
case 0: /*Output data register*/
|
||||||
|
SCSI_BufferLength = val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: /*Initiator Command Register*/
|
||||||
|
if ((val & (ICR_BSY | ICR_SEL)) == (ICR_BSY | ICR_SEL) &&
|
||||||
|
(ncr->icr & (ICR_BSY | ICR_SEL)) == ICR_SEL)
|
||||||
|
{
|
||||||
|
uint8_t temp = SCSI_BufferLength & 0x7f;
|
||||||
|
|
||||||
|
ncr->target_id = -1;
|
||||||
|
while (temp)
|
||||||
|
{
|
||||||
|
temp >>= 1;
|
||||||
|
ncr->target_id++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ncr5380_log("Select - target ID = %i, temp data %x\n", ncr->target_id, temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
ncr->icr = val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: /*Mode register*/
|
||||||
|
if ((val & MODE_ARBITRATE) && !(ncr->mode & MODE_ARBITRATE))
|
||||||
|
{
|
||||||
|
ncr->icr &= ~ICR_ARB_LOST;
|
||||||
|
ncr->icr |= ICR_ARB_IN_PROGRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ncr->mode = val;
|
||||||
|
ncr53c400_dma_changed(scsi, ncr->dma_mode, ncr->mode & MODE_DMA);
|
||||||
|
if (!(ncr->mode & MODE_DMA))
|
||||||
|
{
|
||||||
|
ncr->tcr &= ~TCR_LAST_BYTE_SENT;
|
||||||
|
ncr->isr &= ~STATUS_END_OF_DMA;
|
||||||
|
ncr->dma_mode = DMA_IDLE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: /*Target Command Register*/
|
||||||
|
ncr->tcr = val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4: /*Select Enable Register*/
|
||||||
|
ncr->ser = val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5: /*Start DMA Send*/
|
||||||
|
ncr->dma_mode = DMA_SEND;
|
||||||
|
ncr53c400_dma_changed(scsi, ncr->dma_mode, ncr->mode & MODE_DMA);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7: /*Start DMA Initiator Receive*/
|
||||||
|
ncr->dma_mode = DMA_INITIATOR_RECEIVE;
|
||||||
|
ncr53c400_dma_changed(scsi, ncr->dma_mode, ncr->mode & MODE_DMA);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// pclog("Bad NCR5380 write %06x %02x\n", port, val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bus_host = get_bus_host(ncr);
|
||||||
|
|
||||||
|
scsi_bus_update(&ncr->bus, bus_host);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t
|
||||||
|
ncr5380_read(uint16_t port, void *priv)
|
||||||
|
{
|
||||||
|
lcs6821n_t *scsi = (lcs6821n_t *)priv;
|
||||||
|
ncr5380_t *ncr = &scsi->ncr;
|
||||||
|
uint32_t bus = 0;
|
||||||
|
uint8_t temp = 0xff;
|
||||||
|
|
||||||
|
switch (port & 7)
|
||||||
|
{
|
||||||
|
case 0: /*Current SCSI Data*/
|
||||||
|
if (ncr->icr & ICR_DBP)
|
||||||
|
{
|
||||||
|
temp = SCSI_BufferLength;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bus = scsi_bus_read(&ncr->bus);
|
||||||
|
temp = BUS_GETDATA(bus);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1: /*Initiator Command Register*/
|
||||||
|
temp = ncr->icr;
|
||||||
|
break;
|
||||||
|
case 2: /*Mode Register*/
|
||||||
|
temp = ncr->mode;
|
||||||
|
break;
|
||||||
|
case 3: /*Target Command Register*/
|
||||||
|
temp = ncr->tcr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4: /*Current SCSI Bus Status*/
|
||||||
|
temp = 0;
|
||||||
|
bus = scsi_bus_read(&ncr->bus);
|
||||||
|
temp |= (bus & 0xff);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5: /*Bus and Status Register*/
|
||||||
|
temp = 0;
|
||||||
|
|
||||||
|
bus = get_bus_host(ncr);
|
||||||
|
if (scsi_bus_match(&ncr->bus, bus))
|
||||||
|
temp |= 8;
|
||||||
|
bus = scsi_bus_read(&ncr->bus);
|
||||||
|
|
||||||
|
if (bus & BUS_ACK)
|
||||||
|
temp |= STATUS_ACK;
|
||||||
|
if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA))
|
||||||
|
temp |= STATUS_DRQ;
|
||||||
|
if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA))
|
||||||
|
{
|
||||||
|
int bus_state = 0;
|
||||||
|
if (bus & BUS_IO)
|
||||||
|
bus_state |= TCR_IO;
|
||||||
|
if (bus & BUS_CD)
|
||||||
|
bus_state |= TCR_CD;
|
||||||
|
if (bus & BUS_MSG)
|
||||||
|
bus_state |= TCR_MSG;
|
||||||
|
if ((ncr->tcr & 7) != bus_state)
|
||||||
|
ncr->isr |= STATUS_INT;
|
||||||
|
}
|
||||||
|
if (!(bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY))
|
||||||
|
temp |= STATUS_BUSY_ERROR;
|
||||||
|
temp |= (ncr->isr & (STATUS_INT | STATUS_END_OF_DMA));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7: /*Reset Parity/Interrupt*/
|
||||||
|
ncr->isr &= ~STATUS_INT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
ncr5380_log("Bad NCR5380 read %06x\n", port);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//ncr5380_log("ncr5380_read: addr=%06x temp=%02x pc=%04x:%04x\n", port, temp, CS,cpu_state.pc);
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CTRL_DATA_DIR (1 << 6)
|
||||||
|
|
||||||
|
#define STATUS_BUFFER_NOT_READY (1 << 2)
|
||||||
|
#define STATUS_53C80_ACCESSIBLE (1 << 7)
|
||||||
|
|
||||||
|
static uint8_t
|
||||||
|
lcs6821n_read(uint32_t addr, void *p)
|
||||||
|
{
|
||||||
|
lcs6821n_t *scsi = (lcs6821n_t *)p;
|
||||||
|
uint8_t temp = 0xff;
|
||||||
|
|
||||||
|
addr &= 0x3fff;
|
||||||
|
//ncr5380_log("lcs6821n_read %08x\n", addr);
|
||||||
|
|
||||||
|
if (addr < 0x2000)
|
||||||
|
temp = scsi->bios_rom.rom[addr & 0x1fff];
|
||||||
|
else if (addr < 0x3800)
|
||||||
|
temp = 0xff;
|
||||||
|
else if (addr >= 0x3a00)
|
||||||
|
temp = scsi->ext_ram[addr - 0x3a00];
|
||||||
|
else switch (addr & 0x3f80)
|
||||||
|
{
|
||||||
|
case 0x3800:
|
||||||
|
//ncr5380_log("Read intRAM %02x %02x\n", addr & 0x3f, scsi->int_ram[addr & 0x3f]);
|
||||||
|
temp = scsi->int_ram[addr & 0x3f];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x3880:
|
||||||
|
//ncr5380_log("Read 53c80 %04x\n", addr);
|
||||||
|
temp = ncr5380_read(addr, scsi);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x3900:
|
||||||
|
//ncr5380_log(" Read 3900 %i %02x\n", scsi->buffer_host_pos, scsi->status_ctrl);
|
||||||
|
if (scsi->buffer_host_pos >= 128 || !(scsi->status_ctrl & CTRL_DATA_DIR))
|
||||||
|
temp = 0xff;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
temp = scsi->buffer[scsi->buffer_host_pos++];
|
||||||
|
|
||||||
|
if (scsi->buffer_host_pos == 128)
|
||||||
|
scsi->status_ctrl |= STATUS_BUFFER_NOT_READY;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x3980:
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0x3980: /*Status*/
|
||||||
|
temp = scsi->status_ctrl;// | 0x80;
|
||||||
|
if (!scsi->ncr_busy)
|
||||||
|
temp |= STATUS_53C80_ACCESSIBLE;
|
||||||
|
break;
|
||||||
|
case 0x3981: /*Block counter register*/
|
||||||
|
temp = scsi->block_count;
|
||||||
|
break;
|
||||||
|
case 0x3982: /*Switch register read*/
|
||||||
|
temp = 0xff;
|
||||||
|
break;
|
||||||
|
case 0x3983:
|
||||||
|
temp = 0xff;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (addr >= 0x3880) ncr5380_log("lcs6821n_read: addr=%05x val=%02x\n", addr, temp);
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
lcs6821n_write(uint32_t addr, uint8_t val, void *p)
|
||||||
|
{
|
||||||
|
lcs6821n_t *scsi = (lcs6821n_t *)p;
|
||||||
|
|
||||||
|
addr &= 0x3fff;
|
||||||
|
|
||||||
|
//ncr5380_log("lcs6821n_write: addr=%05x val=%02x %04x:%04x %i %02x\n", addr, val, CS,cpu_state.pc, scsi->buffer_host_pos, scsi->status_ctrl);
|
||||||
|
|
||||||
|
if (addr >= 0x3a00)
|
||||||
|
scsi->ext_ram[addr - 0x3a00] = val;
|
||||||
|
else switch (addr & 0x3f80)
|
||||||
|
{
|
||||||
|
case 0x3800:
|
||||||
|
//ncr5380_log("Write intram %02x %02x\n", addr & 0x3f, val);
|
||||||
|
scsi->int_ram[addr & 0x3f] = val;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x3880:
|
||||||
|
//ncr5380_log("Write 53c80 %04x %02x\n", addr, val);
|
||||||
|
ncr5380_write(addr, val, scsi);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x3900:
|
||||||
|
if (!(scsi->status_ctrl & CTRL_DATA_DIR) && scsi->buffer_host_pos < 128)
|
||||||
|
{
|
||||||
|
scsi->buffer[scsi->buffer_host_pos++] = val;
|
||||||
|
if (scsi->buffer_host_pos == 128)
|
||||||
|
{
|
||||||
|
scsi->status_ctrl |= STATUS_BUFFER_NOT_READY;
|
||||||
|
scsi->ncr_busy = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x3980:
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0x3980: /*Control*/
|
||||||
|
if ((val & CTRL_DATA_DIR) && !(scsi->status_ctrl & CTRL_DATA_DIR))
|
||||||
|
{
|
||||||
|
scsi->buffer_host_pos = 128;
|
||||||
|
scsi->status_ctrl |= STATUS_BUFFER_NOT_READY;
|
||||||
|
}
|
||||||
|
else if (!(val & CTRL_DATA_DIR) && (scsi->status_ctrl & CTRL_DATA_DIR))
|
||||||
|
{
|
||||||
|
scsi->buffer_host_pos = 0;
|
||||||
|
scsi->status_ctrl &= ~STATUS_BUFFER_NOT_READY;
|
||||||
|
}
|
||||||
|
scsi->status_ctrl = (scsi->status_ctrl & 0x87) | (val & 0x78);
|
||||||
|
break;
|
||||||
|
case 0x3981: /*Block counter register*/
|
||||||
|
scsi->block_count = val;
|
||||||
|
scsi->block_count_loaded = 1;
|
||||||
|
scsi->dma_enabled = (scsi->ncr5380_dma_enabled && scsi->block_count_loaded);
|
||||||
|
if (scsi->status_ctrl & CTRL_DATA_DIR)
|
||||||
|
{
|
||||||
|
scsi->buffer_host_pos = 128;
|
||||||
|
scsi->status_ctrl |= STATUS_BUFFER_NOT_READY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scsi->buffer_host_pos = 0;
|
||||||
|
scsi->status_ctrl &= ~STATUS_BUFFER_NOT_READY;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t
|
||||||
|
t130b_read(uint32_t addr, void *p)
|
||||||
|
{
|
||||||
|
lcs6821n_t *scsi = (lcs6821n_t *)p;
|
||||||
|
uint8_t temp = 0xff;
|
||||||
|
addr &= 0x3fff;
|
||||||
|
|
||||||
|
if (addr < 0x1800)
|
||||||
|
temp = scsi->bios_rom.rom[addr & 0x1fff];
|
||||||
|
else if (addr < 0x1880)
|
||||||
|
temp = scsi->ext_ram[addr & 0x7f];
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
t130b_write(uint32_t addr, uint8_t val, void *p)
|
||||||
|
{
|
||||||
|
lcs6821n_t *scsi = (lcs6821n_t *)p;
|
||||||
|
|
||||||
|
addr &= 0x3fff;
|
||||||
|
|
||||||
|
if (addr >= 0x1800 && addr < 0x1880)
|
||||||
|
scsi->ext_ram[addr & 0x7f] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t
|
||||||
|
t130b_in(uint16_t port, void *p)
|
||||||
|
{
|
||||||
|
lcs6821n_t *scsi = (lcs6821n_t *)p;
|
||||||
|
uint8_t temp = 0xff;
|
||||||
|
|
||||||
|
switch (port & 0xf)
|
||||||
|
{
|
||||||
|
case 0x0: case 0x1: case 0x2: case 0x3:
|
||||||
|
temp = lcs6821n_read((port & 7) | 0x3980, scsi);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x4: case 0x5:
|
||||||
|
temp = lcs6821n_read(0x3900, scsi);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x8: case 0x9: case 0xa: case 0xb:
|
||||||
|
case 0xc: case 0xd: case 0xe: case 0xf:
|
||||||
|
temp = ncr5380_read(port, scsi);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
t130b_out(uint16_t port, uint8_t val, void *p)
|
||||||
|
{
|
||||||
|
lcs6821n_t *scsi = (lcs6821n_t *)p;
|
||||||
|
|
||||||
|
switch (port & 0xf)
|
||||||
|
{
|
||||||
|
case 0x0: case 0x1: case 0x2: case 0x3:
|
||||||
|
lcs6821n_write((port & 7) | 0x3980, val, scsi);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x4: case 0x5:
|
||||||
|
lcs6821n_write(0x3900, val, scsi);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x8: case 0x9: case 0xa: case 0xb:
|
||||||
|
case 0xc: case 0xd: case 0xe: case 0xf:
|
||||||
|
ncr5380_write(port, val, scsi);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ncr53c400_dma_callback(void *p)
|
||||||
|
{
|
||||||
|
lcs6821n_t *scsi = (lcs6821n_t *)p;
|
||||||
|
ncr5380_t *ncr = &scsi->ncr;
|
||||||
|
int c;
|
||||||
|
int bytes_transferred = 0;
|
||||||
|
|
||||||
|
scsi->dma_callback += POLL_TIME_US;
|
||||||
|
|
||||||
|
switch (scsi->ncr.dma_mode)
|
||||||
|
{
|
||||||
|
case DMA_SEND:
|
||||||
|
if (scsi->status_ctrl & CTRL_DATA_DIR)
|
||||||
|
{
|
||||||
|
ncr5380_log("DMA_SEND with DMA direction set wrong\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(scsi->status_ctrl & STATUS_BUFFER_NOT_READY))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!scsi->block_count_loaded)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL)
|
||||||
|
{
|
||||||
|
int bus;
|
||||||
|
uint8_t data;
|
||||||
|
|
||||||
|
for (c = 0; c < 10; c++)
|
||||||
|
{
|
||||||
|
uint8_t status = scsi_bus_read(&ncr->bus);
|
||||||
|
|
||||||
|
if (status & BUS_REQ)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (c == 10)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Data ready*/
|
||||||
|
data = scsi->buffer[scsi->buffer_pos];
|
||||||
|
bus = get_bus_host(ncr) & ~BUS_DATAMASK;
|
||||||
|
bus |= BUS_SETDATA(data);
|
||||||
|
|
||||||
|
scsi_bus_update(&ncr->bus, bus | BUS_ACK);
|
||||||
|
scsi_bus_update(&ncr->bus, bus & ~BUS_ACK);
|
||||||
|
|
||||||
|
scsi->buffer_pos++;
|
||||||
|
bytes_transferred++;
|
||||||
|
|
||||||
|
if (scsi->buffer_pos == 128)
|
||||||
|
{
|
||||||
|
scsi->buffer_pos = 0;
|
||||||
|
scsi->buffer_host_pos = 0;
|
||||||
|
scsi->status_ctrl &= ~STATUS_BUFFER_NOT_READY;
|
||||||
|
scsi->block_count = (scsi->block_count - 1) & 255;
|
||||||
|
scsi->ncr_busy = 0;
|
||||||
|
if (!scsi->block_count)
|
||||||
|
{
|
||||||
|
scsi->block_count_loaded = 0;
|
||||||
|
scsi->dma_enabled = 0;
|
||||||
|
|
||||||
|
ncr->tcr |= TCR_LAST_BYTE_SENT;
|
||||||
|
ncr->isr |= STATUS_END_OF_DMA;
|
||||||
|
if (ncr->mode & MODE_ENA_EOP_INT)
|
||||||
|
ncr->isr |= STATUS_INT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DMA_INITIATOR_RECEIVE:
|
||||||
|
if (!(scsi->status_ctrl & CTRL_DATA_DIR))
|
||||||
|
{
|
||||||
|
ncr5380_log("DMA_INITIATOR_RECEIVE with DMA direction set wrong\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(scsi->status_ctrl & STATUS_BUFFER_NOT_READY))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!scsi->block_count_loaded)
|
||||||
|
break;
|
||||||
|
|
||||||
|
while (bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL)
|
||||||
|
{
|
||||||
|
int bus;
|
||||||
|
uint8_t temp;
|
||||||
|
|
||||||
|
for (c = 0; c < 10; c++)
|
||||||
|
{
|
||||||
|
uint8_t status = scsi_bus_read(&ncr->bus);
|
||||||
|
|
||||||
|
if (status & BUS_REQ)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (c == 10)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*Data ready*/
|
||||||
|
bus = scsi_bus_read(&ncr->bus);
|
||||||
|
temp = BUS_GETDATA(bus);
|
||||||
|
bus = get_bus_host(ncr);
|
||||||
|
|
||||||
|
scsi_bus_update(&ncr->bus, bus | BUS_ACK);
|
||||||
|
scsi_bus_update(&ncr->bus, bus & ~BUS_ACK);
|
||||||
|
|
||||||
|
scsi->buffer[scsi->buffer_pos++] = temp;
|
||||||
|
bytes_transferred++;
|
||||||
|
|
||||||
|
if (scsi->buffer_pos == 128)
|
||||||
|
{
|
||||||
|
scsi->buffer_pos = 0;
|
||||||
|
scsi->buffer_host_pos = 0;
|
||||||
|
scsi->status_ctrl &= ~STATUS_BUFFER_NOT_READY;
|
||||||
|
scsi->block_count = (scsi->block_count - 1) & 255;
|
||||||
|
if (!scsi->block_count)
|
||||||
|
{
|
||||||
|
scsi->block_count_loaded = 0;
|
||||||
|
scsi->dma_enabled = 0;
|
||||||
|
|
||||||
|
ncr->isr |= STATUS_END_OF_DMA;
|
||||||
|
if (ncr->mode & MODE_ENA_EOP_INT)
|
||||||
|
ncr->isr |= STATUS_INT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// pclog("DMA callback bad mode %i\n", scsi->ncr.dma_mode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int bus = scsi_bus_read(&ncr->bus);
|
||||||
|
|
||||||
|
if (!(bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY))
|
||||||
|
{
|
||||||
|
ncr->mode &= ~MODE_DMA;
|
||||||
|
ncr->dma_mode = DMA_IDLE;
|
||||||
|
ncr53c400_dma_changed(scsi, ncr->dma_mode, ncr->mode & MODE_DMA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *scsi_53c400_init(wchar_t *bios_fn)
|
||||||
|
{
|
||||||
|
lcs6821n_t *scsi = malloc(sizeof(lcs6821n_t));
|
||||||
|
memset(scsi, 0, sizeof(lcs6821n_t));
|
||||||
|
|
||||||
|
rom_init(&scsi->bios_rom, bios_fn, 0xdc000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
|
||||||
|
mem_mapping_disable(&scsi->bios_rom.mapping);
|
||||||
|
|
||||||
|
mem_mapping_add(&scsi->mapping, 0xdc000, 0x4000,
|
||||||
|
lcs6821n_read, NULL, NULL,
|
||||||
|
lcs6821n_write, NULL, NULL,
|
||||||
|
scsi->bios_rom.rom, 0, scsi);
|
||||||
|
|
||||||
|
ncr5380_reset(&scsi->ncr);
|
||||||
|
|
||||||
|
scsi->status_ctrl = STATUS_BUFFER_NOT_READY;
|
||||||
|
scsi->buffer_host_pos = 128;
|
||||||
|
|
||||||
|
timer_add(ncr53c400_dma_callback, &scsi->dma_callback, &scsi->dma_enabled, scsi);
|
||||||
|
|
||||||
|
return scsi;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *scsi_lcs6821n_init(device_t *info)
|
||||||
|
{
|
||||||
|
return scsi_53c400_init(L"roms/scsi/ncr5380/Longshine LCS-6821N - BIOS version 1.04.bin");
|
||||||
|
}
|
||||||
|
static void *scsi_rt1000b_init(device_t *info)
|
||||||
|
{
|
||||||
|
return scsi_53c400_init(L"roms/scsi/ncr5380/Rancho_RT1000_RTBios_version_8.10R.bin");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *scsi_t130b_init(device_t *info)
|
||||||
|
{
|
||||||
|
lcs6821n_t *scsi = malloc(sizeof(lcs6821n_t));
|
||||||
|
memset(scsi, 0, sizeof(lcs6821n_t));
|
||||||
|
|
||||||
|
rom_init(&scsi->bios_rom, L"roms/scsi/ncr5380/trantor_t130b_bios_v2.14.bin", 0xdc000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL);
|
||||||
|
|
||||||
|
mem_mapping_add(&scsi->mapping, 0xdc000, 0x4000,
|
||||||
|
t130b_read, NULL, NULL,
|
||||||
|
t130b_write, NULL, NULL,
|
||||||
|
scsi->bios_rom.rom, 0, scsi);
|
||||||
|
io_sethandler(0x0350, 0x0010,
|
||||||
|
t130b_in, NULL, NULL,
|
||||||
|
t130b_out, NULL, NULL,
|
||||||
|
scsi);
|
||||||
|
|
||||||
|
ncr5380_reset(&scsi->ncr);
|
||||||
|
|
||||||
|
scsi->status_ctrl = STATUS_BUFFER_NOT_READY;
|
||||||
|
scsi->buffer_host_pos = 128;
|
||||||
|
|
||||||
|
timer_add(ncr53c400_dma_callback, &scsi->dma_callback, &scsi->dma_enabled, scsi);
|
||||||
|
|
||||||
|
return scsi;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
scsi_53c400_close(void *p)
|
||||||
|
{
|
||||||
|
lcs6821n_t *scsi = (lcs6821n_t *)p;
|
||||||
|
|
||||||
|
free(scsi);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int scsi_lcs6821n_available()
|
||||||
|
{
|
||||||
|
return rom_present(L"roms/scsi/ncr5380/Longshine LCS-6821N - BIOS version 1.04.bin");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int scsi_rt1000b_available()
|
||||||
|
{
|
||||||
|
return rom_present(L"roms/scsi/ncr5380/Rancho_RT1000_RTBios_version_8.10R.bin");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int scsi_t130b_available()
|
||||||
|
{
|
||||||
|
return rom_present(L"roms/scsi/ncr5380/trantor_t130b_bios_v2.14.bin");
|
||||||
|
}
|
||||||
|
|
||||||
|
device_t scsi_lcs6821n_device =
|
||||||
|
{
|
||||||
|
"Longshine LCS-6821N (SCSI)",
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
scsi_lcs6821n_init,
|
||||||
|
scsi_53c400_close,
|
||||||
|
NULL,
|
||||||
|
scsi_lcs6821n_available,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
device_t scsi_rt1000b_device =
|
||||||
|
{
|
||||||
|
"Ranco RT1000B (SCSI)",
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
scsi_rt1000b_init,
|
||||||
|
scsi_53c400_close,
|
||||||
|
NULL,
|
||||||
|
scsi_rt1000b_available,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
device_t scsi_t130b_device =
|
||||||
|
{
|
||||||
|
"Trantor T130B (SCSI)",
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
scsi_t130b_init,
|
||||||
|
scsi_53c400_close,
|
||||||
|
NULL,
|
||||||
|
scsi_t130b_available,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
27
src/scsi/scsi_ncr5380.h
Normal file
27
src/scsi/scsi_ncr5380.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* 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 NCR 5380 series of SCSI Host Adapters
|
||||||
|
* made by NCR. These controllers were designed for
|
||||||
|
* the ISA bus.
|
||||||
|
*
|
||||||
|
* Version: @(#)scsi_ncr5380.c 1.0.0 2017/10/04
|
||||||
|
*
|
||||||
|
* Authors: Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||||
|
* TheCollector1995, <mariogplayer@gmail.com>
|
||||||
|
*/
|
||||||
|
#ifndef SCSI_NCR5380_H
|
||||||
|
# define SCSI_NCR5380_H
|
||||||
|
|
||||||
|
|
||||||
|
extern device_t scsi_lcs6821n_device;
|
||||||
|
extern device_t scsi_rt1000b_device;
|
||||||
|
extern device_t scsi_t130b_device;
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*SCSI_NCR5380_H*/
|
||||||
@@ -42,7 +42,6 @@
|
|||||||
#include "../nvr.h"
|
#include "../nvr.h"
|
||||||
#include "../mouse.h"
|
#include "../mouse.h"
|
||||||
#include "../cdrom/cdrom.h"
|
#include "../cdrom/cdrom.h"
|
||||||
#include "../cdrom/cdrom_ioctl.h"
|
|
||||||
#include "../cdrom/cdrom_image.h"
|
#include "../cdrom/cdrom_image.h"
|
||||||
#include "../cdrom/cdrom_null.h"
|
#include "../cdrom/cdrom_null.h"
|
||||||
#include "../floppy/floppy.h"
|
#include "../floppy/floppy.h"
|
||||||
@@ -60,6 +59,7 @@
|
|||||||
#include "plat_ticks.h"
|
#include "plat_ticks.h"
|
||||||
#include "plat_ui.h"
|
#include "plat_ui.h"
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
|
#include "win_cdrom_ioctl.h"
|
||||||
#include "win_cgapal.h"
|
#include "win_cgapal.h"
|
||||||
#include "win_ddraw.h"
|
#include "win_ddraw.h"
|
||||||
#include "win_d3d.h"
|
#include "win_d3d.h"
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
#include "../cdrom/cdrom.h"
|
#include "../cdrom/cdrom.h"
|
||||||
#include "../cdrom/cdrom_ioctl.h"
|
|
||||||
#include "../cdrom/cdrom_image.h"
|
#include "../cdrom/cdrom_image.h"
|
||||||
#include "../cdrom/cdrom_null.h"
|
#include "../cdrom/cdrom_null.h"
|
||||||
#include "../disk/hdd.h"
|
#include "../disk/hdd.h"
|
||||||
@@ -37,6 +36,7 @@
|
|||||||
#include "../scsi/scsi_disk.h"
|
#include "../scsi/scsi_disk.h"
|
||||||
#include "plat_ui.h"
|
#include "plat_ui.h"
|
||||||
#include "win.h"
|
#include "win.h"
|
||||||
|
#include "win_cdrom_ioctl.h"
|
||||||
#include "win_language.h"
|
#include "win_language.h"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,8 +28,8 @@
|
|||||||
#include "../ibm.h"
|
#include "../ibm.h"
|
||||||
#include "../device.h"
|
#include "../device.h"
|
||||||
#include "../scsi/scsi.h"
|
#include "../scsi/scsi.h"
|
||||||
#include "cdrom.h"
|
#include "../cdrom/cdrom.h"
|
||||||
#include "cdrom_ioctl.h"
|
#include "win_cdrom_ioctl.h"
|
||||||
|
|
||||||
|
|
||||||
#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f)
|
#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f)
|
||||||
Reference in New Issue
Block a user