From d64848d12285cb53def999da5559811aeb95b697 Mon Sep 17 00:00:00 2001 From: waltje Date: Sat, 26 Aug 2017 04:30:10 -0400 Subject: [PATCH] Updated to implement booting from AHA-1640 on MCA. Fixed AHA/BL "BIOS Command" code to also support the use of direct LBA32. --- src/CPU/808x.c | 2 +- src/scsi.h | 34 +++++++++++++++++++++++----------- src/scsi_aha154x.c | 24 +++++++++++++++++------- src/scsi_buslogic.c | 38 ++++++++++++++++++++++++-------------- 4 files changed, 65 insertions(+), 33 deletions(-) diff --git a/src/CPU/808x.c b/src/CPU/808x.c index ad5940283..781af9dc0 100644 --- a/src/CPU/808x.c +++ b/src/CPU/808x.c @@ -34,8 +34,8 @@ #include "../mem.h" #include "../nmi.h" #include "../pic.h" -#include "../scsi.h" #include "../timer.h" +#include "../scsi.h" int xt_cpu_multi; int nmi = 0; diff --git a/src/scsi.h b/src/scsi.h index b39216ad0..fc48b4dc9 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -8,7 +8,7 @@ * * SCSI controller handler header. * - * Version: @(#)scsi_h 1.0.1 2017/08/23 + * Version: @(#)scsi_h 1.0.3 2017/08/25 * * Authors: TheCollector1995, * Miran Grca, @@ -308,19 +308,31 @@ typedef struct { #pragma pack(push,1) typedef struct { - uint8_t command; - unsigned char id:3; - unsigned char reserved:2; - unsigned char lun:3; - uint16_t cylinder; - uint8_t head; - uint8_t sector; - uint8_t secount; - addr24 dma_address; + uint8_t command; + uint8_t id:3, + reserved:2, + lun:3; + union { + struct { + uint16_t cyl; + uint8_t head; + uint8_t sec; + } chs; + struct { + uint8_t lba0; /* MSB */ + uint8_t lba1; + uint8_t lba2; + uint8_t lba3; /* LSB */ + } lba; + } u; + uint8_t secount; + addr24 dma_address; } BIOSCMD; #pragma pack(pop) +#define lba32_blk(p) ((uint32_t)(p->u.lba.lba0<<24) | (p->u.lba.lba1<<16) | \ + (p->u.lba.lba2<<8) | p->u.lba.lba3) -extern uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd); +extern uint8_t scsi_bios_cmd(uint8_t last_id, BIOSCMD *BiosCmd, int8_t islba); /* diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index 50393517d..369bf5f14 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -1174,16 +1174,26 @@ aha_0x01: case CMD_BIOSCMD: /* Execute BIOS Command */ BiosCmd = (BIOSCMD *)dev->CmdBuf; - - cyl = ((BiosCmd->cylinder & 0xff) << 8) | ((BiosCmd->cylinder >> 8) & 0xff); - BiosCmd->cylinder = cyl; + if (dev->type != AHA_1640) { + cyl = ((BiosCmd->u.chs.cyl & 0xff) << 8) | ((BiosCmd->u.chs.cyl >> 8) & 0xff); + BiosCmd->u.chs.cyl = cyl; + } temp = BiosCmd->id; BiosCmd->id = BiosCmd->lun; BiosCmd->lun = temp; - BiosCmd->head &= 0xf; - BiosCmd->sector &= 0x1f; - pclog("C: %04X, H: %02X, S: %02X\n", BiosCmd->cylinder, BiosCmd->head, BiosCmd->sector); - dev->DataBuf[0] = HACommand03Handler(7, BiosCmd); + if (dev->type == AHA_1640) { + pclog("BIOS LBA=%06lx (%lu)\n", + lba32_blk(BiosCmd), + lba32_blk(BiosCmd)); + } else { + BiosCmd->u.chs.head &= 0xf; + BiosCmd->u.chs.sec &= 0x1f; + pclog("BIOS CHS=%04X/%02X%02X\n", + BiosCmd->u.chs.cyl, + BiosCmd->u.chs.head, + BiosCmd->u.chs.sec); + } + dev->DataBuf[0] = scsi_bios_cmd(7, BiosCmd, (dev->type==AHA_1640)?1:0); pclog("BIOS Completion/Status Code %x\n", dev->DataBuf[0]); dev->DataReplyLeft = 1; break; diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index 47fb7d26e..2567d33ad 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -10,7 +10,7 @@ * 0 - BT-542B ISA; * 1 - BT-946C PCI (but BT-542B ISA on non-PCI machines) * - * Version: @(#)scsi_buslogic.c 1.0.8 2017/08/23 + * Version: @(#)scsi_buslogic.c 1.0.9 2017/08/25 * * Authors: TheCollector1995, * Miran Grca, @@ -1420,16 +1420,22 @@ static void BuslogicIDCheck(uint8_t id, uint8_t lun) } } + /* This returns the completion code. */ -uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd) +uint8_t scsi_bios_cmd(uint8_t last_id, BIOSCMD *BiosCmd, int8_t islba) { uint32_t dma_address; - int lba = (BiosCmd->cylinder << 9) + (BiosCmd->head << 5) + BiosCmd->sector; + uint32_t lba; int sector_len = BiosCmd->secount; int block_shift = 9; uint8_t ret = 0; uint8_t cdb[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + if (islba) + lba = lba32_blk(BiosCmd); + else + lba = (BiosCmd->u.chs.cyl << 9) + (BiosCmd->u.chs.head << 5) + BiosCmd->u.chs.sec; + SpecificLog("BIOS Command = 0x%02X\n", BiosCmd->command); if ((BiosCmd->id > last_id) || (BiosCmd->lun > 7)) { @@ -1461,8 +1467,6 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd) case 0x00: /* Reset Disk System, in practice it's a nop */ return 0; - break; - case 0x01: /* Read Status of Last Operation */ BuslogicIDCheck(BiosCmd->id, BiosCmd->lun); @@ -1507,12 +1511,15 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd) cdb[5] = lba & 0xff; cdb[7] = (sector_len >> 8) & 0xff; cdb[8] = sector_len & 0xff; +#if 0 +pclog("BIOS CMD(READ, %08lx, %d)\n", lba, BiosCmd->secount); +#endif scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb); if (sector_len > 0) { - SpecificLog("BusLogic BIOS DMA: Reading %i bytes at %08X\n", sector_len << block_shift, dma_address); + SpecificLog("BIOS DMA: Reading %i bytes at %08X\n", sector_len << block_shift, dma_address); DMAPageWrite(dma_address, (char *)SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, sector_len << block_shift); } @@ -1536,7 +1543,7 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd) if (sector_len > 0) { - SpecificLog("BusLogic BIOS DMA: Reading %i bytes at %08X\n", sector_len << block_shift, dma_address); + SpecificLog("BIOS DMA: Reading %i bytes at %08X\n", sector_len << block_shift, dma_address); DMAPageRead(dma_address, (char *)SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, sector_len << block_shift); } @@ -1548,6 +1555,9 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd) cdb[5] = lba & 0xff; cdb[7] = (sector_len >> 8) & 0xff; cdb[8] = sector_len & 0xff; +#if 0 +pclog("BIOS CMD(WRITE, %08lx, %d)\n", lba, BiosCmd->secount); +#endif scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb); @@ -1611,7 +1621,7 @@ uint8_t HACommand03Handler(uint8_t last_id, BIOSCMD *BiosCmd) ret = BuslogicBIOSCommand08(BiosCmd->id, BiosCmd->lun, SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer); - SpecificLog("BusLogic BIOS DMA: Reading 6 bytes at %08X\n", dma_address); + SpecificLog("BIOS DMA: Reading 6 bytes at %08X\n", dma_address); DMAPageWrite(dma_address, (char *)SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 6); if (SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer != NULL) @@ -1966,18 +1976,18 @@ BuslogicWrite(uint16_t Port, uint8_t Val, void *p) case 0x03: BiosCmd = (BIOSCMD *)bl->CmdBuf; - cyl = ((BiosCmd->cylinder & 0xff) << 8) | ((BiosCmd->cylinder >> 8) & 0xff); - BiosCmd->cylinder = cyl; + cyl = ((BiosCmd->u.chs.cyl & 0xff) << 8) | ((BiosCmd->u.chs.cyl >> 8) & 0xff); + BiosCmd->u.chs.cyl = cyl; if (bl->chip == CHIP_BUSLOGIC_PCI) { temp = BiosCmd->id; BiosCmd->id = BiosCmd->lun; BiosCmd->lun = temp; } - BiosCmd->head &= 0xf; - BiosCmd->sector &= 0x1f; - SpecificLog("C: %04X, H: %02X, S: %02X\n", BiosCmd->cylinder, BiosCmd->head, BiosCmd->sector); - bl->DataBuf[0] = HACommand03Handler(15, BiosCmd); + BiosCmd->u.chs.head &= 0x0f; + BiosCmd->u.chs.sec &= 0x1f; + SpecificLog("C: %04X, H: %02X, S: %02X\n", BiosCmd->u.chs.cyl, BiosCmd->u.chs.head, BiosCmd->u.chs.sec); + bl->DataBuf[0] = scsi_bios_cmd(15, BiosCmd, 0); SpecificLog("BIOS Completion/Status Code %x\n", bl->DataBuf[0]); bl->DataReplyLeft = 1; break;