Essentially reverted 8-bit IDE data reads and writes to old operation, fixes the hard disk bug;

SCSI LUN is now selectable for the CD-ROM drives;
Made sure every BusLogic RequestSetup ends in a StartMailbox sooner or later, fixes freezes with the DOS BusLogic drivers;
Commented out execess logging from mem.c;
Applied the mainline PCem commit that fixes the Bahamas64 on some boards.
This commit is contained in:
OBattler
2017-01-18 21:51:03 +01:00
parent fc42c2e2e7
commit 0548d8f9c8
13 changed files with 612 additions and 289 deletions

View File

@@ -685,6 +685,7 @@ static void BuslogicReadSGEntries(int Is24bit, uint32_t SGList, uint32_t Entries
void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bit)
{
uint32_t sg_buffer_pos = 0;
uint32_t DataPointer, DataLength;
if (Is24bit)
@@ -698,8 +699,13 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi
DataLength = BuslogicRequests->CmdBlock.new.DataLength;
}
if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY)
DataLength = 0;
/* if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY)
DataLength = 0; */
if ((BuslogicRequests->CmdBlock.common.Cdb[0] != GPCMD_MODE_SELECT_6) && (BuslogicRequests->CmdBlock.common.Cdb[0] != GPCMD_MODE_SELECT_10))
{
return;
}
BuslogicLog("Data Buffer write: length %d, pointer 0x%04X\n", DataLength, DataPointer);
@@ -737,8 +743,7 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi
BuslogicLog("Data to transfer (S/G) %d\n", DataToTransfer);
SCSIDevices[BuslogicRequests->TargetID].InitLength = DataToTransfer;
SCSIDevices[BuslogicRequests->TargetID].CmdBuffer[SCSIDevices[BuslogicRequests->TargetID].pos++] = SCSIDevices[BuslogicRequests->TargetID].InitLength;
SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength = DataToTransfer;
//If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without
//checking its length, so do this procedure for both no read/write commands.
@@ -763,7 +768,8 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi
Address = ScatterGatherBuffer[ScatterEntry].SegmentPointer;
DataToTransfer = ScatterGatherBuffer[ScatterEntry].Segment;
DMAPageRead(Address, SCSIDevices[BuslogicRequests->TargetID].CmdBuffer, DataToTransfer);
DMAPageRead(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer + sg_buffer_pos, DataToTransfer);
sg_buffer_pos += DataToTransfer;
}
ScatterGatherAddrCurrent += ScatterGatherRead * (Is24bit ? sizeof(SGE) : sizeof(SGE32));
@@ -774,10 +780,12 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi
BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES)
{
uint32_t Address = DataPointer;
SCSIDevices[BuslogicRequests->TargetID].InitLength = DataLength;
SCSIDevices[BuslogicRequests->TargetID].CmdBuffer[SCSIDevices[BuslogicRequests->TargetID].pos++] = SCSIDevices[BuslogicRequests->TargetID].InitLength;
SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength = DataLength;
DMAPageRead(Address, SCSIDevices[BuslogicRequests->TargetID].CmdBuffer, SCSIDevices[BuslogicRequests->TargetID].InitLength);
if (DataLength > 0)
{
DMAPageRead(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength);
}
}
}
}
@@ -798,6 +806,8 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests)
{
uint32_t sg_buffer_pos = 0;
uint32_t transfer_length = 0;
if (BuslogicRequests->Is24bit)
{
DataPointer = ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataPointer);
@@ -808,9 +818,19 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests)
DataPointer = BuslogicRequests->CmdBlock.new.DataPointer;
DataLength = BuslogicRequests->CmdBlock.new.DataLength;
}
if (DataLength > SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength)
{
DataLength = SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength;
}
if ((DataLength != 0) && (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY))
{
BuslogicLog("Data length not 0 with TEST UNIT READY: %i (%i)\n", DataLength, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength);
}
if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY)
DataLength = 0;
/* if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY)
DataLength = 0; */
BuslogicLog("Data Buffer read: length %d, pointer 0x%04X\n", DataLength, DataPointer);
@@ -852,7 +872,7 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests)
Address = ScatterGatherBuffer[ScatterEntry].SegmentPointer;
DataToTransfer = ScatterGatherBuffer[ScatterEntry].Segment;
DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID].CmdBuffer + sg_buffer_pos, DataToTransfer);
DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer + sg_buffer_pos, DataToTransfer);
sg_buffer_pos += DataToTransfer;
}
@@ -863,11 +883,21 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests)
BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES)
{
uint32_t Address = DataPointer;
DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID].CmdBuffer, SCSIDevices[BuslogicRequests->TargetID].InitLength);
if (DataLength > 0)
{
if (DataLength > SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength)
{
DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength);
}
else
{
DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer, DataLength);
}
}
}
}
SCSIDevices[BuslogicRequests->TargetID].InitLength = 0;
SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength = 0;
}
uint8_t BuslogicRead(uint16_t Port, void *p)
@@ -916,15 +946,20 @@ uint8_t BuslogicRead(uint16_t Port, void *p)
return Temp;
}
int buslogic_scsi_drive_is_cdrom(uint8_t id)
int buslogic_scsi_drive_is_cdrom(uint8_t id, uint8_t lun)
{
if (scsi_cdrom_drives[id] >= CDROM_NUM)
if (lun > 7)
{
return 0;
}
if (scsi_cdrom_drives[id][lun] >= CDROM_NUM)
{
return 0;
}
else
{
if (cdrom_drives[scsi_cdrom_drives[id]].enabled && cdrom_drives[scsi_cdrom_drives[id]].bus_type && (cdrom_drives[scsi_cdrom_drives[id]].bus_mode & 2))
if (cdrom_drives[scsi_cdrom_drives[id][lun]].enabled && cdrom_drives[scsi_cdrom_drives[id][lun]].bus_type && (cdrom_drives[scsi_cdrom_drives[id][lun]].bus_mode & 2))
{
return 1;
}
@@ -939,6 +974,10 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
{
int i = 0;
uint8_t j = 0;
uint8_t max_id = scsi_model ? 16 : 8;
Buslogic_t *Buslogic = (Buslogic_t *)p;
BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests;
BuslogicLog("Buslogic: Write Port 0x%02X, Value %02X\n", Port, Val);
@@ -964,9 +1003,9 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
{
for (i = 0; i < CDROM_NUM; i++)
{
if (buslogic_scsi_drive_is_cdrom(cdrom_drives[i].scsi_device_id))
if (buslogic_scsi_drive_is_cdrom(cdrom_drives[i].scsi_device_id, cdrom_drives[i].scsi_device_lun))
{
SCSICallback[cdrom_drives[i].scsi_device_id] = 1;
SCSICallback[cdrom_drives[i].scsi_device_id][cdrom_drives[i].scsi_device_lun] = 1;
}
}
break;
@@ -1105,13 +1144,16 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
break;
case 0x0A:
for (i = 0; i < 8; i++)
for (i = 0; i < max_id; i++)
{
if (buslogic_scsi_drive_is_cdrom(i))
Buslogic->DataBuf[i] = 1;
Buslogic->DataBuf[7] = 0;
Buslogic->DataReplyLeft = 8;
for (j = 0; j < 8; j++)
{
if (buslogic_scsi_drive_is_cdrom(i, j))
Buslogic->DataBuf[i] = 1;
Buslogic->DataBuf[7] = 0;
Buslogic->DataReplyLeft = 8;
}
}
break;
@@ -1147,14 +1189,16 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
}
break;
case 0x23:
for (i = 0; i < 8; i++)
for (i = 0; i < max_id; i++)
{
if (buslogic_scsi_drive_is_cdrom(i))
Buslogic->DataBuf[i] = 1;
for (i = 0; j < 8; j++)
{
if (buslogic_scsi_drive_is_cdrom(i, j))
Buslogic->DataBuf[i] = 1;
Buslogic->DataReplyLeft = 8;
Buslogic->DataReplyLeft = 8;
}
}
break;
@@ -1200,13 +1244,15 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
case 0x24:
{
uint8_t i;
uint16_t TargetsPresentMask = 0;
for (i=0;i<ELEMENTS(SCSIDevices);i++)
for (i = 0; i < max_id; i++)
{
if (SCSIDevices[i].LunType == SCSI_CDROM)
TargetsPresentMask |= (1 << i);
for (j = 0; j < 8; j++)
{
if (SCSIDevices[i][j].LunType == SCSI_CDROM)
TargetsPresentMask |= (1 << i);
}
}
Buslogic->DataBuf[0] = TargetsPresentMask&0x0F;
Buslogic->DataBuf[1] = TargetsPresentMask>>8;
@@ -1414,6 +1460,7 @@ static void BuslogicSenseBufferAllocate(BuslogicRequests_t *BuslogicRequests)
static void BuslogicSenseBufferFree(BuslogicRequests_t *BuslogicRequests, int Copy)
{
uint8_t SenseLength = BuslogicConvertSenseLength(BuslogicRequests->CmdBlock.common.RequestSenseLength);
uint8_t cdrom_id = scsi_cdrom_drives[BuslogicRequests->TargetID][BuslogicRequests->LUN];
if (SenseLength && Copy)
{
@@ -1434,8 +1481,7 @@ static void BuslogicSenseBufferFree(BuslogicRequests_t *BuslogicRequests, int Co
BuslogicLog("Request Sense address: %02X\n", SenseBufferAddress);
// DMAPageWrite(SenseBufferAddress, BuslogicRequests->RequestSenseBuffer, SenseLength);
DMAPageWrite(SenseBufferAddress, cdrom[BuslogicRequests->TargetID].sense, SenseLength);
DMAPageWrite(SenseBufferAddress, cdrom[cdrom_id].sense, SenseLength);
}
//Free the sense buffer when needed.
free(BuslogicRequests->RequestSenseBuffer);
@@ -1451,6 +1497,8 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer,
uint32_t temp = 0;
uint8_t temp_cdb[12];
//Fetch data from the Command Control Block.
DMAPageRead(CCBPointer, &BuslogicRequests->CmdBlock, sizeof(CCB32));
@@ -1463,9 +1511,9 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer,
BuslogicLog("Scanning SCSI Target ID %i\n", Id);
//Only SCSI CD-ROMs are supported at the moment, SCSI hard disk support will come soon.
if (buslogic_scsi_drive_is_cdrom(Id) && Lun == 0)
if (buslogic_scsi_drive_is_cdrom(Id, Lun))
{
cdrom_id = scsi_cdrom_drives[Id];
cdrom_id = scsi_cdrom_drives[Id][Lun];
BuslogicLog("SCSI Target ID %i detected and working\n", Id);
@@ -1483,6 +1531,22 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer,
BuslogicLog("SCSI Cdb[0]=0x%02X\n", BuslogicRequests->CmdBlock.common.Cdb[0]);
for (i = 1; i < BuslogicRequests->CmdBlock.common.CdbLength; i++)
BuslogicLog("SCSI Cdb[%i]=%i\n", i, BuslogicRequests->CmdBlock.common.Cdb[i]);
memset(temp_cdb, 0, cdrom[cdrom_id].cdb_len);
if (BuslogicRequests->CmdBlock.common.CdbLength <= cdrom[cdrom_id].cdb_len)
{
memcpy(temp_cdb, BuslogicRequests->CmdBlock.common.Cdb, BuslogicRequests->CmdBlock.common.CdbLength);
}
else
{
memcpy(temp_cdb, BuslogicRequests->CmdBlock.common.Cdb, cdrom[cdrom_id].cdb_len);
}
if (BuslogicRequests->CmdBlock.common.CdbLength != 12)
{
cdrom[cdrom_id].request_length = temp_cdb[1]; /* Since that field in the cdrom struct is never used when the bus type is SCSI, let's use it for this scope. */
temp_cdb[1] &= 0x1f; /* Make sure the LUN field of the temporary CDB is always 0, otherwise Daemon Tools drives will misehave when a command is passed through to them. */
}
BuslogicLog("Transfer Control %02X\n", BuslogicRequests->CmdBlock.common.ControlByte);
BuslogicLog("CDB Length %i\n", BuslogicRequests->CmdBlock.common.CdbLength);
@@ -1495,11 +1559,11 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer,
{
if ((BuslogicRequests->CmdBlock.common.ControlByte != 0x03) && (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND))
{
if (!cdrom_pre_execution_check(cdrom_id, BuslogicRequests->CmdBlock.common.Cdb))
if (!cdrom_pre_execution_check(cdrom_id, temp_cdb))
{
SCSIStatus = SCSI_STATUS_CHECK_CONDITION;
SCSICallback[Id]=50*SCSI_TIME;
SCSIDevices[BuslogicRequests->TargetID].InitLength = 0;
SCSICallback[Id][Lun]=50*SCSI_TIME;
SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength = 0;
if (BuslogicRequests->RequestSenseBuffer)
BuslogicSenseBufferFree(BuslogicRequests, 1);
BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR);
@@ -1508,28 +1572,13 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer,
}
}
//First, get the data buffer otherwise putting it after the
//exec function results into not getting read/write commands right and
//failing to detect the device.
/* Note by Tohka: After looking at the code, both functions do a copy of one part of the buffer to another,
with no purpose, whatsoever, and then end up with SCSIDevices.pos being equal to the InitLength.
SCSIReadData does not use pos at all, and the write code does, but in a useless way, therefore that
variable is going away.
All I am going to do at this point is zero the buffer.
Also, instead of directly calling SCSIReadData from here, this will be modified to call the CD-ROM
callback for the correct CD-ROM drive, and make that call SCSIReadData.
Since the new code will have the target ID and LUN inside the cdrom struct, as well as a copy of the Cdb
and the InitLength (in cdrom[id].request_length), it can be called from there and do everything needed. */
memset(SCSIDevices[Id].CmdBuffer, 0, 390144);
memset(SCSIDevices[Id][Lun].CmdBuffer, 0, 390144);
//Finally, execute the SCSI command immediately and get the transfer length.
SCSIPhase = SCSI_PHASE_COMMAND;
cdrom_command(cdrom_id, BuslogicRequests->CmdBlock.common.Cdb);
// SCSIDevices[Id].InitLength = cdrom[cdrom_id].0;
// SCSIGetLength(Id, &SCSIDevices[Id].InitLength);
SCSIDevices[Id][Lun].InitLength = 0;
cdrom_command(cdrom_id, temp_cdb);
SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id);
if (SCSIStatus == SCSI_STATUS_OK)
{
@@ -1553,9 +1602,12 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer,
/* Error (Check Condition) - call the phase callback to complete the command. */
cdrom_phase_callback(cdrom_id);
}
SCSICallback[Id] = cdrom[cdrom_id].callback;
SCSICallback[Id][Lun] = cdrom[cdrom_id].callback;
BuslogicDataBufferFree(BuslogicRequests);
if ((BuslogicRequests->CmdBlock.common.ControlByte != 0x03) && (SCSIDevices[Id][Lun].InitLength != 0))
{
BuslogicDataBufferFree(BuslogicRequests);
}
if (BuslogicRequests->RequestSenseBuffer)
BuslogicSenseBufferFree(BuslogicRequests, (SCSIStatus != SCSI_STATUS_OK));
@@ -1563,7 +1615,7 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer,
else
{
BuslogicLog("Mailbox32->u.out.ActionCode = %02X\n", Mailbox32->u.out.ActionCode);
SCSICallback[Id] = 50 * SCSI_TIME;
SCSICallback[Id][Lun] = 50 * SCSI_TIME;
}
BuslogicLog("Request complete\n");
@@ -1571,7 +1623,7 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer,
if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES)
{
temp = BuslogicGetDataLength(BuslogicRequests);
temp -= SCSIDevices[Id].InitLength;
temp -= SCSIDevices[Id][Lun].InitLength;
if (BuslogicRequests->Is24bit)
{
@@ -1686,11 +1738,11 @@ static void BuslogicStartMailbox(Buslogic_t *Buslogic)
}
}
void BuslogicCommandCallback(int Id, void *p)
void BuslogicCommandCallback(int id, int lun, void *p)
{
Buslogic_t *Buslogic = (Buslogic_t *)p;
SCSICallback[Id] = 0;
SCSICallback[id][lun] = 0;
if (Buslogic->MailboxCount)
{
BuslogicStartMailbox(Buslogic);
@@ -1699,22 +1751,22 @@ void BuslogicCommandCallback(int Id, void *p)
void BuslogicCommandCallback0(void *p)
{
BuslogicCommandCallback(cdrom_drives[0].scsi_device_id, p);
BuslogicCommandCallback(cdrom_drives[0].scsi_device_id, cdrom_drives[0].scsi_device_lun, p);
}
void BuslogicCommandCallback1(void *p)
{
BuslogicCommandCallback(cdrom_drives[1].scsi_device_id, p);
BuslogicCommandCallback(cdrom_drives[1].scsi_device_id, cdrom_drives[1].scsi_device_lun, p);
}
void BuslogicCommandCallback2(void *p)
{
BuslogicCommandCallback(cdrom_drives[2].scsi_device_id, p);
BuslogicCommandCallback(cdrom_drives[2].scsi_device_id, cdrom_drives[2].scsi_device_lun, p);
}
void BuslogicCommandCallback3(void *p)
{
BuslogicCommandCallback(cdrom_drives[3].scsi_device_id, p);
BuslogicCommandCallback(cdrom_drives[3].scsi_device_id, cdrom_drives[3].scsi_device_lun, p);
}
void *BuslogicInit()
@@ -1730,25 +1782,25 @@ void *BuslogicInit()
BuslogicLog("Building CD-ROM map...\n");
build_scsi_cdrom_map();
if (buslogic_scsi_drive_is_cdrom(cdrom_drives[0].scsi_device_id))
if (buslogic_scsi_drive_is_cdrom(cdrom_drives[0].scsi_device_id, cdrom_drives[0].scsi_device_lun))
{
SCSIDevices[cdrom_drives[0].scsi_device_id].LunType == SCSI_CDROM;
timer_add(BuslogicCommandCallback0, &SCSICallback[cdrom_drives[0].scsi_device_id], &SCSICallback[cdrom_drives[0].scsi_device_id], Buslogic);
SCSIDevices[cdrom_drives[0].scsi_device_id][cdrom_drives[0].scsi_device_lun].LunType == SCSI_CDROM;
timer_add(BuslogicCommandCallback0, &SCSICallback[cdrom_drives[0].scsi_device_id][cdrom_drives[0].scsi_device_lun], &SCSICallback[cdrom_drives[0].scsi_device_id][cdrom_drives[0].scsi_device_lun], Buslogic);
}
if (buslogic_scsi_drive_is_cdrom(cdrom_drives[1].scsi_device_id))
if (buslogic_scsi_drive_is_cdrom(cdrom_drives[1].scsi_device_id, cdrom_drives[1].scsi_device_lun))
{
SCSIDevices[cdrom_drives[1].scsi_device_id].LunType == SCSI_CDROM;
timer_add(BuslogicCommandCallback1, &SCSICallback[cdrom_drives[1].scsi_device_id], &SCSICallback[cdrom_drives[1].scsi_device_id], Buslogic);
SCSIDevices[cdrom_drives[1].scsi_device_id][cdrom_drives[1].scsi_device_lun].LunType == SCSI_CDROM;
timer_add(BuslogicCommandCallback1, &SCSICallback[cdrom_drives[1].scsi_device_id][cdrom_drives[1].scsi_device_lun], &SCSICallback[cdrom_drives[1].scsi_device_id][cdrom_drives[1].scsi_device_lun], Buslogic);
}
if (buslogic_scsi_drive_is_cdrom(cdrom_drives[2].scsi_device_id))
if (buslogic_scsi_drive_is_cdrom(cdrom_drives[2].scsi_device_id, cdrom_drives[2].scsi_device_lun))
{
SCSIDevices[cdrom_drives[2].scsi_device_id].LunType == SCSI_CDROM;
timer_add(BuslogicCommandCallback2, &SCSICallback[cdrom_drives[2].scsi_device_id], &SCSICallback[cdrom_drives[2].scsi_device_id], Buslogic);
SCSIDevices[cdrom_drives[2].scsi_device_id][cdrom_drives[2].scsi_device_lun].LunType == SCSI_CDROM;
timer_add(BuslogicCommandCallback2, &SCSICallback[cdrom_drives[2].scsi_device_id][cdrom_drives[2].scsi_device_lun], &SCSICallback[cdrom_drives[2].scsi_device_id][cdrom_drives[2].scsi_device_lun], Buslogic);
}
if (buslogic_scsi_drive_is_cdrom(cdrom_drives[3].scsi_device_id))
if (buslogic_scsi_drive_is_cdrom(cdrom_drives[3].scsi_device_id, cdrom_drives[3].scsi_device_lun))
{
SCSIDevices[cdrom_drives[3].scsi_device_id].LunType == SCSI_CDROM;
timer_add(BuslogicCommandCallback3, &SCSICallback[cdrom_drives[3].scsi_device_id], &SCSICallback[cdrom_drives[3].scsi_device_id], Buslogic);
SCSIDevices[cdrom_drives[3].scsi_device_id][cdrom_drives[3].scsi_device_lun].LunType == SCSI_CDROM;
timer_add(BuslogicCommandCallback3, &SCSICallback[cdrom_drives[3].scsi_device_id][cdrom_drives[3].scsi_device_lun], &SCSICallback[cdrom_drives[3].scsi_device_id][cdrom_drives[3].scsi_device_lun], Buslogic);
}
BuslogicLog("Buslogic on port 0x%04X\n", scsi_base);

View File

@@ -37,7 +37,7 @@ enum
CD_PAUSED
};
int cdrom_ioctl_do_log = 1;
int cdrom_ioctl_do_log = 0;
void cdrom_ioctl_log(const char *format, ...)
{
@@ -517,34 +517,23 @@ struct sptd_with_sense
UCHAR data[65536];
} sptd;
static int SCSICommand(uint8_t id, const UCHAR *cdb, UCHAR *buf, uint32_t *len, int no_length_check)
static int ioctl_get_block_length(uint8_t id, const UCHAR *cdb, int number_of_blocks, int no_length_check)
{
HANDLE fh;
DWORD ioctl_bytes;
DWORD out_size;
int ioctl_rv = 0;
int sector_type = 0;
int temp_len = 0;
SCSISense.SenseKey = 0;
SCSISense.Asc = 0;
SCSISense.Ascq = 0;
if (no_length_check)
{
return 8192;
}
*len = 0;
memset(&sptd, 0, sizeof(sptd));
sptd.s.Length = sizeof(SCSI_PASS_THROUGH);
sptd.s.CdbLength = 12;
sptd.s.DataIn = SCSI_IOCTL_DATA_IN;
sptd.s.TimeOutValue = 80 * 60;
goto bypass_check;
if (no_length_check) goto bypass_check;
switch (cdb[0])
{
case 0x08:
case 0x28:
case 0xa8:
/* READ (6), READ (10), READ (12) */
sptd.s.DataTransferLength = 2048 * cdrom[id].requested_blocks;
return 2048 * number_of_blocks;
break;
case 0xb9:
sector_type = (cdb[1] >> 2) & 7;
@@ -554,7 +543,7 @@ static int SCSICommand(uint8_t id, const UCHAR *cdb, UCHAR *buf, uint32_t *len,
if (sector_type == 0)
{
cdrom_illegal_mode(id);
return 1;
return -1;
}
}
goto common_handler;
@@ -567,7 +556,7 @@ static int SCSICommand(uint8_t id, const UCHAR *cdb, UCHAR *buf, uint32_t *len,
if (sector_type == 0)
{
cdrom_illegal_mode(id);
return 1;
return -1;
}
}
common_handler:
@@ -595,16 +584,38 @@ common_handler:
if (temp_len <= 0)
{
cdrom_illegal_mode(id);
return 1;
return -1;
}
sptd.s.DataTransferLength = temp_len * cdrom[id].requested_blocks;
return temp_len * cdrom[id].requested_blocks;
break;
default:
bypass_check:
/* Other commands */
sptd.s.DataTransferLength = 65536;
return 8192;
break;
}
}
static int SCSICommand(uint8_t id, const UCHAR *cdb, UCHAR *buf, uint32_t *len, int no_length_check)
{
HANDLE fh;
DWORD ioctl_bytes;
DWORD out_size;
int ioctl_rv = 0;
int sector_type = 0;
int temp_len = 0;
SCSISense.SenseKey = 0;
SCSISense.Asc = 0;
SCSISense.Ascq = 0;
*len = 0;
memset(&sptd, 0, sizeof(sptd));
sptd.s.Length = sizeof(SCSI_PASS_THROUGH);
sptd.s.CdbLength = 12;
sptd.s.DataIn = SCSI_IOCTL_DATA_IN;
sptd.s.TimeOutValue = 80 * 60;
sptd.s.DataTransferLength = ioctl_get_block_length(id, cdb, cdrom_ioctl[id].actual_requested_blocks, no_length_check);
sptd.s.SenseInfoOffset = (uintptr_t)&sptd.sense - (uintptr_t)&sptd;
sptd.s.SenseInfoLength = 32;
sptd.s.DataBufferOffset = (uintptr_t)&sptd.data - (uintptr_t)&sptd;
@@ -755,6 +766,19 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t
const UCHAR cdb[12];
int ret;
int block_length = 0;
int temp_block_length = 0;
int temp_pos = 0;
int blocks_at_once = 0;
int buffer_pos = 0;
int temp_requested_blocks = 0;
int transferred_blocks = 0;
int temp_len = 0;
if (cdb[0] == 0x43)
{
@@ -765,9 +789,57 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t
ioctl_open(id, 0);
memcpy(cdb, in_cdb, 12);
ret = SCSICommand(id, cdb, buf, len, 0);
memcpy(b, buf, *len);
temp_block_length = ioctl_get_block_length(id, cdb, cdrom[id].requested_blocks, 0);
if (temp_block_length != -1)
{
if (temp_block_length > 65534)
{
cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is bigger than 65534, splitting the transfer...\n", id, temp_block_length);
block_length = temp_block_length / cdrom[id].requested_blocks;
blocks_at_once = 32768 / block_length;
buffer_pos = 0;
temp_pos = cdrom[id].sector_pos;
temp_requested_blocks = cdrom[id].requested_blocks;
transferred_blocks = 0;
temp_len = 0;
split_block_read_iterate:
if (temp_requested_blocks < blocks_at_once)
{
cdrom_ioctl[id].actual_requested_blocks = temp_requested_blocks;
}
else
{
cdrom_ioctl[id].actual_requested_blocks = blocks_at_once;
}
cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Transferring %i blocks...\n", id, cdrom_ioctl[id].actual_requested_blocks);
cdrom_update_cdb(cdb, temp_pos, cdrom_ioctl[id].actual_requested_blocks);
ret = SCSICommand(id, cdb, buf + buffer_pos, &temp_len, 0);
*len += temp_len;
transferred_blocks += cdrom_ioctl[id].actual_requested_blocks;
if (ret && (transferred_blocks >= cdrom[id].requested_blocks))
{
temp_pos += cdrom_ioctl[id].actual_requested_blocks;
buffer_pos += (cdrom_ioctl[id].actual_requested_blocks * block_length);
goto split_block_read_iterate;
}
cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Split transfer done\n", id);
}
else
{
cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is smaller than 65534, transferring all at once...\n", id, temp_block_length);
cdrom_ioctl[id].actual_requested_blocks = cdrom[id].requested_blocks;
ret = SCSICommand(id, cdb, buf, len, 0);
cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Single transfer done\n", id);
}
memcpy(b, buf, *len);
}
else
{
cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is -1, this indicates an illegal mode\n", id, temp_block_length);
}
cdrom_ioctl_log("IOCTL DATA: %02X %02X %02X %02X %02X %02X %02X %02X\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);

View File

@@ -33,7 +33,22 @@
cdrom_t cdrom[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 scsi_cdrom_drives[16] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
uint8_t scsi_cdrom_drives[16][8] = { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } };
static struct __attribute__((__packed__))
{
@@ -240,13 +255,13 @@ void build_atapi_cdrom_map()
}
}
int find_cdrom_for_scsi_id(uint8_t scsi_id)
int find_cdrom_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun)
{
uint8_t i = 0;
for (i = 0; i < CDROM_NUM; i++)
{
if (cdrom_drives[i].bus_type && (cdrom_drives[i].scsi_device_id == scsi_id))
if (cdrom_drives[i].bus_type && (cdrom_drives[i].scsi_device_id == scsi_id) && (cdrom_drives[i].scsi_device_lun == scsi_lun))
{
return i;
}
@@ -257,15 +272,22 @@ int find_cdrom_for_scsi_id(uint8_t scsi_id)
void build_scsi_cdrom_map()
{
uint8_t i = 0;
memset(scsi_cdrom_drives, 0xff, 16);
uint8_t j = 0;
for (i = 0; i < 16; i++)
{
scsi_cdrom_drives[i] = find_cdrom_for_scsi_id(i);
if (scsi_cdrom_drives[i] != 0xff)
memset(scsi_cdrom_drives[i], 0xff, 8);
}
for (i = 0; i < 16; i++)
{
for (j = 0; j < 8; j++)
{
cdrom_init(scsi_cdrom_drives[i], 12, 1);
scsi_cdrom_drives[i][j] = find_cdrom_for_scsi_id(i, j);
if (scsi_cdrom_drives[i][j] != 0xff)
{
cdrom_init(scsi_cdrom_drives[i][j], 12, 1);
}
}
}
}
@@ -849,6 +871,10 @@ 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_drives[id].bus_type)
{
SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength = 0;
}
cdrom_command_complete(id);
}
else
@@ -857,7 +883,7 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al
{
if (cdrom_drives[id].bus_type)
{
SCSIDevices[cdrom_drives[id].scsi_device_id].InitLength = alloc_len;
SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength = alloc_len;
}
if (direction == 0)
{
@@ -928,6 +954,15 @@ static void cdrom_not_ready(uint8_t id)
cdrom_cmd_error(id);
}
/* This is 05/00/00, based on what a Daemon Tools drive returns for such a case. */
static void cdrom_illegal_lun(uint8_t id)
{
cdrom_sense_key = SENSE_ILLEGAL_REQUEST;
cdrom_asc = 0;
cdrom_ascq = 0;
cdrom_cmd_error(id);
}
static void cdrom_illegal_opcode(uint8_t id)
{
cdrom_sense_key = SENSE_ILLEGAL_REQUEST;
@@ -1007,7 +1042,7 @@ static int cdrom_pass_through(uint8_t id, int *len)
if ((cdrom_sense_key != 0) || (cdrom_asc != 0) || (cdrom_ascq != 0))
{
/* Command failed with sense, error with that sense. */
cdrom_log("CD-ROM %i: Command failed with sense, error with that sense.\n", id);
cdrom_log("CD-ROM %i: Command failed with sense, error with that sense (%02X/%02X/%02X).\n", id, cdrom_sense_key, cdrom_asc, cdrom_ascq);
cdrom_cmd_error(id);
return 0;
}
@@ -1020,58 +1055,58 @@ static int cdrom_pass_through(uint8_t id, int *len)
}
}
int cdrom_update_cdb(uint8_t id)
int cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks)
{
int temp = 0;
switch(cdrom[id].current_cdb[0])
switch(cdb[0])
{
case GPCMD_READ_6:
cdrom[id].current_cdb[1] = (cdrom[id].sector_pos >> 16) & 0xff;
cdrom[id].current_cdb[2] = (cdrom[id].sector_pos >> 8) & 0xff;
cdrom[id].current_cdb[3] = cdrom[id].sector_pos & 0xff;
cdb[1] = (lba_pos >> 16) & 0xff;
cdb[2] = (lba_pos >> 8) & 0xff;
cdb[3] = lba_pos & 0xff;
break;
case GPCMD_READ_10:
cdrom[id].current_cdb[2] = (cdrom[id].sector_pos >> 24) & 0xff;
cdrom[id].current_cdb[3] = (cdrom[id].sector_pos >> 16) & 0xff;
cdrom[id].current_cdb[4] = (cdrom[id].sector_pos >> 8) & 0xff;
cdrom[id].current_cdb[5] = cdrom[id].sector_pos & 0xff;
cdrom[id].current_cdb[7] = (cdrom[id].requested_blocks >> 8) & 0xff;
cdrom[id].current_cdb[8] = cdrom[id].requested_blocks & 0xff;
cdb[2] = (lba_pos >> 24) & 0xff;
cdb[3] = (lba_pos >> 16) & 0xff;
cdb[4] = (lba_pos >> 8) & 0xff;
cdb[5] = lba_pos & 0xff;
cdb[7] = (number_of_blocks >> 8) & 0xff;
cdb[8] = number_of_blocks & 0xff;
break;
case GPCMD_READ_12:
cdrom[id].current_cdb[2] = (cdrom[id].sector_pos >> 24) & 0xff;
cdrom[id].current_cdb[3] = (cdrom[id].sector_pos >> 16) & 0xff;
cdrom[id].current_cdb[4] = (cdrom[id].sector_pos >> 8) & 0xff;
cdrom[id].current_cdb[5] = cdrom[id].sector_pos & 0xff;
cdrom[id].current_cdb[6] = (cdrom[id].requested_blocks >> 24) & 0xff;
cdrom[id].current_cdb[7] = (cdrom[id].requested_blocks >> 16) & 0xff;
cdrom[id].current_cdb[8] = (cdrom[id].requested_blocks >> 8) & 0xff;
cdrom[id].current_cdb[9] = cdrom[id].requested_blocks & 0xff;
cdb[2] = (lba_pos >> 24) & 0xff;
cdb[3] = (lba_pos >> 16) & 0xff;
cdb[4] = (lba_pos >> 8) & 0xff;
cdb[5] = lba_pos & 0xff;
cdb[6] = (number_of_blocks >> 24) & 0xff;
cdb[7] = (number_of_blocks >> 16) & 0xff;
cdb[8] = (number_of_blocks >> 8) & 0xff;
cdb[9] = number_of_blocks & 0xff;
break;
case GPCMD_READ_CD_MSF:
temp = cdrom_lba_to_msf_accurate(cdrom[id].sector_pos);
cdrom[id].current_cdb[3] = (temp >> 16) & 0xff;
cdrom[id].current_cdb[4] = (temp >> 8) & 0xff;
cdrom[id].current_cdb[5] = temp & 0xff;
temp = cdrom_lba_to_msf_accurate(lba_pos);
cdb[3] = (temp >> 16) & 0xff;
cdb[4] = (temp >> 8) & 0xff;
cdb[5] = temp & 0xff;
temp = cdrom_lba_to_msf_accurate(cdrom[id].sector_pos + cdrom[id].requested_blocks - 1);
cdrom[id].current_cdb[6] = (temp >> 16) & 0xff;
cdrom[id].current_cdb[7] = (temp >> 8) & 0xff;
cdrom[id].current_cdb[8] = temp & 0xff;
temp = cdrom_lba_to_msf_accurate(lba_pos + number_of_blocks - 1);
cdb[6] = (temp >> 16) & 0xff;
cdb[7] = (temp >> 8) & 0xff;
cdb[8] = temp & 0xff;
break;
case GPCMD_READ_CD:
cdrom[id].current_cdb[2] = (cdrom[id].sector_pos >> 24) & 0xff;
cdrom[id].current_cdb[3] = (cdrom[id].sector_pos >> 16) & 0xff;
cdrom[id].current_cdb[4] = (cdrom[id].sector_pos >> 8) & 0xff;
cdrom[id].current_cdb[5] = cdrom[id].sector_pos & 0xff;
cdrom[id].current_cdb[6] = (cdrom[id].requested_blocks >> 16) & 0xff;
cdrom[id].current_cdb[7] = (cdrom[id].requested_blocks >> 8) & 0xff;
cdrom[id].current_cdb[8] = cdrom[id].requested_blocks & 0xff;
cdb[2] = (lba_pos >> 24) & 0xff;
cdb[3] = (lba_pos >> 16) & 0xff;
cdb[4] = (lba_pos >> 8) & 0xff;
cdb[5] = lba_pos & 0xff;
cdb[6] = (number_of_blocks >> 16) & 0xff;
cdb[7] = (number_of_blocks >> 8) & 0xff;
cdb[8] = number_of_blocks & 0xff;
break;
}
}
@@ -1177,7 +1212,7 @@ int cdrom_read_blocks(uint8_t id, int *len, int first_batch)
cdrom_log("Reading %i blocks starting from %i...\n", cdrom[id].requested_blocks, cdrom[id].sector_pos);
cdrom_update_cdb(id);
cdrom_update_cdb(cdrom[id].current_cdb, cdrom[id].sector_pos, cdrom[id].requested_blocks);
ret = cdrom_read_data(id, msf, type, flags, len);
@@ -1385,9 +1420,19 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb)
{
int ready = 0;
if (cdrom_drives[id].bus_type)
{
if (((cdrom[id].request_length >> 5) & 7) != cdrom_drives[id].scsi_device_lun)
{
cdrom_log("CD-ROM %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", id, ((cdrom[id].request_length >> 5) & 7));
cdrom_illegal_lun(id);
return 0;
}
}
if (!(cdrom_command_flags[cdb[0]] & IMPLEMENTED))
{
cdrom_log("CD-ROM %i: Attempting to unknown command %02X over %s\n", id, cdb[0], cdrom_drives[id].bus_type ? "SCSI" : "ATAPI");
cdrom_log("CD-ROM %i: Attempting to execute unknown command %02X over %s\n", id, cdb[0], cdrom_drives[id].bus_type ? "SCSI" : "ATAPI");
cdrom_illegal_opcode(id);
return 0;
}
@@ -2630,11 +2675,11 @@ int cdrom_read_from_ide_dma(uint8_t channel)
}
}
int cdrom_read_from_scsi_dma(uint8_t scsi_id)
int cdrom_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun)
{
uint8_t *cdbufferb;
uint8_t id = scsi_cdrom_drives[scsi_id];
uint8_t id = scsi_cdrom_drives[scsi_id][scsi_lun];
cdbufferb = (uint8_t *) cdrom[id].buffer;
@@ -2643,8 +2688,8 @@ int cdrom_read_from_scsi_dma(uint8_t scsi_id)
return 0;
}
cdrom_log("Reading from SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSIDevices[scsi_id].InitLength);
memcpy(cdbufferb, SCSIDevices[scsi_id].CmdBuffer, SCSIDevices[scsi_id].InitLength);
cdrom_log("Reading from SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSIDevices[scsi_id][scsi_lun].InitLength);
memcpy(cdbufferb, SCSIDevices[scsi_id][scsi_lun].CmdBuffer, SCSIDevices[scsi_id][scsi_lun].InitLength);
return 1;
}
@@ -2657,7 +2702,7 @@ int cdrom_read_from_dma(uint8_t id)
if (cdrom_drives[id].bus_type)
{
ret = cdrom_read_from_scsi_dma(cdrom_drives[id].scsi_device_id);
ret = cdrom_read_from_scsi_dma(cdrom_drives[id].scsi_device_id, cdrom_drives[id].scsi_device_lun);
}
else
{
@@ -2713,11 +2758,11 @@ int cdrom_write_to_ide_dma(uint8_t channel)
}
}
int cdrom_write_to_scsi_dma(uint8_t scsi_id)
int cdrom_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun)
{
uint8_t *cdbufferb;
uint8_t id = scsi_cdrom_drives[scsi_id];
uint8_t id = scsi_cdrom_drives[scsi_id][scsi_lun];
if (id > CDROM_NUM)
{
@@ -2726,10 +2771,10 @@ int cdrom_write_to_scsi_dma(uint8_t scsi_id)
cdbufferb = (uint8_t *) cdrom[id].buffer;
cdrom_log("Writing to SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSIDevices[scsi_id].InitLength);
memcpy(SCSIDevices[scsi_id].CmdBuffer, cdbufferb, SCSIDevices[scsi_id].InitLength);
cdrom_log("Writing to SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSIDevices[scsi_id][scsi_lun].InitLength);
memcpy(SCSIDevices[scsi_id][scsi_lun].CmdBuffer, cdbufferb, SCSIDevices[scsi_id][scsi_lun].InitLength);
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].CmdBuffer[0], SCSIDevices[scsi_id].CmdBuffer[1], SCSIDevices[scsi_id].CmdBuffer[2], SCSIDevices[scsi_id].CmdBuffer[3], SCSIDevices[scsi_id].CmdBuffer[4], SCSIDevices[scsi_id].CmdBuffer[5], SCSIDevices[scsi_id].CmdBuffer[6], SCSIDevices[scsi_id].CmdBuffer[7]);
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;
}
@@ -2739,7 +2784,7 @@ int cdrom_write_to_dma(uint8_t id)
if (cdrom_drives[id].bus_type)
{
ret = cdrom_write_to_scsi_dma(cdrom_drives[id].scsi_device_id);
ret = cdrom_write_to_scsi_dma(cdrom_drives[id].scsi_device_id, cdrom_drives[id].scsi_device_lun);
}
else
{
@@ -2810,14 +2855,15 @@ int cdrom_phase_callback(uint8_t id)
}
/* Reimplement as 8-bit due to reimplementation of IDE data read and write. */
uint8_t cdrom_read(uint8_t channel)
uint32_t cdrom_read(uint8_t channel, int length)
{
uint8_t *cdbufferb;
uint16_t *cdbufferw;
uint32_t *cdbufferl;
uint8_t id = atapi_cdrom_drives[channel];
// uint16_t temp = 0;
uint8_t temp = 0;
uint32_t temp = 0;
int ret = 0;
if (id > CDROM_NUM)
@@ -2826,15 +2872,33 @@ uint8_t cdrom_read(uint8_t channel)
}
cdbufferb = (uint8_t *) cdrom[id].buffer;
cdbufferw = cdrom[id].buffer;
cdbufferl = (uint32_t *) cdrom[id].buffer;
temp = cdbufferb[cdrom[id].pos];
cdrom[id].pos++;
cdrom[id].request_pos++;
switch(length)
{
case 1:
temp = cdbufferb[cdrom[id].pos];
cdrom[id].pos++;
cdrom[id].request_pos++;
break;
case 2:
temp = cdbufferw[cdrom[id].pos >> 1];
cdrom[id].pos += 2;
cdrom[id].request_pos += 2;
break;
case 4:
temp = cdbufferl[cdrom[id].pos >> 2];
cdrom[id].pos += 4;
cdrom[id].request_pos += 4;
break;
default:
return 0;
}
if (cdrom[id].packet_status == CDROM_PHASE_DATA_IN)
{
cdrom[id].total_read++;
cdrom[id].total_read += length;
ret = cdrom_block_check(id);
/* If the block check has returned 0, this means all the requested blocks have been read, therefore the command has finished. */
if (ret)
@@ -2866,9 +2930,12 @@ uint8_t cdrom_read(uint8_t channel)
}
/* Reimplement as 8-bit due to reimplementation of IDE data read and write. */
void cdrom_write(uint8_t channel, uint8_t val)
void cdrom_write(uint8_t channel, uint32_t val, int length)
{
uint8_t i = 0;
uint8_t *cdbufferb;
uint16_t *cdbufferw;
uint32_t *cdbufferl;
uint8_t id = atapi_cdrom_drives[channel];
@@ -2880,14 +2947,34 @@ void cdrom_write(uint8_t channel, uint8_t val)
}
cdbufferb = (uint8_t *) cdrom[id].buffer;
cdbufferw = cdrom[id].buffer;
cdbufferl = (uint32_t *) cdrom[id].buffer;
cdbufferb[cdrom[id].pos] = val;
cdrom[id].pos++;
switch(length)
{
case 1:
cdbufferb[cdrom[id].pos] = val & 0xff;
cdrom[id].pos++;
break;
case 2:
cdbufferw[cdrom[id].pos >> 1] = val & 0xff;
cdrom[id].pos += 2;
break;
case 4:
cdbufferl[cdrom[id].pos >> 2] = val;
cdrom[id].pos += 4;
break;
default:
return;
}
if (cdrom[id].packet_status == CDROM_PHASE_DATA_OUT)
{
ret = cdrom_mode_select_write(id, val);
cdrom_mode_select_return(id, ret);
for (i = 0; i < length; i++)
{
ret = cdrom_mode_select_write(id, val);
cdrom_mode_select_return(id, ret);
}
return;
}
else if (cdrom[id].packet_status == CDROM_PHASE_IDLE)

View File

@@ -94,7 +94,7 @@ typedef struct __attribute__((__packed__))
int prev_status;
int unit_attention;
uint8_t sense[18];
uint8_t sense[256];
int request_pos;
@@ -135,6 +135,7 @@ typedef struct __attribute__((__packed__))
uint8_t ide_channel;
uint8_t scsi_device_id;
uint8_t scsi_device_lun;
uint8_t sound_on;
} cdrom_drive_t;
@@ -143,7 +144,7 @@ extern cdrom_drive_t cdrom_drives[CDROM_NUM];
extern uint8_t atapi_cdrom_drives[8];
extern uint8_t scsi_cdrom_drives[16];
extern uint8_t scsi_cdrom_drives[16][8];
extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length);
extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length);
@@ -175,6 +176,7 @@ typedef struct
uint32_t cd_end;
int16_t cd_buffer[BUF_SIZE];
int cd_buflen;
int actual_requested_blocks;
} cdrom_ioctl_t;
void ioctl_close(uint8_t id);
@@ -189,8 +191,8 @@ int cdrom_CDROM_PHASE_to_scsi(uint8_t id);
int cdrom_atapi_phase_to_scsi(uint8_t id);
void cdrom_command(uint8_t id, uint8_t *cdb);
int cdrom_phase_callback(uint8_t id);
uint8_t cdrom_read(uint8_t channel);
void cdrom_write(uint8_t channel, uint8_t val);
uint32_t cdrom_read(uint8_t channel, int length);
void cdrom_write(uint8_t channel, uint32_t val, int length);
int cdrom_lba_to_msf_accurate(int lba);
void cdrom_reset(uint8_t id);
void cdrom_set_signature(int id);

View File

@@ -344,6 +344,7 @@ static void ide_identify(IDE *ide)
h = hdc[cur_ide[ide->board]].hpc; /* Heads */
s = hdc[cur_ide[ide->board]].spt; /* Sectors */
ide->buffer[0] = 0x40; /* Fixed disk */
ide->buffer[1] = hdc[cur_ide[ide->board]].tracks; /* Cylinders */
ide->buffer[3] = hdc[cur_ide[ide->board]].hpc; /* Heads */
ide->buffer[6] = hdc[cur_ide[ide->board]].spt; /* Sectors */
@@ -372,6 +373,7 @@ static void ide_identify(IDE *ide)
ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0;
ide->buffer[60] = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) & 0xFFFF; /* Total addressable sectors (LBA) */
ide->buffer[61] = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) >> 16;
ide->buffer[80] = 0x1e; /*ATA-1 to ATA-4 supported*/
// ide->buffer[63] = 7; /*Multiword DMA*/
if (ide->board < 2)
{
@@ -380,8 +382,8 @@ static void ide_identify(IDE *ide)
ide->buffer[63] = ide->dma_identify_data[1];
ide->buffer[65] = 150;
ide->buffer[66] = 150;
ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/
ide->buffer[88] = ide->dma_identify_data[2];
// ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/
// ide->buffer[88] = ide->dma_identify_data[2];
}
}
@@ -405,6 +407,7 @@ static void ide_atapi_identify(IDE *ide)
ide->buffer[51] = 2 << 8; /*PIO timing mode*/
ide->buffer[73] = 6;
ide->buffer[73] = 9;
ide->buffer[80] = 0x10; /*ATA/ATAPI-4 supported*/
if ((ide->board < 2) && (cdrom_drives[cdrom_id].bus_mode & 2))
{
@@ -751,12 +754,14 @@ void resetide(void)
int idetimes = 0;
void ide_write_data(int ide_board, uint8_t val)
void ide_write_data(int ide_board, uint32_t val, int length)
{
int ret = 0;
IDE *ide = &ide_drives[cur_ide[ide_board]];
uint8_t *idebufferb = (uint8_t *) ide->buffer;
uint16_t *idebufferw = ide->buffer;
uint32_t *idebufferl = (uint32_t *) ide->buffer;
#if 0
if (ide_drive_is_cdrom(ide))
@@ -768,12 +773,14 @@ void ide_write_data(int ide_board, uint8_t val)
// ide_log("Write IDEw %04X\n",val);
if (ide->command == WIN_PACKETCMD)
{
ide->pos = 0;
if (!ide_drive_is_cdrom(ide))
{
return;
}
cdrom_write(cur_ide[ide_board], val);
cdrom_write(cur_ide[ide_board], val, length);
if (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback)
{
@@ -783,8 +790,23 @@ void ide_write_data(int ide_board, uint8_t val)
}
else
{
idebufferb[ide->pos] = val;
ide->pos++;
switch(length)
{
case 1:
idebufferb[ide->pos] = val & 0xff;
ide->pos++;
break;
case 2:
idebufferw[ide->pos >> 1] = val & 0xffff;
ide->pos += 2;
break;
case 4:
idebufferl[ide->pos >> 2] = val;
ide->pos += 4;
break;
default:
return;
}
if (ide->pos>=512)
{
@@ -807,15 +829,13 @@ void ide_write_data(int ide_board, uint8_t val)
void writeidew(int ide_board, uint16_t val)
{
// ide_log("WriteIDEw %04X\n", val);
ide_write_data(ide_board, val);
ide_write_data(ide_board, val >> 8);
ide_write_data(ide_board, val, 2);
}
void writeidel(int ide_board, uint32_t val)
{
// ide_log("WriteIDEl %08X\n", val);
writeidew(ide_board, val);
writeidew(ide_board, val >> 16);
ide_write_data(ide_board, val, 4);
}
void writeide(int ide_board, uint16_t addr, uint8_t val)
@@ -832,7 +852,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
switch (addr)
{
case 0x1F0: /* Data */
ide_write_data(ide_board, val);
// writeidew(ide_board, val | (val << 8));
writeidew(ide_board, val | (val << 8));
return;
/* Note to self: for ATAPI, bit 0 of this is DMA if set, PIO if clear. */
@@ -1292,21 +1313,24 @@ ide_bad_command:
// fatal("Bad IDE write %04X %02X\n", addr, val);
}
uint8_t ide_read_data(int ide_board)
uint32_t ide_read_data(int ide_board, int length)
{
IDE *ide = &ide_drives[cur_ide[ide_board]];
uint8_t temp;
uint32_t temp;
uint8_t *idebufferb = (uint8_t *) ide->buffer;
uint16_t *idebufferw = ide->buffer;
uint32_t *idebufferl = (uint32_t *) ide->buffer;
if (ide->command == WIN_PACKETCMD)
{
ide->pos = 0;
if (!ide_drive_is_cdrom(ide))
{
ide_log("Drive not CD-ROM (position: %i)\n", ide->pos);
return 0;
}
temp = cdrom_read(cur_ide[ide_board]);
temp = cdrom_read(cur_ide[ide_board], length);
if (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback)
{
idecallback[ide_board] = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback;
@@ -1314,8 +1338,23 @@ uint8_t ide_read_data(int ide_board)
}
else
{
temp = idebufferb[ide->pos];
ide->pos++;
switch (length)
{
case 1:
temp = idebufferb[ide->pos];
ide->pos++;
break;
case 2:
temp = idebufferw[ide->pos >> 1];
ide->pos += 2;
break;
case 4:
temp = idebufferb[ide->pos >> 2];
ide->pos += 4;
break;
default:
return 0;
}
}
if (ide->pos>=512 && ide->command != WIN_PACKETCMD)
{
@@ -1367,7 +1406,10 @@ uint8_t readide(int ide_board, uint16_t addr)
switch (addr)
{
case 0x1F0: /* Data */
return ide_read_data(ide_board);
// temp = ide_read_data(ide_board, 1);
tempw = readidew(ide_board);
// pclog("Read IDEW %04X\n", tempw);
temp = tempw & 0xff;
break;
/* For ATAPI: Bits 7-4 = sense key, bit 3 = MCR (media change requested),
@@ -1517,20 +1559,17 @@ int all_blocks_total = 0;
uint16_t readidew(int ide_board)
{
uint16_t temp = 0;
uint16_t temp2 = 0;
temp = ide_read_data(ide_board);
temp2 = ide_read_data(ide_board);
temp2 <<= 8;
return (temp | temp2);
uint16_t temp;
temp = ide_read_data(ide_board, 2);
return temp;
}
uint32_t readidel(int ide_board)
{
uint16_t temp;
// ide_log("Read IDEl %i\n", ide_board);
temp = readidew(ide_board);
return temp | (readidew(ide_board) << 16);
temp = ide_read_data(ide_board, 4);
return temp;
}
int times30=0;

View File

@@ -975,7 +975,7 @@ int mmu_page_fault_check(uint32_t addr, int rw, uint32_t flags, int pde, int is_
if (!(flags & 1))
{
pclog("Trying to read or write a page that is not present!\n");
// pclog("Trying to read or write a page that is not present!\n");
is_page_fault = 1;
}
@@ -983,12 +983,12 @@ int mmu_page_fault_check(uint32_t addr, int rw, uint32_t flags, int pde, int is_
{
if (!(flags & 4) && mem_cpl3_check())
{
pclog("Trying to read a system page from user mode!\n");
// pclog("Trying to read a system page from user mode!\n");
is_page_fault = 1;
}
if (rw && !(flags & 2) && (mem_cpl3_check() || (cr0 & WP_FLAG)))
{
pclog("Trying to write a read-only-for-user page from user mode!\n");
// pclog("Trying to write a read-only-for-user page from user mode!\n");
is_page_fault = 1;
}
}

View File

@@ -275,7 +275,7 @@ void initpc(int argc, char *argv[])
{
if (cdrom_drives[i].bus_type)
{
SCSIReset(cdrom_drives[i].scsi_device_id);
SCSIReset(cdrom_drives[i].scsi_device_id, cdrom_drives[i].scsi_device_lun);
}
if (cdrom_drives[i].host_drive == 0)
@@ -453,7 +453,7 @@ void resetpchard()
{
if (cdrom_drives[i].bus_type)
{
SCSIReset(cdrom_drives[i].scsi_device_id);
SCSIReset(cdrom_drives[i].scsi_device_id, cdrom_drives[i].scsi_device_lun);
}
}
@@ -736,6 +736,7 @@ void loadconfig(char *fn)
cdrom_drives[0].bus_type = config_get_int(NULL, "cdrom_1_bus_type", 0);
cdrom_drives[0].ide_channel = config_get_int(NULL, "cdrom_1_ide_channel", 2);
cdrom_drives[0].scsi_device_id = config_get_int(NULL, "cdrom_1_scsi_device_id", 2);
cdrom_drives[0].scsi_device_lun = config_get_int(NULL, "cdrom_1_scsi_device_lun", 0);
p = (char *)config_get_string(NULL, "cdrom_1_iso_path", "");
if (p) strcpy(cdrom_iso[0].iso_path, p);
@@ -748,6 +749,7 @@ void loadconfig(char *fn)
cdrom_drives[1].bus_type = config_get_int(NULL, "cdrom_2_bus_type", 0);
cdrom_drives[1].ide_channel = config_get_int(NULL, "cdrom_2_ide_channel", 3);
cdrom_drives[1].scsi_device_id = config_get_int(NULL, "cdrom_2_scsi_device_id", 3);
cdrom_drives[1].scsi_device_lun = config_get_int(NULL, "cdrom_2_scsi_device_lun", 0);
p = (char *)config_get_string(NULL, "cdrom_2_iso_path", "");
if (p) strcpy(cdrom_iso[1].iso_path, p);
@@ -760,6 +762,7 @@ void loadconfig(char *fn)
cdrom_drives[2].bus_type = config_get_int(NULL, "cdrom_3_bus_type", 0);
cdrom_drives[2].ide_channel = config_get_int(NULL, "cdrom_3_ide_channel", 4);
cdrom_drives[2].scsi_device_id = config_get_int(NULL, "cdrom_3_scsi_device_id", 4);
cdrom_drives[2].scsi_device_lun = config_get_int(NULL, "cdrom_3_scsi_device_lun", 0);
p = (char *)config_get_string(NULL, "cdrom_3_iso_path", "");
if (p) strcpy(cdrom_iso[2].iso_path, p);
@@ -772,6 +775,7 @@ void loadconfig(char *fn)
cdrom_drives[3].bus_type = config_get_int(NULL, "cdrom_4_bus_type", 0);
cdrom_drives[3].ide_channel = config_get_int(NULL, "cdrom_4_ide_channel", 5);
cdrom_drives[3].scsi_device_id = config_get_int(NULL, "cdrom_4_scsi_device_id", 5);
cdrom_drives[3].scsi_device_lun = config_get_int(NULL, "cdrom_4_scsi_device_lun", 0);
p = (char *)config_get_string(NULL, "cdrom_4_iso_path", "");
if (p) strcpy(cdrom_iso[3].iso_path, p);
@@ -951,6 +955,7 @@ void saveconfig()
config_set_int(NULL, "cdrom_1_bus_type", cdrom_drives[0].bus_type);
config_set_int(NULL, "cdrom_1_ide_channel", cdrom_drives[0].ide_channel);
config_set_int(NULL, "cdrom_1_scsi_device_id", cdrom_drives[0].scsi_device_id);
config_set_int(NULL, "cdrom_1_scsi_device_lun", cdrom_drives[0].scsi_device_lun);
config_set_string(NULL, "cdrom_1_iso_path", cdrom_iso[0].iso_path);
@@ -959,7 +964,8 @@ void saveconfig()
config_set_int(NULL, "cdrom_2_sound_on", cdrom_drives[1].sound_on);
config_set_int(NULL, "cdrom_2_bus_type", cdrom_drives[1].bus_type);
config_set_int(NULL, "cdrom_2_ide_channel", cdrom_drives[1].ide_channel);
config_set_int(NULL, "cdrom_2_scsi_device_id", cdrom_drives[1].scsi_device_id);
config_set_int(NULL, "cdrom_2_scsi_device_id", cdrom_drives[1].scsi_device_id);
config_set_int(NULL, "cdrom_2_scsi_device_lun", cdrom_drives[1].scsi_device_lun);
config_set_string(NULL, "cdrom_2_iso_path", cdrom_iso[1].iso_path);
@@ -968,7 +974,8 @@ void saveconfig()
config_set_int(NULL, "cdrom_3_sound_on", cdrom_drives[2].sound_on);
config_set_int(NULL, "cdrom_3_bus_type", cdrom_drives[2].bus_type);
config_set_int(NULL, "cdrom_3_ide_channel", cdrom_drives[2].ide_channel);
config_set_int(NULL, "cdrom_3_scsi_device_id", cdrom_drives[2].scsi_device_id);
config_set_int(NULL, "cdrom_3_scsi_device_id", cdrom_drives[2].scsi_device_id);
config_set_int(NULL, "cdrom_3_scsi_device_lun", cdrom_drives[2].scsi_device_lun);
config_set_string(NULL, "cdrom_3_iso_path", cdrom_iso[2].iso_path);
@@ -977,7 +984,8 @@ void saveconfig()
config_set_int(NULL, "cdrom_4_sound_on", cdrom_drives[3].sound_on);
config_set_int(NULL, "cdrom_4_bus_type", cdrom_drives[3].bus_type);
config_set_int(NULL, "cdrom_4_ide_channel", cdrom_drives[3].ide_channel);
config_set_int(NULL, "cdrom_4_scsi_device_id", cdrom_drives[3].scsi_device_id);
config_set_int(NULL, "cdrom_4_scsi_device_id", cdrom_drives[3].scsi_device_id);
config_set_int(NULL, "cdrom_4_scsi_device_lun", cdrom_drives[3].scsi_device_lun);
config_set_string(NULL, "cdrom_4_iso_path", cdrom_iso[3].iso_path);

View File

@@ -56,6 +56,7 @@ BEGIN
MENUITEM "&I:",IDM_CDROM_1_I
MENUITEM "&J:",IDM_CDROM_1_J
END
MENUITEM SEPARATOR
POPUP "S&CSI ID..."
BEGIN
MENUITEM "&0",IDM_CDROM_1_0
@@ -74,6 +75,17 @@ BEGIN
MENUITEM "14",IDM_CDROM_1_14
MENUITEM "15",IDM_CDROM_1_15
END
POPUP "SCSI &LUN..."
BEGIN
MENUITEM "&0",IDM_CDROM_1_LUN_0
MENUITEM "&1",IDM_CDROM_1_LUN_1
MENUITEM "&2",IDM_CDROM_1_LUN_2
MENUITEM "&3",IDM_CDROM_1_LUN_3
MENUITEM "&4",IDM_CDROM_1_LUN_4
MENUITEM "&5",IDM_CDROM_1_LUN_5
MENUITEM "&6",IDM_CDROM_1_LUN_6
MENUITEM "&7",IDM_CDROM_1_LUN_7
END
MENUITEM SEPARATOR
MENUITEM "&ISO...",IDM_CDROM_1_ISO
END
@@ -98,6 +110,7 @@ BEGIN
MENUITEM "&I:",IDM_CDROM_2_I
MENUITEM "&J:",IDM_CDROM_2_J
END
MENUITEM SEPARATOR
POPUP "S&CSI ID..."
BEGIN
MENUITEM "&0",IDM_CDROM_2_0
@@ -116,6 +129,17 @@ BEGIN
MENUITEM "14",IDM_CDROM_2_14
MENUITEM "15",IDM_CDROM_2_15
END
POPUP "SCSI &LUN..."
BEGIN
MENUITEM "&0",IDM_CDROM_2_LUN_0
MENUITEM "&1",IDM_CDROM_2_LUN_1
MENUITEM "&2",IDM_CDROM_2_LUN_2
MENUITEM "&3",IDM_CDROM_2_LUN_3
MENUITEM "&4",IDM_CDROM_2_LUN_4
MENUITEM "&5",IDM_CDROM_2_LUN_5
MENUITEM "&6",IDM_CDROM_2_LUN_6
MENUITEM "&7",IDM_CDROM_2_LUN_7
END
MENUITEM SEPARATOR
MENUITEM "&ISO...",IDM_CDROM_2_ISO
END
@@ -140,6 +164,7 @@ BEGIN
MENUITEM "&I:",IDM_CDROM_3_I
MENUITEM "&J:",IDM_CDROM_3_J
END
MENUITEM SEPARATOR
POPUP "S&CSI ID..."
BEGIN
MENUITEM "&0",IDM_CDROM_3_0
@@ -158,6 +183,17 @@ BEGIN
MENUITEM "14",IDM_CDROM_3_14
MENUITEM "15",IDM_CDROM_3_15
END
POPUP "SCSI &LUN..."
BEGIN
MENUITEM "&0",IDM_CDROM_3_LUN_0
MENUITEM "&1",IDM_CDROM_3_LUN_1
MENUITEM "&2",IDM_CDROM_3_LUN_2
MENUITEM "&3",IDM_CDROM_3_LUN_3
MENUITEM "&4",IDM_CDROM_3_LUN_4
MENUITEM "&5",IDM_CDROM_3_LUN_5
MENUITEM "&6",IDM_CDROM_3_LUN_6
MENUITEM "&7",IDM_CDROM_3_LUN_7
END
MENUITEM SEPARATOR
MENUITEM "&ISO...",IDM_CDROM_3_ISO
END
@@ -181,6 +217,7 @@ BEGIN
MENUITEM "&I:",IDM_CDROM_4_I
MENUITEM "&J:",IDM_CDROM_4_J
END
MENUITEM SEPARATOR
POPUP "S&CSI ID..."
BEGIN
MENUITEM "&0",IDM_CDROM_4_0
@@ -199,6 +236,17 @@ BEGIN
MENUITEM "14",IDM_CDROM_4_14
MENUITEM "15",IDM_CDROM_4_15
END
POPUP "SCSI &LUN..."
BEGIN
MENUITEM "&0",IDM_CDROM_4_LUN_0
MENUITEM "&1",IDM_CDROM_4_LUN_1
MENUITEM "&2",IDM_CDROM_4_LUN_2
MENUITEM "&3",IDM_CDROM_4_LUN_3
MENUITEM "&4",IDM_CDROM_4_LUN_4
MENUITEM "&5",IDM_CDROM_4_LUN_5
MENUITEM "&6",IDM_CDROM_4_LUN_6
MENUITEM "&7",IDM_CDROM_4_LUN_7
END
MENUITEM SEPARATOR
MENUITEM "&ISO...",IDM_CDROM_4_ISO
END

View File

@@ -65,6 +65,14 @@
#define IDM_CDROM_1_13 40713
#define IDM_CDROM_1_14 40714
#define IDM_CDROM_1_15 40715
#define IDM_CDROM_1_LUN_0 40800
#define IDM_CDROM_1_LUN_1 40801
#define IDM_CDROM_1_LUN_2 40802
#define IDM_CDROM_1_LUN_3 40803
#define IDM_CDROM_1_LUN_4 40804
#define IDM_CDROM_1_LUN_5 40805
#define IDM_CDROM_1_LUN_6 40806
#define IDM_CDROM_1_LUN_7 40807
#define IDM_CDROM_2_ISO 41100
#define IDM_CDROM_2_RELOAD 41101
#define IDM_CDROM_2_EMPTY 41200
@@ -95,6 +103,14 @@
#define IDM_CDROM_2_13 41713
#define IDM_CDROM_2_14 41714
#define IDM_CDROM_2_15 41715
#define IDM_CDROM_2_LUN_0 41800
#define IDM_CDROM_2_LUN_1 41801
#define IDM_CDROM_2_LUN_2 41802
#define IDM_CDROM_2_LUN_3 41803
#define IDM_CDROM_2_LUN_4 41804
#define IDM_CDROM_2_LUN_5 41805
#define IDM_CDROM_2_LUN_6 41806
#define IDM_CDROM_2_LUN_7 41807
#define IDM_CDROM_3_ISO 42100
#define IDM_CDROM_3_RELOAD 42101
#define IDM_CDROM_3_EMPTY 42200
@@ -125,6 +141,14 @@
#define IDM_CDROM_3_13 42713
#define IDM_CDROM_3_14 42714
#define IDM_CDROM_3_15 42715
#define IDM_CDROM_3_LUN_0 42800
#define IDM_CDROM_3_LUN_1 42801
#define IDM_CDROM_3_LUN_2 42802
#define IDM_CDROM_3_LUN_3 42803
#define IDM_CDROM_3_LUN_4 42804
#define IDM_CDROM_3_LUN_5 42805
#define IDM_CDROM_3_LUN_6 42806
#define IDM_CDROM_3_LUN_7 42807
#define IDM_CDROM_4_ISO 43100
#define IDM_CDROM_4_RELOAD 43101
#define IDM_CDROM_4_EMPTY 43200
@@ -155,6 +179,14 @@
#define IDM_CDROM_4_13 43713
#define IDM_CDROM_4_14 43714
#define IDM_CDROM_4_15 43715
#define IDM_CDROM_4_LUN_0 43800
#define IDM_CDROM_4_LUN_1 43801
#define IDM_CDROM_4_LUN_2 43802
#define IDM_CDROM_4_LUN_3 43803
#define IDM_CDROM_4_LUN_4 43804
#define IDM_CDROM_4_LUN_5 43805
#define IDM_CDROM_4_LUN_6 43806
#define IDM_CDROM_4_LUN_7 43807
#define IDM_IDE_TER_ENABLED 44000
#define IDM_IDE_TER_IRQ9 44009
#define IDM_IDE_TER_IRQ10 44010

View File

@@ -16,82 +16,38 @@
uint8_t SCSIPhase = SCSI_PHASE_BUS_FREE;
uint8_t SCSIStatus = SCSI_STATUS_OK;
int SCSICallback[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int SCSICallback[16][8] = { { 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 } };
uint8_t scsi_cdrom_id = 3; /*common setting*/
//Get the transfer length of the command
void SCSIGetLength(uint8_t id, int *datalen)
{
*datalen = SCSIDevices[id].CmdBufferLength;
}
#if 0
//Execute SCSI command
void SCSIExecCommand(uint8_t id, uint8_t *buffer, uint8_t *cdb)
{
SCSICDROM_Command(id, buffer, cdb);
}
//Read pending data from the resulting SCSI command
void SCSIReadData(uint8_t id, uint8_t *cdb, uint8_t *data, int datalen)
{
SCSICDROM_ReadData(id, cdb, data, datalen);
}
/////
void SCSIDMAResetPosition(uint8_t Id)
{
//Reset position in memory after reaching its limit
SCSIDevices[Id].pos = 0;
}
//Read data from buffer with given position in buffer memory
void SCSIRead(uint8_t Id, uint8_t *dstbuf, uint8_t *srcbuf, uint32_t len_size)
{
if (!len_size) //If there's no data, don't try to do anything.
return;
int c;
for (c = 0; c <= len_size; c++) //Count as many bytes as the length of the buffer is requested
{
memcpy(dstbuf, srcbuf + SCSIDevices[Id].pos, len_size);
SCSIDevices[Id].pos = c;
//pclog("SCSI Read: position at %i\n", SCSIDevices[Id].pos);
}
}
//Write data to buffer with given position in buffer memory
void SCSIWrite(uint8_t Id, uint8_t *srcbuf, uint8_t *dstbuf, uint32_t len_size)
{
int c;
for (c = 0; c <= len_size; c++) //Count as many bytes as the length of the buffer is requested
{
memcpy(srcbuf + SCSIDevices[Id].pos, dstbuf, len_size);
SCSIDevices[Id].pos = c;
//pclog("SCSI Write: position at %i\n", SCSIDevices[Id].pos);
}
}
/////
#endif
//Initialization function for the SCSI layer
void SCSIReset(uint8_t Id)
void SCSIReset(uint8_t id, uint8_t lun)
{
uint8_t cdrom_id = scsi_cdrom_drives[Id];
uint8_t cdrom_id = scsi_cdrom_drives[id][lun];
if (buslogic_scsi_drive_is_cdrom(Id))
if (buslogic_scsi_drive_is_cdrom(id, lun))
{
SCSICallback[cdrom_id]=0;
SCSICallback[id][lun] = 0;
cdrom_reset(cdrom_id);
SCSIDevices[Id].LunType = SCSI_CDROM;
SCSIDevices[id][lun].LunType = SCSI_CDROM;
}
else
{
SCSIDevices[Id].LunType = SCSI_NONE;
SCSIDevices[id][lun].LunType = SCSI_NONE;
}
}

View File

@@ -188,7 +188,7 @@ int MediaPresent;
extern uint8_t SCSIStatus;
extern uint8_t SCSIPhase;
extern int SCSICallback[16];
extern int SCSICallback[16][8];
extern uint8_t scsi_cdrom_id;
struct
@@ -221,14 +221,13 @@ extern int prev_status;
struct
{
uint32_t pos;
uint8_t CmdBuffer[390144];
uint32_t CmdBufferLength;
int LunType;
uint32_t InitLength;
} SCSIDevices[16];
} SCSIDevices[16][8];
extern void SCSIReset(uint8_t Id);
extern void SCSIReset(uint8_t id, uint8_t lun);
uint32_t SCSICDROMModeSense(uint8_t *buf, uint32_t pos, uint8_t type);
uint8_t SCSICDROMSetProfile(uint8_t *buf, uint8_t *index, uint16_t profile);

View File

@@ -2314,7 +2314,7 @@ void *s3_bahamas64_init()
{
s3_t *s3 = s3_init("roms/bahamas64.BIN", S3_VISION864);
s3->id = 0xc1; /*Vision864P*/
s3->id = 0xc0; /*Vision864P*/
s3->id_ext = s3->id_ext_pci = 0xc1;
s3->packed_mmio = 0;
@@ -2393,7 +2393,7 @@ void *s3_phoenix_vision864_init()
{
s3_t *s3 = s3_init("roms/86c864p.bin", S3_VISION864);
s3->id = 0xc1; /*Vision864P*/
s3->id = 0xc0; /*Vision864P*/
s3->id_ext = s3->id_ext_pci = 0xc1;
s3->packed_mmio = 0;
@@ -2413,7 +2413,7 @@ void *s3_diamond_stealth64_init()
s3_t *s3 = s3_init("roms/STEALT64.BIN", S3_VISION864);
svga_t *svga = &s3->svga;
s3->id = 0xc1; /*Vision864P*/
s3->id = 0xc0; /*Vision864P*/
s3->id_ext = s3->id_ext_pci = 0xc1;
s3->packed_mmio = 0;
@@ -2432,7 +2432,7 @@ void *s3_miro_vision964_init()
{
s3_t *s3 = s3_init("roms/mirocrystal.VBI", S3_VISION964);
s3->id = 0xd1; /*Vision964P*/
s3->id = 0xd0; /*Vision964P*/
s3->id_ext = s3->id_ext_pci = 0xd1;
s3->packed_mmio = 1;

View File

@@ -526,6 +526,7 @@ int valid_irqs[6] = { 9, 10, 11, 12, 14, 15 };
int valid_dma_channels[3] = { 5, 6, 7 };
int valid_ide_channels[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
int valid_scsi_ids[15] = { 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15 };
int valid_scsi_luns[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
int find_in_array(int *array, int val, int len, int menu_base)
{
@@ -663,18 +664,25 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
if (!find_in_array(valid_ide_channels, cdrom_drives[e].ide_channel, 8, IDM_CDROM_1_C + (e * 1000)))
{
fatal("Tertiary IDE controller: Invalid IRQ\n");
fatal("CD-ROM %i: Invalid IDE channel\n", e);
}
CheckMenuItem(menu, IDM_CDROM_1_C + (e * 1000) + cdrom_drives[e].ide_channel, MF_CHECKED);
if (!find_in_array(valid_scsi_ids, cdrom_drives[e].scsi_device_id, 15, IDM_CDROM_1_0 + (e * 1000)))
{
fatal("Tertiary IDE controller: Invalid IRQ\n");
fatal("CD-ROM %i: Invalid SCSI ID\n", e);
}
CheckMenuItem(menu, IDM_CDROM_1_0 + (e * 1000) + cdrom_drives[e].scsi_device_id, MF_CHECKED);
if (!find_in_array(valid_scsi_luns, cdrom_drives[e].scsi_device_lun, 8, IDM_CDROM_1_LUN_0 + (e * 1000)))
{
fatal("CD-ROM %i: Invalid SCSI LUN\n", e);
}
CheckMenuItem(menu, IDM_CDROM_1_LUN_0 + (e * 1000) + cdrom_drives[e].scsi_device_lun, MF_CHECKED);
if (cdrom_drives[e].host_drive == 200)
{
CheckMenuItem(menu, IDM_CDROM_1_ISO + (e * 1000), MF_CHECKED);
@@ -1685,6 +1693,26 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
pause = 0;
break;
case IDM_CDROM_1_LUN_0 ... IDM_CDROM_1_LUN_7:
case IDM_CDROM_2_LUN_0 ... IDM_CDROM_2_LUN_7:
case IDM_CDROM_3_LUN_0 ... IDM_CDROM_3_LUN_7:
case IDM_CDROM_4_LUN_0 ... IDM_CDROM_4_LUN_7:
menu_sub_param = LOWORD(wParam) % 100;
cdrom_id = convert_cdrom_id(LOWORD(wParam) - menu_sub_param - IDM_CDROM_1_LUN_0);
if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK)
{
break;
}
pause = 1;
Sleep(100);
CheckMenuItem(hmenu, IDM_CDROM_1_LUN_0 + (cdrom_id * 1000) + cdrom_drives[cdrom_id].scsi_device_lun, MF_UNCHECKED);
cdrom_drives[cdrom_id].scsi_device_lun = menu_sub_param;
CheckMenuItem(hmenu, IDM_CDROM_1_LUN_0 + (cdrom_id * 1000) + cdrom_drives[cdrom_id].scsi_device_lun, MF_CHECKED);
saveconfig();
resetpchard();
pause = 0;
break;
case IDM_IDE_TER_ENABLED:
if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK)
{