Files
86Box/src/scsi/scsi.c
TC1995 d60602dd5d 53c9x changes of the night (August 11th, 2025)
1. Add the original AMD 53c974 (AMD bios only and revision 0x00 compared to the A revision which is 0x10 in the PCI regs) as well as correcting the SCSI bus reset when prompted (ESP CMD 0x03), the latter fixes DawiControl 53c974 drivers on win9x.
2. Check if DMA length is not 0 for DMA transfers.
3. More logs for possible problem diagnostics.
2025-08-11 22:48:30 +02:00

189 lines
4.3 KiB
C

/*
* 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.
*
* Handling of the SCSI controllers.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
* TheCollector1995, <mariogplayer@gmail.com>
*
* Copyright 2016-2018 Miran Grca.
* Copyright 2017-2018 Fred N. van Kempen.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include <86box/device.h>
#include <86box/machine.h>
#include <86box/hdc.h>
#include <86box/hdd.h>
#include <86box/plat.h>
#include <86box/scsi.h>
#include <86box/scsi_device.h>
#include <86box/cdrom.h>
#include <86box/rdisk.h>
#include <86box/scsi_disk.h>
#include <86box/scsi_aha154x.h>
#include <86box/scsi_buslogic.h>
#include <86box/scsi_ncr5380.h>
#include <86box/scsi_ncr53c8xx.h>
#include <86box/scsi_pcscsi.h>
#include <86box/scsi_spock.h>
int scsi_card_current[SCSI_CARD_MAX] = { 0, 0, 0, 0 };
double scsi_bus_speed[SCSI_BUS_MAX] = { 0.0, 0.0, 0.0, 0.0 };
static uint8_t next_scsi_bus = 0;
typedef const struct {
const device_t *device;
} SCSI_CARD;
static SCSI_CARD scsi_cards[] = {
// clang-format off
{ &device_none, },
/* ISA/Sidecar */
{ &scsi_ls2000_device, },
/* ISA */
{ &scsi_lcs6821n_device, },
{ &scsi_rt1000b_device, },
{ &scsi_t128_device, },
{ &scsi_t130b_device, },
/* ISA16 */
{ &aha154xa_device, },
{ &aha154xb_device, },
{ &aha154xc_device, },
{ &aha154xcf_device, },
{ &aha154xcp_device, },
{ &buslogic_542b_device, },
{ &buslogic_542bh_device, },
{ &buslogic_545s_device, },
{ &buslogic_545c_device, },
/* MCA */
{ &aha1640_device, },
{ &buslogic_640a_device, },
{ &spock_device, },
{ &tribble_device, },
{ &ncr53c90a_mca_device, },
{ &scsi_rt1000mc_device, },
{ &scsi_t228_device, },
/* VLB */
{ &buslogic_445s_device, },
{ &buslogic_445c_device, },
/* PCI */
{ &am53c974_pci_device, },
{ &am53c974a_pci_device, },
{ &buslogic_958d_pci_device, },
{ &ncr53c810_pci_device, },
{ &ncr53c815_pci_device, },
{ &ncr53c820_pci_device, },
{ &ncr53c825a_pci_device, },
{ &ncr53c860_pci_device, },
{ &ncr53c875_pci_device, },
{ &dc390_pci_device, },
{ NULL, },
// clang-format on
};
void
scsi_reset(void)
{
next_scsi_bus = 0;
}
uint8_t
scsi_get_bus(void)
{
uint8_t ret = next_scsi_bus;
if (next_scsi_bus >= SCSI_BUS_MAX)
return 0xff;
next_scsi_bus++;
return ret;
}
int
scsi_card_available(int card)
{
if (scsi_cards[card].device)
return (device_available(scsi_cards[card].device));
return 1;
}
const device_t *
scsi_card_getdevice(int card)
{
return (scsi_cards[card].device);
}
int
scsi_card_has_config(int card)
{
if (!scsi_cards[card].device)
return 0;
return (device_has_config(scsi_cards[card].device) ? 1 : 0);
}
const char *
scsi_card_get_internal_name(int card)
{
return device_get_internal_name(scsi_cards[card].device);
}
int
scsi_card_get_from_internal_name(char *s)
{
int c = 0;
while (scsi_cards[c].device != NULL) {
if (!strcmp(scsi_cards[c].device->internal_name, s))
return c;
c++;
}
return 0;
}
void
scsi_card_init(void)
{
int max = SCSI_CARD_MAX;
/* Do not initialize any controllers if we have do not have any SCSI
bus left. */
if (max > 0) {
for (int i = 0; i < max; i++) {
if ((scsi_card_current[i] > 0) && scsi_cards[scsi_card_current[i]].device)
device_add_inst(scsi_cards[scsi_card_current[i]].device, i + 1);
}
}
}
void
scsi_bus_set_speed(uint8_t bus, double speed)
{
scsi_bus_speed[bus] = speed;
}
double
scsi_bus_get_speed(uint8_t bus)
{
return scsi_bus_speed[bus];
}