Big SCSI bus update of the day, NCR 5380 too (January 20th, 2025)

1. Separate the SCSI bus functions from NCR 5380 into true general purpose SCSI bus functions, allowing use of future legacy scsi controllers.
2. Corrected NCR 5380 chip period for the SCSI controllers based on that chip so that CD-ROM speed is correct enough per speed tests and no more breakage (I hope, report if they are still there, please!) on desyncs.
3. A NCR 5380 software reset involves asserting an IRQ.
This commit is contained in:
TC1995
2025-01-20 19:55:18 +01:00
parent 3dea388ae4
commit 4008010131
7 changed files with 546 additions and 482 deletions

View File

@@ -333,6 +333,20 @@
#define BUS_IDLE (1 << 31)
#define STATE_IDLE 0
#define STATE_COMMAND 1
#define STATE_DATAIN 2
#define STATE_DATAOUT 3
#define STATE_STATUS 4
#define STATE_MESSAGEIN 5
#define STATE_SELECT 6
#define STATE_MESSAGEOUT 7
#define STATE_MESSAGE_ID 8
#define PIO_TX_BUS 0
#define DMA_IN_TX_BUS 1
#define DMA_OUT_TX_BUS 2
#define PHASE_IDLE 0x00
#define PHASE_COMMAND 0x01
#define PHASE_DATA_IN 0x02
@@ -420,6 +434,36 @@ typedef struct scsi_device_t {
void (*command_stop)(scsi_common_t *sc);
} scsi_device_t;
typedef struct scsi_bus_t {
int tx_mode;
int clear_req;
int wait_data;
int wait_complete;
int bus_out;
int bus_in;
int command_pos;
int command_issued;
int data_pos;
int msgout_pos;
int is_msgout;
int state;
int dma_on_pio_enabled;
uint8_t data;
uint8_t msglun;
uint8_t data_wait;
uint8_t command[16];
uint8_t msgout[4];
uint8_t target_id;
uint8_t bus_device;
uint32_t bus_phase;
double period;
double speed;
double divider;
double multi;
void *priv;
void (*timer)(void *priv, double period);
} scsi_bus_t;
/* These are based on the INQUIRY values. */
#define SCSI_NONE 0x0060
#define SCSI_FIXED_DISK 0x0000
@@ -454,6 +498,8 @@ extern void scsi_device_init(void);
extern void scsi_reset(void);
extern uint8_t scsi_get_bus(void);
extern int scsi_bus_read(scsi_bus_t *scsi_bus);
extern void scsi_bus_update(scsi_bus_t *scsi_bus, int bus);
extern void scsi_bus_set_speed(uint8_t bus, double speed);
extern double scsi_bus_get_speed(uint8_t bus);

View File

@@ -44,6 +44,9 @@
#define ICR_ACK 0x10
#define ICR_ARB_LOST 0x20
#define ICR_ARB_IN_PROGRESS 0x40
#define ICR_RST 0x80
#define ICR_PHASE 0x9e
#define ICR_WRITE 0x9f
#define MODE_ARBITRATE 0x01
#define MODE_DMA 0x02
@@ -63,70 +66,33 @@
#define TCR_REQ 0x08
#define TCR_LAST_BYTE_SENT 0x80
#define STATE_IDLE 0
#define STATE_COMMAND 1
#define STATE_DATAIN 2
#define STATE_DATAOUT 3
#define STATE_STATUS 4
#define STATE_MESSAGEIN 5
#define STATE_SELECT 6
#define STATE_MESSAGEOUT 7
#define STATE_MESSAGE_ID 8
#define DMA_IDLE 0
#define DMA_SEND 1
#define DMA_INITIATOR_RECEIVE 2
typedef struct ncr_t {
uint8_t icr;
uint8_t mode;
uint8_t tcr;
uint8_t data_wait;
uint8_t isr;
uint8_t output_data;
uint8_t target_id;
uint8_t tx_data;
uint8_t msglun;
uint8_t irq_state;
uint8_t command[20];
uint8_t msgout[4];
uint8_t bus;
int msgout_pos;
int is_msgout;
int dma_mode;
int cur_bus;
int bus_in;
int new_phase;
int state;
int clear_req;
int wait_data;
int wait_data_back;
int wait_complete;
int command_pos;
int data_pos;
int irq;
double period;
void *priv;
void (*dma_mode_ext)(void *priv, void *ext_priv);
void (*dma_mode_ext)(void *priv, void *ext_priv, uint8_t val);
int (*dma_send_ext)(void *priv, void *ext_priv);
int (*dma_initiator_receive_ext)(void *priv, void *ext_priv);
void (*timer)(void *ext_priv, double period);
scsi_bus_t scsibus;
} ncr_t;
extern int ncr5380_cmd_len[8];
extern void ncr5380_irq(ncr_t *ncr, int set_irq);
extern void ncr5380_set_irq(ncr_t *ncr, int irq);
extern void ncr5380_set_irq(ncr_t *ncr, int irq);
extern uint32_t ncr5380_get_bus_host(ncr_t *ncr);
extern void ncr5380_bus_read(ncr_t *ncr);
extern void ncr5380_bus_update(ncr_t *ncr, int bus);
extern void ncr5380_write(uint16_t port, uint8_t val, ncr_t *ncr);
extern uint8_t ncr5380_read(uint16_t port, ncr_t *ncr);