Merge remote-tracking branch 'refs/remotes/OBattler/master'
This commit is contained in:
@@ -19,7 +19,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429
|
||||
vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \
|
||||
vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o \
|
||||
vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \
|
||||
vid_vga.o vid_wy700.o vid_voodoo.o video.o w83877f.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \
|
||||
vid_vga.o vid_wy700.o vid_voodoo.o video.o w83877f.o wd76c10.o win.o win-crashdump.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \
|
||||
win-ddraw-fs.o win-ddraw-screenshot.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \
|
||||
win-status.o win-video.o x86seg.o x87.o xtide.o pc.res
|
||||
DBOBJ = dbopl.o nukedopl.o vid_cga_comp.o
|
||||
@@ -32,9 +32,9 @@ LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9
|
||||
|
||||
86Box.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ)
|
||||
$(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS)
|
||||
sleep 2
|
||||
sleep 10
|
||||
strip "86Box.exe"
|
||||
sleep 2
|
||||
sleep 10
|
||||
|
||||
all : 86Box.exe
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429
|
||||
vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \
|
||||
vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o \
|
||||
vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \
|
||||
vid_vga.o vid_wy700.o vid_voodoo.o video.o w83877f.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \
|
||||
vid_vga.o vid_wy700.o vid_voodoo.o video.o w83877f.o wd76c10.o win.o win-crashdump.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \
|
||||
win-ddraw-fs.o win-ddraw-screenshot.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \
|
||||
win-status.o win-video.o x86seg.o x87.o xtide.o pc.res
|
||||
DBOBJ = dbopl.o nukedopl.o vid_cga_comp.o
|
||||
|
||||
255
src/buslogic.c
255
src/buslogic.c
@@ -629,7 +629,11 @@ static void BuslogicMailboxIn(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *C
|
||||
CmdBlock->common.TargetStatus = TargetStatus;
|
||||
|
||||
//Rewrite the CCB up to the CDB.
|
||||
DMAPageWrite(CCBPointer, CmdBlock, offsetof(CCBC, Cdb));
|
||||
if (CmdBlock->common.TargetStatus != 0x02)
|
||||
{
|
||||
BuslogicLog("CCB rewritten to the CDB (pointer %08X, length %i)\n", CCBPointer, offsetof(CCBC, Cdb));
|
||||
DMAPageWrite(CCBPointer, CmdBlock, offsetof(CCBC, Cdb));
|
||||
}
|
||||
}
|
||||
|
||||
BuslogicLog("Host Status 0x%02X, Target Status 0x%02X\n", HostStatus, TargetStatus);
|
||||
@@ -681,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)
|
||||
@@ -694,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);
|
||||
|
||||
@@ -733,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.
|
||||
@@ -759,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));
|
||||
@@ -770,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -794,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);
|
||||
@@ -804,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);
|
||||
|
||||
@@ -848,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;
|
||||
}
|
||||
|
||||
@@ -859,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)
|
||||
@@ -912,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;
|
||||
}
|
||||
@@ -935,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);
|
||||
@@ -960,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;
|
||||
@@ -1101,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;
|
||||
|
||||
@@ -1143,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;
|
||||
|
||||
@@ -1196,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;
|
||||
@@ -1410,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)
|
||||
{
|
||||
@@ -1430,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);
|
||||
@@ -1447,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));
|
||||
|
||||
@@ -1459,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);
|
||||
|
||||
@@ -1476,13 +1528,29 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer,
|
||||
|
||||
uint32_t i;
|
||||
|
||||
pclog("SCSI Cdb[0]=0x%02X\n", BuslogicRequests->CmdBlock.common.Cdb[0]);
|
||||
BuslogicLog("SCSI Cdb[0]=0x%02X\n", BuslogicRequests->CmdBlock.common.Cdb[0]);
|
||||
for (i = 1; i < BuslogicRequests->CmdBlock.common.CdbLength; i++)
|
||||
pclog("SCSI Cdb[%i]=%i\n", i, BuslogicRequests->CmdBlock.common.Cdb[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. */
|
||||
}
|
||||
|
||||
pclog("Transfer Control %02X\n", BuslogicRequests->CmdBlock.common.ControlByte);
|
||||
pclog("CDB Length %i\n", BuslogicRequests->CmdBlock.common.CdbLength);
|
||||
pclog("CCB Opcode %x\n", BuslogicRequests->CmdBlock.common.Opcode);
|
||||
BuslogicLog("Transfer Control %02X\n", BuslogicRequests->CmdBlock.common.ControlByte);
|
||||
BuslogicLog("CDB Length %i\n", BuslogicRequests->CmdBlock.common.CdbLength);
|
||||
BuslogicLog("CCB Opcode %x\n", BuslogicRequests->CmdBlock.common.Opcode);
|
||||
|
||||
//This not ready/unit attention stuff below is only for the Buslogic!
|
||||
//The Adaptec one is in scsi_cdrom.c.
|
||||
@@ -1491,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);
|
||||
@@ -1504,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)
|
||||
{
|
||||
@@ -1549,22 +1602,28 @@ 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));
|
||||
}
|
||||
else
|
||||
{
|
||||
BuslogicLog("Mailbox32->u.out.ActionCode = %02X\n", Mailbox32->u.out.ActionCode);
|
||||
SCSICallback[Id][Lun] = 50 * SCSI_TIME;
|
||||
}
|
||||
|
||||
pclog("Request complete\n");
|
||||
pclog("SCSI Status %02X, Sense %02X, Asc %02X, Ascq %02X\n", SCSIStatus, cdrom[cdrom_id].sense[2], cdrom[cdrom_id].sense[12], cdrom[cdrom_id].sense[13]);
|
||||
|
||||
if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES ||
|
||||
BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)
|
||||
BuslogicLog("Request complete\n");
|
||||
|
||||
if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES)
|
||||
{
|
||||
temp = BuslogicGetDataLength(BuslogicRequests);
|
||||
temp -= SCSIDevices[Id].InitLength;
|
||||
temp -= SCSIDevices[Id][Lun].InitLength;
|
||||
|
||||
if (BuslogicRequests->Is24bit)
|
||||
{
|
||||
@@ -1577,6 +1636,19 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer,
|
||||
BuslogicLog("32-bit Residual data length for reading: %d\n", BuslogicRequests->CmdBlock.new.DataLength);
|
||||
}
|
||||
}
|
||||
else if (BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)
|
||||
{
|
||||
if (BuslogicRequests->Is24bit)
|
||||
{
|
||||
U32_TO_ADDR(BuslogicRequests->CmdBlock.old.DataLength, 0);
|
||||
BuslogicLog("24-bit Residual data length for reading: %d\n", ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength));
|
||||
}
|
||||
else
|
||||
{
|
||||
BuslogicRequests->CmdBlock.new.DataLength = 0;
|
||||
BuslogicLog("32-bit Residual data length for reading: %d\n", BuslogicRequests->CmdBlock.new.DataLength);
|
||||
}
|
||||
}
|
||||
|
||||
if (SCSIStatus == SCSI_STATUS_OK)
|
||||
{
|
||||
@@ -1593,7 +1665,8 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer,
|
||||
{
|
||||
BuslogicMailboxIn(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR);
|
||||
|
||||
if (Mailbox32->u.out.ActionCode == MBO_START)
|
||||
// if (Mailbox32->u.out.ActionCode == MBO_START && Lun == 0)
|
||||
if (Mailbox32->u.out.ActionCode == MBO_START && Lun <= 7)
|
||||
BuslogicStartMailbox(Buslogic);
|
||||
}
|
||||
}
|
||||
@@ -1665,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);
|
||||
@@ -1678,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()
|
||||
@@ -1709,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);
|
||||
|
||||
@@ -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]);
|
||||
|
||||
|
||||
227
src/cdrom.c
227
src/cdrom.c
@@ -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)
|
||||
|
||||
10
src/cdrom.h
10
src/cdrom.h
@@ -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);
|
||||
|
||||
@@ -415,6 +415,8 @@ enum
|
||||
ROM_THOR, /*Intel Advanced/ATX / 430FX / AMI BIOS / National Semiconductors PC87306*/
|
||||
ROM_MRTHOR, /*Intel Advanced/ATX / 430FX / MR.BIOS / National Semiconductors PC87306*/
|
||||
ROM_POWERMATE_V,/*NEC PowerMate V / 430FX / Phoenix BIOS / SMC FDC37C665*/
|
||||
|
||||
ROM_IBMPS1_2121_ISA,/*IBM PS/1 Model 2121 with ISA expansion bus*/
|
||||
|
||||
ROM_MAX
|
||||
};
|
||||
|
||||
89
src/ide.c
89
src/ide.c
@@ -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;
|
||||
|
||||
175
src/mem.c
175
src/mem.c
@@ -957,84 +957,115 @@ int mem_cpl3_check()
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The relevant page table entry bits are:
|
||||
0 = P (1 = page is present, 0 = page is not present);
|
||||
1 = R/W (0 = read-only for user, 1 = writable for user);
|
||||
2 = U/S (0 = system page, 1 = user page). */
|
||||
void mmu_page_fault(uint32_t addr, uint32_t error_code)
|
||||
{
|
||||
cr2 = addr;
|
||||
cpu_state.abrt = ABRT_PF;
|
||||
abrt_error = error_code;
|
||||
}
|
||||
|
||||
int mmu_page_fault_check(uint32_t addr, int rw, uint32_t flags, int pde, int is_abrt)
|
||||
{
|
||||
uint8_t error_code = 0;
|
||||
|
||||
uint8_t is_page_fault = 0;
|
||||
|
||||
if (mem_cpl3_check()) error_code = 4; /* If CPL = 3 and it's not a PDE check, set US bit. */
|
||||
if (rw) error_code |= 2; /* If writing and it's not a PDE check, set RW bit. */
|
||||
|
||||
if (!(flags & 1))
|
||||
{
|
||||
// pclog("Trying to read or write a page that is not present!\n");
|
||||
is_page_fault = 1;
|
||||
}
|
||||
|
||||
if (!pde)
|
||||
{
|
||||
if (!(flags & 4) && mem_cpl3_check())
|
||||
{
|
||||
// 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");
|
||||
is_page_fault = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_page_fault)
|
||||
{
|
||||
if (is_abrt)
|
||||
{
|
||||
mmu_page_fault(addr, error_code | (flags & 1));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PAGE_DIRTY_AND_ACCESSED 0x60
|
||||
#define PAGE_DIRTY 0x40
|
||||
#define PAGE_ACCESSED 0x20
|
||||
|
||||
/* rw means 0 = read, 1 = write */
|
||||
uint32_t mmutranslate(uint32_t addr, int rw, int is_abrt)
|
||||
{
|
||||
/* Mask out the lower 12 bits. */
|
||||
uint32_t dir_base = 0;
|
||||
|
||||
uint32_t table_addr = 0;
|
||||
uint32_t page_addr = 0;
|
||||
|
||||
uint32_t table_flags = 0;
|
||||
uint32_t page_flags = 0;
|
||||
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
dir_base = cr3 & ~0xfff;
|
||||
table_addr = dir_base + ((addr >> 20) & 0xffc);
|
||||
|
||||
/* First check the flags of the page directory entry. */
|
||||
table_flags = ((uint32_t *)ram)[table_addr >> 2];
|
||||
|
||||
if (mmu_page_fault_check(addr, rw, table_flags & 7, 1, is_abrt) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
page_addr = table_flags & ~0xfff;
|
||||
page_addr += ((addr >> 10) & 0xffc);
|
||||
|
||||
/* Then check the flags of the page table entry. */
|
||||
page_flags = ((uint32_t *)ram)[page_addr >> 2];
|
||||
|
||||
if (mmu_page_fault_check(addr, rw, page_flags & 7, 0, is_abrt) == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (is_abrt)
|
||||
{
|
||||
mmu_perm = page_flags & 4;
|
||||
((uint32_t *)ram)[table_addr >> 2] |= PAGE_ACCESSED;
|
||||
((uint32_t *)ram)[page_addr >> 2] |= (rw ? PAGE_DIRTY_AND_ACCESSED : PAGE_ACCESSED);
|
||||
}
|
||||
|
||||
return (page_flags & ~0xFFF) + (addr & 0xFFF);
|
||||
}
|
||||
|
||||
uint32_t mmutranslatereal(uint32_t addr, int rw)
|
||||
{
|
||||
uint32_t pde_addr;
|
||||
uint32_t section_flags;
|
||||
uint32_t temp_section_flags;
|
||||
uint32_t masked_flags;
|
||||
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
// pclog("Translate recursive abort\n");
|
||||
return -1;
|
||||
}
|
||||
pde_addr = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc));
|
||||
section_flags = temp_section_flags = ((uint32_t *)ram)[pde_addr >> 2];
|
||||
// if (output == 3) pclog("Do translate %08X %i %08X\n", addr, rw, section_flags);
|
||||
if (!(section_flags & 1))// || !(section_flags & 4) && mem_cpl3_check()) || (rw && !(section_flags & 2) && (mem_cpl3_check() || (cr0 & WP_FLAG))))
|
||||
{
|
||||
// if (!nopageerrors) pclog("Section not present! %08X %08X %02X %04X:%08X %i %i\n",addr,temp,opcode,CS,cpu_state.pc,CPL,rw);
|
||||
|
||||
cr2 = addr;
|
||||
section_flags &= 1;
|
||||
if (CPL==3) section_flags |= 4;
|
||||
if (rw) section_flags |= 2;
|
||||
cpu_state.abrt = ABRT_PF;
|
||||
abrt_error = section_flags;
|
||||
return -1;
|
||||
}
|
||||
section_flags = ((uint32_t *)ram)[((section_flags & ~0xFFF) + ((addr >> 10) & 0xFFC))>>2];
|
||||
masked_flags = section_flags & temp_section_flags;
|
||||
// if (output == 3) pclog("Do translate %08X %08X\n", section_flags, temp3);
|
||||
if (!(section_flags & 1) || (!(masked_flags & 4) && mem_cpl3_check()) || (rw && !(masked_flags & 2) && (mem_cpl3_check() || (cr0 & WP_FLAG))))
|
||||
{
|
||||
// if (!nopageerrors) pclog("Page not present! %08X %08X %02X %02X %i %08X %04X:%08X %04X:%08X %i %i %i\n",addr,section_flags,opcode,opcode2,frame,rmdat32, CS,cpu_state.pc,SS,ESP,ins,CPL,rw);
|
||||
|
||||
cr2 = addr;
|
||||
section_flags &= 1;
|
||||
if (CPL==3) section_flags |= 4;
|
||||
if (rw) section_flags |= 2;
|
||||
cpu_state.abrt = ABRT_PF;
|
||||
abrt_error = section_flags;
|
||||
// pclog("%04X\n",cpu_state.abrt);
|
||||
return -1;
|
||||
}
|
||||
mmu_perm = section_flags & 4;
|
||||
((uint32_t *)ram)[pde_addr >> 2] |= 0x20;
|
||||
((uint32_t *)ram)[((temp_section_flags & ~0xFFF) + ((addr >> 10) & 0xFFC)) >> 2] |= (rw ? 0x60 : 0x20);
|
||||
// /*if (output) */pclog("Translate %08X %08X %08X %08X:%08X %08X\n",addr,(temp&~0xFFF)+(addr&0xFFF),section_flags,cs,cpu_state.pc,EDI);
|
||||
|
||||
return (section_flags & ~0xFFF) + (addr & 0xFFF);
|
||||
return mmutranslate(addr, rw, 1);
|
||||
}
|
||||
|
||||
uint32_t mmutranslate_noabrt(uint32_t addr, int rw)
|
||||
{
|
||||
uint32_t pde_addr;
|
||||
uint32_t section_flags;
|
||||
uint32_t temp_section_flags;
|
||||
uint32_t masked_flags;
|
||||
|
||||
if (cpu_state.abrt)
|
||||
return -1;
|
||||
|
||||
pde_addr = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc));
|
||||
section_flags = temp_section_flags = ((uint32_t *)ram)[pde_addr >> 2];
|
||||
|
||||
if (!(section_flags & 1))
|
||||
return -1;
|
||||
|
||||
section_flags = ((uint32_t *)ram)[((section_flags & ~0xFFF)+((addr >> 10) & 0xFFC)) >> 2];
|
||||
masked_flags = section_flags & temp_section_flags;
|
||||
|
||||
if (!(section_flags & 1) || (!(masked_flags & 4) && mem_cpl3_check()) || (rw && !(masked_flags & 2) && (mem_cpl3_check() || (cr0 & WP_FLAG))))
|
||||
return -1;
|
||||
|
||||
return (section_flags & ~0xFFF) + (addr & 0xFFF);
|
||||
return mmutranslate(addr, rw, 0);
|
||||
}
|
||||
|
||||
void mmu_invalidate(uint32_t addr)
|
||||
|
||||
@@ -146,6 +146,7 @@ MODEL models[] =
|
||||
{"DELL System 200", ROM_DELL200, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL},
|
||||
{"IBM PS/1 model 2011", ROM_IBMPS1_2011, { "", cpus_ps1_m2011,"", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2011_init, NULL},
|
||||
{"IBM PS/1 model 2121", ROM_IBMPS1_2121, { "Intel", cpus_i386, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL},
|
||||
{"IBM PS/1 m.2121+ISA", ROM_IBMPS1_2121_ISA, { "Intel", cpus_i386, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL},
|
||||
{"Compaq Deskpro 386", ROM_DESKPRO_386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL},
|
||||
{"Acer 386SX25/N", ROM_ACER386, { "Intel", cpus_acer, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, at_acer386sx_init, NULL},
|
||||
{"DTK 386SX clone", ROM_DTK386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL},
|
||||
|
||||
18
src/pc.c
18
src/pc.c
@@ -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);
|
||||
|
||||
|
||||
48
src/pc.rc
48
src/pc.rc
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
88
src/scsi.c
88
src/scsi.c
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
120
src/win-crashdump.c
Normal file
120
src/win-crashdump.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/* Copyright holders: Riley
|
||||
see COPYING for more details
|
||||
|
||||
win-crashdump.c : Windows exception handler to make a crash dump just before a crash happens.
|
||||
*/
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "86box.h"
|
||||
#include "win-crashdump.h"
|
||||
|
||||
PVOID hExceptionHandler;
|
||||
char* ExceptionHandlerBuffer;
|
||||
|
||||
|
||||
LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo) {
|
||||
// Win32-specific functions will be used wherever possible, just in case the C stdlib-equivalents try to allocate memory.
|
||||
// (The Win32-specific functions are generally just wrappers over NT system calls anyway.)
|
||||
|
||||
if ((ExceptionInfo->ExceptionRecord->ExceptionCode >> 28) != 0xC) {
|
||||
// The exception code is not a fatal exception (highest 4 bits of ntstatus = 0xC)
|
||||
// Not going to crash, let's not make a crash dump
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
// So, the program is about to crash. Oh no what do?
|
||||
// Let's create a crash dump file as a debugging-aid.
|
||||
|
||||
// First, what would a good filename be? It should contain the current date and time so as to be (hopefully!) unique.
|
||||
SYSTEMTIME SystemTime;
|
||||
GetSystemTime(&SystemTime);
|
||||
sprintf(ExceptionHandlerBuffer,
|
||||
"86box-%d%02d%02d-%02d-%02d-%02d-%03d.dmp",
|
||||
SystemTime.wYear,
|
||||
SystemTime.wMonth,
|
||||
SystemTime.wDay,
|
||||
SystemTime.wHour,
|
||||
SystemTime.wMinute,
|
||||
SystemTime.wSecond,
|
||||
SystemTime.wMilliseconds);
|
||||
|
||||
DWORD Error;
|
||||
|
||||
// Now the filename is in the buffer, the file can be created.
|
||||
HANDLE hDumpFile = CreateFile(
|
||||
ExceptionHandlerBuffer, // The filename of the file to open.
|
||||
GENERIC_WRITE, // The permissions to request.
|
||||
0, // Make sure other processes can't touch the crash dump at all while it's open.
|
||||
NULL, // Leave the security descriptor undefined, it doesn't matter.
|
||||
OPEN_ALWAYS, // Opens the file if it exists, creates a new file if it doesn't.
|
||||
FILE_ATTRIBUTE_NORMAL, // File attributes / etc don't matter.
|
||||
NULL); // A template file is not being used.
|
||||
|
||||
// Check to make sure the file was actually created.
|
||||
if (hDumpFile == INVALID_HANDLE_VALUE) {
|
||||
// CreateFile() failed, so just do nothing more.
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
// Now the file is open, let's write the data we were passed out in a human-readable format.
|
||||
|
||||
sprintf(ExceptionHandlerBuffer,
|
||||
"86Box version %s crashed on %d-%02d-%02d %02d:%02d:%02d.%03d\r\n\r\n"
|
||||
""
|
||||
"Exception details:\r\n"
|
||||
"Exception NTSTATUS code: 0x%08x\r\n"
|
||||
"Occured at address: 0x%p\r\n"
|
||||
"Number of parameters: %d\r\n"
|
||||
"Exception parameters: ",
|
||||
emulator_version, SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds,
|
||||
|
||||
ExceptionInfo->ExceptionRecord->ExceptionCode,
|
||||
ExceptionInfo->ExceptionRecord->ExceptionAddress,
|
||||
ExceptionInfo->ExceptionRecord->NumberParameters);
|
||||
|
||||
char* CurrentBufferPointer;
|
||||
|
||||
for (int i = 0; i < ExceptionInfo->ExceptionRecord->NumberParameters; i++) {
|
||||
CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)];
|
||||
sprintf(CurrentBufferPointer,"0x%p ",ExceptionInfo->ExceptionRecord->ExceptionInformation[i]);
|
||||
}
|
||||
|
||||
CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer) - 1];
|
||||
|
||||
PCONTEXT Registers = ExceptionInfo->ContextRecord;
|
||||
|
||||
#if defined(__i386__) && !defined(__x86_64)
|
||||
sprintf(CurrentBufferPointer,
|
||||
"\r\n"
|
||||
"Register dump:\r\n"
|
||||
"eax=0x%08x ebx=0x%08x ecx=0x%08x edx=0x%08x ebp=0x%08x esp=0x%08x esi=0x%08x edi=0x%08x eip=0x%08x\r\n"
|
||||
"\r\n",
|
||||
Registers->Eax, Registers->Ebx, Registers->Ecx, Registers->Edx, Registers->Ebp, Registers->Esp, Registers->Esi, Registers->Edi, Registers->Eip);
|
||||
#else
|
||||
// Register dump is supported by no other architectures right now. MinGW headers seem to lack the x64 CONTEXT structure definition.
|
||||
sprintf(CurrentBufferPointer,"\r\n");
|
||||
#endif
|
||||
|
||||
WriteFile(hDumpFile,
|
||||
ExceptionHandlerBuffer,
|
||||
strlen(ExceptionHandlerBuffer),
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
// Finally, close the file.
|
||||
CloseHandle(hDumpFile);
|
||||
|
||||
// And return, therefore causing the crash, but only after the crash dump has been created.
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
void InitCrashDump() {
|
||||
// An exception handler should not allocate memory, so allocate 10kb for it to use if it gets called, an amount which should be more than enough.
|
||||
ExceptionHandlerBuffer = malloc(10240);
|
||||
// Register the exception handler. Zero first argument means this exception handler gets called last, therefore, crash dump is only made, when a crash is going to happen.
|
||||
hExceptionHandler = AddVectoredExceptionHandler(0,MakeCrashDump);
|
||||
}
|
||||
7
src/win-crashdump.h
Normal file
7
src/win-crashdump.h
Normal file
@@ -0,0 +1,7 @@
|
||||
/* Copyright holders: Riley
|
||||
see COPYING for more details
|
||||
|
||||
win-crashdump.c : Windows crash dump exception handler header file.
|
||||
*/
|
||||
|
||||
void InitCrashDump();
|
||||
42
src/win.c
42
src/win.c
@@ -44,6 +44,7 @@
|
||||
#include "win-d3d.h"
|
||||
#include "win-d3d-fs.h"
|
||||
//#include "win-opengl.h"
|
||||
#include "win-crashdump.h"
|
||||
|
||||
#ifndef MAPVK_VK_TO_VSC
|
||||
#define MAPVK_VK_TO_VSC 0
|
||||
@@ -525,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)
|
||||
{
|
||||
@@ -556,6 +558,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
|
||||
char emulator_title[200];
|
||||
LARGE_INTEGER qpc_freq;
|
||||
HACCEL haccel; /* Handle to accelerator table */
|
||||
|
||||
InitCrashDump(); // First thing to do before anything else is to make sure crash dumps get created.
|
||||
|
||||
process_command_line();
|
||||
|
||||
@@ -660,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);
|
||||
@@ -1050,7 +1061,8 @@ LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam )
|
||||
BOOL bControlKeyDown;
|
||||
KBDLLHOOKSTRUCT* p;
|
||||
|
||||
if (nCode < 0 || nCode != HC_ACTION || (!mousecapture && !video_fullscreen))
|
||||
// if (nCode < 0 || nCode != HC_ACTION || (!mousecapture && !video_fullscreen))
|
||||
if (nCode < 0 || nCode != HC_ACTION)
|
||||
return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam);
|
||||
|
||||
p = (KBDLLHOOKSTRUCT*)lParam;
|
||||
@@ -1681,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)
|
||||
{
|
||||
@@ -2152,7 +2184,9 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
||||
break;
|
||||
|
||||
case WM_SYSCOMMAND:
|
||||
if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0 && (video_fullscreen || mousecapture))
|
||||
// if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0 && (video_fullscreen || mousecapture))
|
||||
/* Disable ALT key *ALWAYS*, I don't think there's any use for reaching the menu that way. */
|
||||
if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0)
|
||||
return 0; /*disable ALT key for menu*/
|
||||
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user