mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 17:45:31 -07:00
Reverted Direct3D to 2048x2048 buffer and suppressed the EGA/(S)VGA overscan, if enabled, in 2048x modes, fixes Direct3D freezes;
Improved the BusLogic incoming mailbox code; The BusLogic callback is now three-phases and outgoing mailbox interrupts are emulated correctly; Fixed the CD-ROM command READ DISC INFORMATION (0x51), fixes NetBSD crashing 86Box with segmentation fault when using the AHA-154x; Added the CD-ROM command PAUSE/RESUME ALT (0xC2).
This commit is contained in:
331
src/buslogic.c
331
src/buslogic.c
@@ -480,6 +480,9 @@ typedef struct __attribute__((packed)) BuslogicRequests_t
|
||||
int Is24bit;
|
||||
uint8_t TargetID;
|
||||
uint8_t LUN;
|
||||
uint8_t HostStatus;
|
||||
uint8_t TargetStatus;
|
||||
uint8_t MailboxCompletionCode;
|
||||
} BuslogicRequests_t;
|
||||
|
||||
typedef struct __attribute__((packed)) Buslogic_t
|
||||
@@ -512,7 +515,6 @@ typedef struct __attribute__((packed)) Buslogic_t
|
||||
int Mbx24bit;
|
||||
int MailboxOutInterrupts;
|
||||
int MbiActive[256];
|
||||
int DoScan;
|
||||
int PendingInterrupt;
|
||||
} Buslogic_t;
|
||||
|
||||
@@ -521,9 +523,10 @@ int scsi_base = 0x330;
|
||||
int scsi_dma = 6;
|
||||
int scsi_irq = 11;
|
||||
|
||||
int buslogic_do_log = 0;
|
||||
|
||||
int BuslogicCallback = 0;
|
||||
int BuslogicInOperation = 0;
|
||||
|
||||
int buslogic_do_log = 0;
|
||||
|
||||
static void BuslogicStartMailbox(Buslogic_t *Buslogic);
|
||||
|
||||
@@ -596,8 +599,8 @@ static void BuslogicReset(Buslogic_t *Buslogic)
|
||||
Buslogic->MailboxOutPosCur = 0;
|
||||
Buslogic->MailboxInPosCur = 0;
|
||||
Buslogic->MailboxOutInterrupts = 0;
|
||||
Buslogic->DoScan = 0;
|
||||
Buslogic->PendingInterrupt = 0;
|
||||
BuslogicInOperation = 0;
|
||||
|
||||
BuslogicClearInterrupt(Buslogic);
|
||||
|
||||
@@ -617,9 +620,8 @@ static void BuslogicResetControl(Buslogic_t *Buslogic, uint8_t Reset)
|
||||
static void BuslogicCommandComplete(Buslogic_t *Buslogic)
|
||||
{
|
||||
Buslogic->DataReply = 0;
|
||||
|
||||
Buslogic->Status |= STAT_IDLE;
|
||||
|
||||
|
||||
if (Buslogic->Command != 0x02)
|
||||
{
|
||||
Buslogic->Status &= ~STAT_DFULL;
|
||||
@@ -632,6 +634,38 @@ static void BuslogicCommandComplete(Buslogic_t *Buslogic)
|
||||
Buslogic->CmdParam = 0;
|
||||
}
|
||||
|
||||
static void BuslogicRaiseInterrupt(Buslogic_t *Buslogic, uint8_t Interrupt)
|
||||
{
|
||||
if (Buslogic->Interrupt & INTR_HACC)
|
||||
{
|
||||
BuslogicLog("Pending IRQ\n");
|
||||
Buslogic->PendingInterrupt = Interrupt;
|
||||
}
|
||||
else
|
||||
{
|
||||
Buslogic->Interrupt = Interrupt;
|
||||
BuslogicLog("Raising IRQ %i\n", Buslogic->Irq);
|
||||
if (Buslogic->IrqEnabled) picint(1 << Buslogic->Irq);
|
||||
}
|
||||
}
|
||||
|
||||
static void BuslogicMailboxInSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *CmdBlock,
|
||||
uint8_t HostStatus, uint8_t TargetStatus, uint8_t MailboxCompletionCode)
|
||||
{
|
||||
BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests;
|
||||
|
||||
BuslogicRequests->CCBPointer = CCBPointer;
|
||||
memcpy(&(BuslogicRequests->CmdBlock), CmdBlock, sizeof(CCB32));
|
||||
BuslogicRequests->Is24bit = Buslogic->Mbx24bit;
|
||||
BuslogicRequests->HostStatus = HostStatus;
|
||||
BuslogicRequests->TargetStatus = TargetStatus;
|
||||
BuslogicRequests->MailboxCompletionCode = MailboxCompletionCode;
|
||||
|
||||
BuslogicLog("Mailbox in setup\n");
|
||||
|
||||
BuslogicInOperation = 2;
|
||||
}
|
||||
|
||||
static uint32_t BuslogicMailboxInRead(Buslogic_t *Buslogic, uint8_t *CompletionCode)
|
||||
{
|
||||
Mailbox32_t TempMailbox32;
|
||||
@@ -660,50 +694,28 @@ static void BuslogicMailboxInAdvance(Buslogic_t *Buslogic)
|
||||
Buslogic->MailboxInPosCur = (Buslogic->MailboxInPosCur + 1) % Buslogic->MailboxCount;
|
||||
}
|
||||
|
||||
static void BuslogicMailboxIn(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *CmdBlock,
|
||||
uint8_t HostStatus, uint8_t TargetStatus, uint8_t MailboxCompletionCode)
|
||||
static void BuslogicMailboxIn(Buslogic_t *Buslogic)
|
||||
{
|
||||
BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests;
|
||||
|
||||
uint32_t CCBPointer = BuslogicRequests->CCBPointer;
|
||||
CCBU *CmdBlock = &(BuslogicRequests->CmdBlock);
|
||||
uint8_t HostStatus = BuslogicRequests->HostStatus;
|
||||
uint8_t TargetStatus = BuslogicRequests->TargetStatus;
|
||||
uint8_t MailboxCompletionCode = BuslogicRequests->MailboxCompletionCode;
|
||||
|
||||
Mailbox32_t Mailbox32;
|
||||
Mailbox_t MailboxIn;
|
||||
|
||||
Mailbox32_t TempMailbox32;
|
||||
Mailbox_t TempMailboxIn;
|
||||
|
||||
uint32_t Incoming = 0;
|
||||
uint32_t i = 0;
|
||||
|
||||
uint8_t CompletionCode = 0;
|
||||
|
||||
Mailbox32.CCBPointer = CCBPointer;
|
||||
Mailbox32.u.in.HostStatus = HostStatus;
|
||||
Mailbox32.u.in.TargetStatus = TargetStatus;
|
||||
Mailbox32.u.in.CompletionCode = MailboxCompletionCode;
|
||||
|
||||
Incoming = 0;
|
||||
|
||||
if (!Buslogic->StrictRoundRobinMode)
|
||||
{
|
||||
uint8_t MailboxCur = Buslogic->MailboxInPosCur;
|
||||
|
||||
/* Search for a filled mailbox - stop if we have scanned all mailboxes. */
|
||||
do
|
||||
{
|
||||
/* Fetch mailbox from guest memory. */
|
||||
Incoming = BuslogicMailboxInRead(Buslogic, &CompletionCode);
|
||||
|
||||
/* Check the next mailbox. */
|
||||
BuslogicMailboxInAdvance(Buslogic);
|
||||
} while ((CompletionCode != MBI_FREE) && (MailboxCur != Buslogic->MailboxInPosCur));
|
||||
}
|
||||
else
|
||||
{
|
||||
Incoming = BuslogicMailboxInRead(Buslogic, &CompletionCode);
|
||||
}
|
||||
|
||||
if (CompletionCode != MBI_FREE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
uint32_t Incoming = Buslogic->MailboxInAddr + (Buslogic->MailboxInPosCur * (Buslogic->Mbx24bit ? sizeof(Mailbox_t) : sizeof(Mailbox32_t)));
|
||||
|
||||
if (MailboxCompletionCode != MBI_NOT_FOUND)
|
||||
{
|
||||
@@ -734,30 +746,17 @@ static void BuslogicMailboxIn(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *C
|
||||
{
|
||||
BuslogicLog("Mailbox 32-bit: Status=0x%02X, CCB at 0x%04X\n", Mailbox32.u.in.CompletionCode, Mailbox32.CCBPointer);
|
||||
|
||||
if (Incoming != 0)
|
||||
{
|
||||
DMAPageWrite(Incoming, &Mailbox32, sizeof(Mailbox32_t));
|
||||
BuslogicLog("%i bytes of 32-bit mailbox written to: %08X\n", sizeof(Mailbox32_t), Incoming);
|
||||
}
|
||||
DMAPageWrite(Incoming, &Mailbox32, sizeof(Mailbox32_t));
|
||||
BuslogicLog("%i bytes of 32-bit mailbox written to: %08X\n", sizeof(Mailbox32_t), Incoming);
|
||||
}
|
||||
|
||||
Buslogic->MailboxInPosCur++;
|
||||
if (Buslogic->MailboxInPosCur >= Buslogic->MailboxCount)
|
||||
Buslogic->MailboxInPosCur = 0;
|
||||
|
||||
/* Advance to the next mailbox. */
|
||||
if (Buslogic->StrictRoundRobinMode)
|
||||
{
|
||||
BuslogicMailboxInAdvance(Buslogic);
|
||||
}
|
||||
BuslogicRaiseInterrupt(Buslogic, INTR_MBIF | INTR_ANY);
|
||||
|
||||
if (Buslogic->Interrupt & INTR_HACC)
|
||||
{
|
||||
BuslogicLog("Pending IRQ\n");
|
||||
Buslogic->PendingInterrupt = INTR_MBIF | INTR_ANY;
|
||||
}
|
||||
else
|
||||
{
|
||||
Buslogic->Interrupt = INTR_MBIF | INTR_ANY;
|
||||
BuslogicLog("Raising IRQ %i\n", Buslogic->Irq);
|
||||
if (Buslogic->IrqEnabled) picint(1 << Buslogic->Irq);
|
||||
}
|
||||
BuslogicInOperation = 0;
|
||||
}
|
||||
|
||||
static void BuslogicReadSGEntries(int Is24bit, uint32_t SGList, uint32_t Entries, SGE32 *SG)
|
||||
@@ -844,7 +843,7 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi
|
||||
|
||||
//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.
|
||||
if (BuslogicRequests->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT || BuslogicRequests->CmdBlock.common.ControlByte == 0x00)
|
||||
if ((BuslogicRequests->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT) || (BuslogicRequests->CmdBlock.common.ControlByte == 0x00))
|
||||
{
|
||||
ScatterGatherLeft = DataLength / ScatterGatherEntryLength;
|
||||
ScatterGatherAddrCurrent = DataPointer;
|
||||
@@ -891,20 +890,11 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t BuslogicGetDataLength(BuslogicRequests_t *BuslogicRequests)
|
||||
{
|
||||
if (BuslogicRequests->Is24bit)
|
||||
{
|
||||
return ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
return BuslogicRequests->CmdBlock.new.DataLength;
|
||||
}
|
||||
}
|
||||
|
||||
void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests)
|
||||
{
|
||||
uint32_t DataPointer = 0;
|
||||
uint32_t DataLength = 0;
|
||||
|
||||
uint32_t sg_buffer_pos = 0;
|
||||
|
||||
uint32_t transfer_length = 0;
|
||||
@@ -936,7 +926,7 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests)
|
||||
}
|
||||
|
||||
BuslogicLog("Data Buffer read: length %d, pointer 0x%04X\n", DataLength, DataPointer);
|
||||
|
||||
|
||||
//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 read/write commands.
|
||||
if ((DataLength > 0) &&
|
||||
@@ -999,7 +989,7 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests)
|
||||
/* Should be 0 when scatter/gather? */
|
||||
if (DataLength >= SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength)
|
||||
{
|
||||
Residual = BuslogicGetDataLength(BuslogicRequests);
|
||||
Residual = DataLength;
|
||||
Residual -= SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength;
|
||||
}
|
||||
else
|
||||
@@ -1100,7 +1090,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
|
||||
|
||||
Buslogic_t *Buslogic = (Buslogic_t *)p;
|
||||
BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests;
|
||||
// BuslogicLog("Buslogic: Write Port 0x%02X, Value %02X\n", Port, Val);
|
||||
BuslogicLog("Buslogic: Write Port 0x%02X, Value %02X\n", Port, Val);
|
||||
|
||||
switch (Port & 3)
|
||||
{
|
||||
@@ -1119,11 +1109,20 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (!(Buslogic->Status & STAT_IDLE) && (Buslogic->Command == 0xFF) && (Val != 0x02) && (Val != 0x05))
|
||||
/* Fast path for the mailbox execution command. */
|
||||
if ((Val == 0x02) && (Buslogic->Command == 0xFF))
|
||||
{
|
||||
break; /* Any command other than 02 and 05 can only be executed when the IDLE bit is set. */
|
||||
/* If there are no mailboxes configured, don't even try to do anything. */
|
||||
if (Buslogic->MailboxCount)
|
||||
{
|
||||
if (!BuslogicCallback)
|
||||
{
|
||||
BuslogicCallback = 50 * SCSI_TIME;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (Buslogic->Command == 0xFF)
|
||||
{
|
||||
Buslogic->Command = Val;
|
||||
@@ -1134,7 +1133,6 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
|
||||
switch (Buslogic->Command)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x02:
|
||||
case 0x04:
|
||||
case 0x0A:
|
||||
case 0x0B:
|
||||
@@ -1229,27 +1227,6 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
if (Buslogic->Status & STAT_INIT)
|
||||
{
|
||||
Buslogic->Status |= STAT_INVCMD;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!BuslogicCallback)
|
||||
{
|
||||
BuslogicLog("SCSI started\n");
|
||||
BuslogicCallback = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
BuslogicLog("SCSI reactivated\n");
|
||||
}
|
||||
Buslogic->DoScan = 1;
|
||||
}
|
||||
Buslogic->DataReplyLeft = 0;
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
Buslogic->DataBuf[0] = 0x41;
|
||||
Buslogic->DataBuf[1] = scsi_model ? 0x41 : 0x30;
|
||||
@@ -1507,6 +1484,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
|
||||
ReplyInquireExtendedSetupInformation *Reply = (ReplyInquireExtendedSetupInformation *)Buslogic->DataBuf;
|
||||
|
||||
Reply->uBusType = 'A'; /* ISA style */
|
||||
Reply->uBiosAddress = 0;
|
||||
Reply->u16ScatterGatherLimit = 8192;
|
||||
Reply->cMailbox = Buslogic->MailboxCount;
|
||||
Reply->uMailboxAddressBase = Buslogic->MailboxOutAddr;
|
||||
@@ -1520,15 +1498,21 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
/* VirtualBox has these two modes implemented in reverse.
|
||||
According to the BusLogic datasheet:
|
||||
0 is the strict round robin mode, which is also the one used by the AHA-154x according to the
|
||||
Adaptec specification;
|
||||
1 is the aggressive round robin mode, which "hunts" for an active outgoing mailbox and then
|
||||
processes it. */
|
||||
case 0x8F:
|
||||
if (scsi_model)
|
||||
{
|
||||
if (Buslogic->CmdBuf[0] == 0)
|
||||
Buslogic->StrictRoundRobinMode = 0;
|
||||
else if (Buslogic->CmdBuf[0] == 1)
|
||||
Buslogic->StrictRoundRobinMode = 1;
|
||||
|
||||
else if (Buslogic->CmdBuf[0] == 1)
|
||||
Buslogic->StrictRoundRobinMode = 0;
|
||||
|
||||
Buslogic->DataReplyLeft = 0;
|
||||
}
|
||||
else
|
||||
@@ -1636,24 +1620,29 @@ static void BuslogicSenseBufferFree(BuslogicRequests_t *BuslogicRequests, int Co
|
||||
|
||||
BuslogicLog("Request Sense address: %02X\n", SenseBufferAddress);
|
||||
|
||||
if (SenseBufferAddress)
|
||||
{
|
||||
BuslogicLog("BuslogicSenseBufferFree(): Writing %i bytes at %08X\n", SenseLength, SenseBufferAddress);
|
||||
DMAPageWrite(SenseBufferAddress, temp_sense, SenseLength);
|
||||
BuslogicLog("Sense data written to buffer: %02X %02X %02X\n", temp_sense[2], temp_sense[12], temp_sense[13]);
|
||||
}
|
||||
BuslogicLog("BuslogicSenseBufferFree(): Writing %i bytes at %08X\n", SenseLength, SenseBufferAddress);
|
||||
DMAPageWrite(SenseBufferAddress, temp_sense, SenseLength);
|
||||
BuslogicLog("Sense data written to buffer: %02X %02X %02X\n", temp_sense[2], temp_sense[12], temp_sense[13]);
|
||||
}
|
||||
}
|
||||
|
||||
static void BuslogicCDROMCommand(Buslogic_t *Buslogic, uint8_t Id, uint8_t Lun, uint8_t cdrom_id)
|
||||
static void BuslogicCDROMCommand(Buslogic_t *Buslogic)
|
||||
{
|
||||
BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests;
|
||||
uint8_t Id, Lun;
|
||||
|
||||
uint8_t cdrom_id;
|
||||
uint8_t cdrom_phase;
|
||||
|
||||
uint32_t temp = 0;
|
||||
|
||||
uint8_t temp_cdb[12];
|
||||
uint32_t i;
|
||||
|
||||
Id = BuslogicRequests->TargetID;
|
||||
Lun = BuslogicRequests->LUN;
|
||||
|
||||
cdrom_id = scsi_cdrom_drives[Id][Lun];
|
||||
|
||||
BuslogicLog("CD-ROM command being executed on: SCSI ID %i, SCSI LUN %i, CD-ROM %i\n", Id, Lun, cdrom_id);
|
||||
|
||||
@@ -1685,7 +1674,6 @@ static void BuslogicCDROMCommand(Buslogic_t *Buslogic, uint8_t Id, uint8_t Lun,
|
||||
//Finally, execute the SCSI command immediately and get the transfer length.
|
||||
|
||||
SCSIPhase = SCSI_PHASE_COMMAND;
|
||||
SCSIDevices[Id][Lun].InitLength = 0;
|
||||
cdrom_command(cdrom_id, temp_cdb);
|
||||
SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id);
|
||||
if (SCSIStatus == SCSI_STATUS_OK)
|
||||
@@ -1712,6 +1700,21 @@ static void BuslogicCDROMCommand(Buslogic_t *Buslogic, uint8_t Id, uint8_t Lun,
|
||||
}
|
||||
|
||||
BuslogicLog("SCSI Status: %s, Sense: %02X, ASC: %02X, ASCQ: %02X\n", (SCSIStatus == SCSI_STATUS_OK) ? "OK" : "CHECK CONDITION", cdrom[cdrom_id].sense[2], cdrom[cdrom_id].sense[12], cdrom[cdrom_id].sense[13]);
|
||||
|
||||
BuslogicDataBufferFree(BuslogicRequests);
|
||||
|
||||
BuslogicSenseBufferFree(BuslogicRequests, (SCSIStatus != SCSI_STATUS_OK));
|
||||
|
||||
BuslogicLog("Request complete\n");
|
||||
|
||||
if (SCSIStatus == SCSI_STATUS_OK)
|
||||
{
|
||||
BuslogicMailboxInSetup(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS);
|
||||
}
|
||||
else if (SCSIStatus == SCSI_STATUS_CHECK_CONDITION)
|
||||
{
|
||||
BuslogicMailboxInSetup(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
static int BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, Mailbox32_t *Mailbox32)
|
||||
@@ -1726,6 +1729,9 @@ static int BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, M
|
||||
|
||||
//Fetch data from the Command Control Block.
|
||||
DMAPageRead(CCBPointer, &BuslogicRequests->CmdBlock, sizeof(CCB32));
|
||||
|
||||
BuslogicRequests->Is24bit = Buslogic->Mbx24bit;
|
||||
BuslogicRequests->CCBPointer = CCBPointer;
|
||||
|
||||
BuslogicRequests->TargetID = Buslogic->Mbx24bit ? BuslogicRequests->CmdBlock.old.Id : BuslogicRequests->CmdBlock.new.Id;
|
||||
BuslogicRequests->LUN = Buslogic->Mbx24bit ? BuslogicRequests->CmdBlock.old.Lun : BuslogicRequests->CmdBlock.new.Lun;
|
||||
@@ -1735,7 +1741,7 @@ static int BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, M
|
||||
|
||||
if ((Id > last_id) || (Lun > 7))
|
||||
{
|
||||
BuslogicMailboxIn(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_INVALID_CCB, SCSI_STATUS_OK, MBI_ERROR);
|
||||
BuslogicMailboxInSetup(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_INVALID_CCB, SCSI_STATUS_OK, MBI_ERROR);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1743,11 +1749,10 @@ static int BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, M
|
||||
|
||||
cdrom_id = scsi_cdrom_drives[Id][Lun];
|
||||
|
||||
BuslogicRequests->CCBPointer = CCBPointer;
|
||||
BuslogicRequests->Is24bit = Buslogic->Mbx24bit;
|
||||
|
||||
SCSIStatus = SCSI_STATUS_OK;
|
||||
|
||||
SCSIDevices[Id][Lun].InitLength = 0;
|
||||
|
||||
BuslogicDataBufferAllocate(BuslogicRequests, BuslogicRequests->Is24bit);
|
||||
|
||||
if (!buslogic_scsi_drive_is_cdrom(Id, Lun))
|
||||
@@ -1758,7 +1763,7 @@ static int BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, M
|
||||
|
||||
BuslogicSenseBufferFree(BuslogicRequests, 0);
|
||||
|
||||
BuslogicMailboxIn(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR);
|
||||
BuslogicMailboxInSetup(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1773,22 +1778,7 @@ static int BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, M
|
||||
BuslogicLog("Invalid control byte: %02X\n", BuslogicRequests->CmdBlock.common.ControlByte);
|
||||
}
|
||||
|
||||
BuslogicCDROMCommand(Buslogic, Id, Lun, cdrom_id);
|
||||
|
||||
BuslogicDataBufferFree(BuslogicRequests);
|
||||
|
||||
BuslogicSenseBufferFree(BuslogicRequests, (SCSIStatus != SCSI_STATUS_OK));
|
||||
|
||||
BuslogicLog("Request complete\n");
|
||||
|
||||
if (SCSIStatus == SCSI_STATUS_OK)
|
||||
{
|
||||
BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS);
|
||||
}
|
||||
else if (SCSIStatus == SCSI_STATUS_CHECK_CONDITION)
|
||||
{
|
||||
BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR);
|
||||
}
|
||||
BuslogicInOperation = 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -1803,7 +1793,7 @@ static int BuslogicSCSIRequestAbort(Buslogic_t *Buslogic, uint32_t CCBPointer)
|
||||
DMAPageRead(CCBPointer, &CmdBlock, sizeof(CCB32));
|
||||
|
||||
//Only SCSI CD-ROMs are supported at the moment, SCSI hard disk support will come soon.
|
||||
BuslogicMailboxIn(Buslogic, CCBPointer, &CmdBlock, 0x26, SCSI_STATUS_OK, MBI_NOT_FOUND);
|
||||
BuslogicMailboxInSetup(Buslogic, CCBPointer, &CmdBlock, 0x26, SCSI_STATUS_OK, MBI_NOT_FOUND);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1873,37 +1863,26 @@ static int BuslogicProcessMailbox(Buslogic_t *Buslogic)
|
||||
Outgoing = BuslogicMailboxOut(Buslogic, &Mailbox32);
|
||||
}
|
||||
|
||||
/* Check if the mailbox is actually loaded. */
|
||||
if (Mailbox32.u.out.ActionCode == MBO_FREE)
|
||||
{
|
||||
// BuslogicLog("No loaded mailbox left\n");
|
||||
|
||||
if (Buslogic->MailboxOutInterrupts)
|
||||
{
|
||||
if (Buslogic->Interrupt & INTR_HACC)
|
||||
{
|
||||
BuslogicLog("Pending IRQ\n");
|
||||
Buslogic->PendingInterrupt = INTR_MBOA | INTR_ANY;
|
||||
}
|
||||
else
|
||||
{
|
||||
BuslogicLog("Raising IRQ %i\n", Buslogic->Irq);
|
||||
Buslogic->Interrupt = INTR_MBOA | INTR_ANY;
|
||||
if (Buslogic->IrqEnabled) picint(1 << Buslogic->Irq);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We got the mailbox, mark it as free in the guest. */
|
||||
if (Mailbox32.u.out.ActionCode != MBO_FREE)
|
||||
{
|
||||
/* We got the mailbox, mark it as free in the guest. */
|
||||
BuslogicLog("BuslogicStartMailbox(): Writing %i bytes at %08X\n", sizeof(CmdStatus), Outgoing + CodeOffset);
|
||||
DMAPageWrite(Outgoing + CodeOffset, &CmdStatus, sizeof(CmdStatus));
|
||||
}
|
||||
|
||||
if ((Mailbox32.u.out.ActionCode == MBO_START) || (Mailbox32.u.out.ActionCode == MBO_FREE))
|
||||
if (Buslogic->MailboxOutInterrupts)
|
||||
{
|
||||
BuslogicRaiseInterrupt(Buslogic, INTR_MBOA | INTR_ANY);
|
||||
}
|
||||
|
||||
/* Check if the mailbox is actually loaded. */
|
||||
if (Mailbox32.u.out.ActionCode == MBO_FREE)
|
||||
{
|
||||
// BuslogicLog("No loaded mailbox left\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Mailbox32.u.out.ActionCode == MBO_START)
|
||||
{
|
||||
BuslogicLog("Start Mailbox Command\n");
|
||||
ret = BuslogicSCSIRequestSetup(Buslogic, Mailbox32.CCBPointer, &Mailbox32);
|
||||
@@ -1932,21 +1911,41 @@ void BuslogicCommandCallback(void *p)
|
||||
{
|
||||
Buslogic_t *Buslogic = (Buslogic_t *)p;
|
||||
|
||||
BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests;
|
||||
|
||||
int ret = 0;
|
||||
int i = 0;
|
||||
|
||||
// BuslogicLog("BusLogic Callback!\n");
|
||||
|
||||
if (Buslogic->MailboxCount)
|
||||
{
|
||||
ret = BuslogicProcessMailbox(Buslogic);
|
||||
// BuslogicLog("BusLogic Callback (%08X)!\n", BuslogicCallback);
|
||||
|
||||
BuslogicCallback += 50 * SCSI_TIME;
|
||||
if (BuslogicInOperation == 0)
|
||||
{
|
||||
BuslogicLog("BusLogic Callback: Start outgoing mailbox\n");
|
||||
if (Buslogic->MailboxCount)
|
||||
{
|
||||
ret = BuslogicProcessMailbox(Buslogic);
|
||||
}
|
||||
else
|
||||
{
|
||||
fatal("Callback active with mailbox count 0!\n");
|
||||
}
|
||||
}
|
||||
else if (BuslogicInOperation == 1)
|
||||
{
|
||||
BuslogicLog("BusLogic Callback: Process request\n");
|
||||
BuslogicCDROMCommand(Buslogic);
|
||||
}
|
||||
else if (BuslogicInOperation == 2)
|
||||
{
|
||||
BuslogicLog("BusLogic Callback: Send incoming mailbox\n");
|
||||
BuslogicMailboxIn(Buslogic);
|
||||
}
|
||||
else
|
||||
{
|
||||
fatal("Callback active with mailbox count 0!\n");
|
||||
fatal("Invalid BusLogic callback phase: %i\n", BuslogicInOperation);
|
||||
}
|
||||
|
||||
BuslogicCallback += 50 * SCSI_TIME;
|
||||
}
|
||||
|
||||
void *BuslogicInit()
|
||||
|
||||
15
src/cdrom.c
15
src/cdrom.c
@@ -117,6 +117,7 @@ uint8_t cdrom_command_flags[0x100] =
|
||||
[GPCMD_MECHANISM_STATUS] = IMPLEMENTED,
|
||||
[GPCMD_READ_CD] = IMPLEMENTED | CHECK_READY,
|
||||
[GPCMD_SEND_DVD_STRUCTURE] = IMPLEMENTED | CHECK_READY,
|
||||
[GPCMD_PAUSE_RESUME_ALT] = IMPLEMENTED | CHECK_READY | SCSI_ONLY,
|
||||
[GPCMD_SCAN_ALT] = IMPLEMENTED | CHECK_READY | SCSI_ONLY,
|
||||
[GPCMD_SET_SPEED_ALT] = IMPLEMENTED | SCSI_ONLY
|
||||
};
|
||||
@@ -2084,6 +2085,10 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
|
||||
break;
|
||||
|
||||
case GPCMD_READ_DISC_INFORMATION:
|
||||
max_len = cdb[7];
|
||||
max_len <<= 8;
|
||||
max_len |= cdb[8];
|
||||
|
||||
if (cdrom_drives[id].handler->pass_through)
|
||||
{
|
||||
ret = cdrom_pass_through(id, &len);
|
||||
@@ -2105,7 +2110,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
|
||||
len=34;
|
||||
}
|
||||
|
||||
cdrom_data_command_finish(id, len, len, alloc_length, 0);
|
||||
cdrom_data_command_finish(id, len, len, max_len, 0);
|
||||
break;
|
||||
|
||||
case GPCMD_READ_TRACK_INFORMATION:
|
||||
@@ -2156,7 +2161,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
|
||||
}
|
||||
}
|
||||
|
||||
cdrom_data_command_finish(id, len, len, alloc_length, 0);
|
||||
cdrom_data_command_finish(id, len, len, max_len, 0);
|
||||
break;
|
||||
|
||||
case GPCMD_PLAY_AUDIO_10:
|
||||
@@ -2326,11 +2331,6 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
|
||||
{
|
||||
ret = cdrom_read_dvd_structure(id, format, cdb, cdbufferb);
|
||||
|
||||
/* if (!ret)
|
||||
{
|
||||
cdrom_cmd_error(id, SENSE_ILLEGAL_REQUEST, -ret, 0);
|
||||
}
|
||||
else */
|
||||
if (ret)
|
||||
{
|
||||
cdrom_data_command_finish(id, len, len, alloc_length, 0);
|
||||
@@ -2467,6 +2467,7 @@ atapi_out:
|
||||
cdrom_command_complete(id);
|
||||
break;
|
||||
|
||||
case GPCMD_PAUSE_RESUME_ALT:
|
||||
case GPCMD_PAUSE_RESUME:
|
||||
if (cdb[8] & 1)
|
||||
{
|
||||
|
||||
12
src/disc.c
12
src/disc.c
@@ -194,14 +194,22 @@ double disc_real_period(int drive)
|
||||
|
||||
dusec = (double) TIMER_USEC;
|
||||
|
||||
return (ddbp * dusec);
|
||||
/* This is a giant hack but until the timings become even more correct, this is needed to make floppies work right on that BIOS. */
|
||||
if (romset == ROM_MRTHOR)
|
||||
{
|
||||
return (ddbp * dusec) / 2.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (ddbp * dusec);
|
||||
}
|
||||
}
|
||||
|
||||
void disc_poll(int drive)
|
||||
{
|
||||
if (drive >= FDD_NUM)
|
||||
{
|
||||
disc_poll_time[drive] += (int) (32.0 * TIMER_USEC);
|
||||
disc_poll_time[drive] += (int) (((romset == ROM_MRTHOR) ? 16.0 : 32.0) * TIMER_USEC);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -594,8 +594,8 @@ void DMAPageRead(uint32_t PhysAddress, void *DataRead, uint32_t TotalSize)
|
||||
void DMAPageWrite(uint32_t PhysAddress, const void *DataWrite, uint32_t TotalSize)
|
||||
{
|
||||
// uint32_t PageLen = PageLengthReadWrite(PhysAddress, TotalSize);
|
||||
memcpy(&ram[PhysAddress], DataWrite, TotalSize);
|
||||
mem_invalidate_range(PhysAddress, PhysAddress + TotalSize - 1);
|
||||
memcpy(&ram[PhysAddress], DataWrite, TotalSize);
|
||||
// DataWrite -= PageLen;
|
||||
DataWrite -= TotalSize;
|
||||
}
|
||||
|
||||
@@ -607,3 +607,5 @@ extern int fdc_do_log;
|
||||
extern int ide_do_log;
|
||||
extern int ne2000_do_log;
|
||||
#endif
|
||||
|
||||
extern int suppress_overscan;
|
||||
|
||||
24
src/ide.c
24
src/ide.c
@@ -378,8 +378,7 @@ static void ide_identify(IDE *ide)
|
||||
if (ide->board < 2)
|
||||
{
|
||||
ide->buffer[53] = 2;
|
||||
ide->buffer[62] = ide->dma_identify_data[0];
|
||||
ide->buffer[63] = ide->dma_identify_data[1];
|
||||
ide->buffer[63] = ide->dma_identify_data[0];
|
||||
ide->buffer[65] = 150;
|
||||
ide->buffer[66] = 150;
|
||||
// ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/
|
||||
@@ -415,8 +414,7 @@ static void ide_atapi_identify(IDE *ide)
|
||||
ide->buffer[49] |= 0x100; /* DMA supported */
|
||||
ide->buffer[52] = 2 << 8; /*DMA timing mode*/
|
||||
ide->buffer[53] = 2;
|
||||
ide->buffer[62] = ide->dma_identify_data[0];
|
||||
ide->buffer[63] = ide->dma_identify_data[1];
|
||||
ide->buffer[63] = ide->dma_identify_data[0];
|
||||
ide->buffer[65] = 150;
|
||||
ide->buffer[66] = 150;
|
||||
// ide->buffer[88] = ide->dma_identify_data[2];
|
||||
@@ -645,29 +643,17 @@ int ide_set_features(IDE *ide)
|
||||
switch(sf_data >> 3)
|
||||
{
|
||||
case 0:
|
||||
ide->dma_identify_data[0] = ide->dma_identify_data[1] = 7;
|
||||
ide->dma_identify_data[2] = 0x3f;
|
||||
ide->dma_identify_data[0] = 7;
|
||||
break;
|
||||
case 1:
|
||||
/* We do not (yet) emulate flow control, so return with error if this is attempted. */
|
||||
return 0;
|
||||
case 2:
|
||||
if (ide_cdrom_is_pio_only(ide) || (ide->board >= 2))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
ide->dma_identify_data[0] = 7 | (1 << (val + 8));
|
||||
ide->dma_identify_data[1] = 7;
|
||||
ide->dma_identify_data[2] = 0x3f;
|
||||
break;
|
||||
case 4:
|
||||
if (ide_cdrom_is_pio_only(ide) || (ide->board >= 2))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
ide->dma_identify_data[0] = 7;
|
||||
ide->dma_identify_data[1] = 7 | (1 << (val + 8));
|
||||
ide->dma_identify_data[2] = 0x3f;
|
||||
ide->dma_identify_data[0] = 7 | (1 << (val + 8));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
@@ -739,8 +725,6 @@ void resetide(void)
|
||||
if (ide_drives[d].type != IDE_NONE)
|
||||
{
|
||||
ide_drives[d].dma_identify_data[0] = 7;
|
||||
ide_drives[d].dma_identify_data[1] = 7 | (1 << 10);
|
||||
ide_drives[d].dma_identify_data[2] = 0x3f;
|
||||
}
|
||||
|
||||
ide_drives[d].error = 1;
|
||||
|
||||
4
src/pc.c
4
src/pc.c
@@ -393,10 +393,14 @@ void resetpc_cad()
|
||||
pc_keyboard_send(211); /* Delete key released */
|
||||
}
|
||||
|
||||
int suppress_overscan = 0;
|
||||
|
||||
void resetpchard()
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
suppress_overscan = 0;
|
||||
|
||||
savenvr();
|
||||
saveconfig();
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#define GPCMD_MECHANISM_STATUS 0xbd
|
||||
#define GPCMD_READ_CD 0xbe
|
||||
#define GPCMD_SEND_DVD_STRUCTURE 0xbf /* This is for writing only, irrelevant to PCem. */
|
||||
#define GPCMD_PAUSE_RESUME_ALT 0xc2
|
||||
#define GPCMD_SCAN_ALT 0xcd /* Should be equivalent to 0xba */
|
||||
#define GPCMD_SET_SPEED_ALT 0xda /* Should be equivalent to 0xbb */
|
||||
|
||||
|
||||
@@ -2496,8 +2496,8 @@ void mach64_hwcursor_draw(svga_t *svga, int displine)
|
||||
uint8_t dat;
|
||||
uint32_t col0 = mach64->ramdac.pallook[0];
|
||||
uint32_t col1 = mach64->ramdac.pallook[1];
|
||||
int y_add = enable_overscan ? 16 : 0;
|
||||
int x_add = enable_overscan ? 8 : 0;
|
||||
int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0;
|
||||
int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0;
|
||||
|
||||
offset = svga->hwcursor_latch.xoff;
|
||||
for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4)
|
||||
|
||||
@@ -410,8 +410,8 @@ void clgd_hwcursor_draw(svga_t *svga, int displine)
|
||||
int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
|
||||
int largecur = (svga->seqregs[0x12] & 4);
|
||||
int cursize = (largecur) ? 64 : 32;
|
||||
int y_add = enable_overscan ? 16 : 0;
|
||||
int x_add = enable_overscan ? 8 : 0;
|
||||
int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0;
|
||||
int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0;
|
||||
|
||||
for (x = 0; x < cursize; x += 8)
|
||||
{
|
||||
|
||||
@@ -1043,20 +1043,22 @@ void et4000w32p_hwcursor_draw(svga_t *svga, int displine)
|
||||
int x, offset;
|
||||
uint8_t dat;
|
||||
offset = svga->hwcursor_latch.xoff;
|
||||
int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0;
|
||||
int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0;
|
||||
for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4)
|
||||
{
|
||||
dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)];
|
||||
if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] = (dat & 1) ? 0xFFFFFF : 0;
|
||||
else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] ^= 0xFFFFFF;
|
||||
if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 32] = (dat & 1) ? 0xFFFFFF : 0;
|
||||
else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 32] ^= 0xFFFFFF;
|
||||
dat >>= 2;
|
||||
if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] = (dat & 1) ? 0xFFFFFF : 0;
|
||||
else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] ^= 0xFFFFFF;
|
||||
if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 33 + x_add] = (dat & 1) ? 0xFFFFFF : 0;
|
||||
else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 33 + x_add] ^= 0xFFFFFF;
|
||||
dat >>= 2;
|
||||
if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] = (dat & 1) ? 0xFFFFFF : 0;
|
||||
else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] ^= 0xFFFFFF;
|
||||
if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 34] = (dat & 1) ? 0xFFFFFF : 0;
|
||||
else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 34] ^= 0xFFFFFF;
|
||||
dat >>= 2;
|
||||
if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] = (dat & 1) ? 0xFFFFFF : 0;
|
||||
else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] ^= 0xFFFFFF;
|
||||
if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 35] = (dat & 1) ? 0xFFFFFF : 0;
|
||||
else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 35] ^= 0xFFFFFF;
|
||||
dat >>= 2;
|
||||
offset += 4;
|
||||
}
|
||||
|
||||
@@ -2067,8 +2067,8 @@ void s3_hwcursor_draw(svga_t *svga, int displine)
|
||||
uint16_t dat[2];
|
||||
int xx;
|
||||
int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
|
||||
int y_add = enable_overscan ? 16 : 0;
|
||||
int x_add = enable_overscan ? 8 : 0;
|
||||
int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0;
|
||||
int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0;
|
||||
|
||||
if (svga->interlace && svga->hwcursor_oddeven)
|
||||
svga->hwcursor_latch.addr += 16;
|
||||
|
||||
@@ -3328,8 +3328,8 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine)
|
||||
uint16_t dat[2];
|
||||
int xx;
|
||||
int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff;
|
||||
int y_add = enable_overscan ? 16 : 0;
|
||||
int x_add = enable_overscan ? 8 : 0;
|
||||
int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0;
|
||||
int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0;
|
||||
|
||||
// pclog("HWcursor %i %i\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y);
|
||||
for (x = 0; x < 64; x += 16)
|
||||
|
||||
@@ -1497,6 +1497,17 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga)
|
||||
if (xsize<64) xsize=640;
|
||||
if (ysize<32) ysize=200;
|
||||
|
||||
if (xsize > 2032)
|
||||
{
|
||||
x_add = 0;
|
||||
y_add = 0;
|
||||
suppress_overscan = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
suppress_overscan = 1;
|
||||
}
|
||||
|
||||
updatewindowsize(xsize + x_add,ysize + y_add);
|
||||
}
|
||||
if (vid_resize)
|
||||
@@ -1505,7 +1516,7 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga)
|
||||
ysize = wy + 1;
|
||||
}
|
||||
|
||||
if (enable_overscan)
|
||||
if (enable_overscan && !suppress_overscan)
|
||||
{
|
||||
if ((wx >= 160) && ((wy + 1) >= 120))
|
||||
{
|
||||
|
||||
@@ -3412,7 +3412,20 @@ static void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params)
|
||||
{
|
||||
int y;
|
||||
|
||||
if (params->fbzMode & FBZ_RGB_WMASK)
|
||||
int low_y, high_y;
|
||||
|
||||
if (params->fbzMode & (1 << 17))
|
||||
{
|
||||
high_y = voodoo->v_disp - params->clipLowY;
|
||||
low_y = voodoo->v_disp - params->clipHighY;
|
||||
}
|
||||
else
|
||||
{
|
||||
low_y = params->clipLowY;
|
||||
high_y = params->clipHighY;
|
||||
}
|
||||
|
||||
if (params->fbzMode & FBZ_RGB_WMASK)
|
||||
{
|
||||
int r, g, b;
|
||||
uint16_t col;
|
||||
@@ -3422,7 +3435,7 @@ static void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params)
|
||||
b = (params->color1 >> 3) & 0x1f;
|
||||
col = b | (g << 5) | (r << 11);
|
||||
|
||||
for (y = params->clipLowY; y < params->clipHighY; y++)
|
||||
for (y = low_y; y < high_y; y++)
|
||||
{
|
||||
uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + y*voodoo->row_width) & voodoo->fb_mask];
|
||||
int x;
|
||||
@@ -3433,7 +3446,7 @@ static void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params)
|
||||
}
|
||||
if (params->fbzMode & FBZ_DEPTH_WMASK)
|
||||
{
|
||||
for (y = params->clipLowY; y < params->clipHighY; y++)
|
||||
for (y = low_y; y < high_y; y++)
|
||||
{
|
||||
uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + y*voodoo->row_width) & voodoo->fb_mask];
|
||||
int x;
|
||||
@@ -6556,8 +6569,8 @@ static void voodoo_filterline(voodoo_t *voodoo, uint16_t *fil, int column, uint1
|
||||
void voodoo_callback(void *p)
|
||||
{
|
||||
voodoo_t *voodoo = (voodoo_t *)p;
|
||||
int y_add = enable_overscan ? 16 : 0;
|
||||
int x_add = enable_overscan ? 8 : 0;
|
||||
int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0;
|
||||
int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0;
|
||||
|
||||
if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS)
|
||||
{
|
||||
|
||||
@@ -475,9 +475,9 @@ void initvideo()
|
||||
int c, d, e;
|
||||
|
||||
/* Account for overscan. */
|
||||
buffer32 = create_bitmap(2064, 2056);
|
||||
buffer32 = create_bitmap(2048, 2048);
|
||||
|
||||
buffer = create_bitmap(2064, 2056);
|
||||
buffer = create_bitmap(2048, 2048);
|
||||
|
||||
for (c = 0; c < 64; c++)
|
||||
{
|
||||
|
||||
@@ -70,12 +70,12 @@ static uint32_t pal_lookup[256];
|
||||
static CUSTOMVERTEX d3d_verts[] =
|
||||
{
|
||||
{ 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f},
|
||||
{2080.0f, 2080.0f, 1.0f, 1.0f, 1.0f, 1.0f},
|
||||
{ 0.0f, 2080.0f, 1.0f, 1.0f, 0.0f, 1.0f},
|
||||
{2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f},
|
||||
{ 0.0f, 2048.0f, 1.0f, 1.0f, 0.0f, 1.0f},
|
||||
|
||||
{ 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f},
|
||||
{2080.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f},
|
||||
{2080.0f, 2080.0f, 1.0f, 1.0f, 1.0f, 1.0f},
|
||||
{2048.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f},
|
||||
{2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f},
|
||||
};
|
||||
|
||||
void d3d_fs_init(HWND h)
|
||||
@@ -162,19 +162,19 @@ static void d3d_fs_init_objects()
|
||||
&v_buffer,
|
||||
NULL);
|
||||
|
||||
d3ddev->CreateTexture(2080, 2080, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL);
|
||||
d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL);
|
||||
|
||||
r.top = r.left = 0;
|
||||
r.bottom = 2079;
|
||||
r.right = 2079;
|
||||
r.bottom = 2047;
|
||||
r.right = 2047;
|
||||
|
||||
if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0)))
|
||||
fatal("LockRect failed\n");
|
||||
|
||||
for (y = 0; y < 2080; y++)
|
||||
for (y = 0; y < 2048; y++)
|
||||
{
|
||||
uint32_t *p = (uint32_t *)(dr.pBits + (y * dr.Pitch));
|
||||
memset(p, 0, 2080 * 4);
|
||||
memset(p, 0, 2048 * 4);
|
||||
}
|
||||
|
||||
d3dTexture->UnlockRect(0);
|
||||
@@ -346,8 +346,8 @@ static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
|
||||
|
||||
d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;
|
||||
d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;
|
||||
d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2080.0;
|
||||
d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2080.0;
|
||||
d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0;
|
||||
d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0;
|
||||
|
||||
GetClientRect(d3d_device_window, &window_rect);
|
||||
d3d_fs_size(window_rect, &l, &t, &r, &b, w, h);
|
||||
@@ -453,8 +453,8 @@ static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h)
|
||||
|
||||
d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;
|
||||
d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;
|
||||
d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2080.0;
|
||||
d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2080.0;
|
||||
d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0;
|
||||
d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0;
|
||||
|
||||
GetClientRect(d3d_device_window, &window_rect);
|
||||
d3d_fs_size(window_rect, &l, &t, &r, &b, w, h);
|
||||
|
||||
@@ -63,12 +63,12 @@ static uint32_t pal_lookup[256];
|
||||
static CUSTOMVERTEX d3d_verts[] =
|
||||
{
|
||||
{ 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f},
|
||||
{2080.0f, 2080.0f, 1.0f, 1.0f, 1.0f, 1.0f},
|
||||
{ 0.0f, 2080.0f, 1.0f, 1.0f, 0.0f, 1.0f},
|
||||
{2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f},
|
||||
{ 0.0f, 2048.0f, 1.0f, 1.0f, 0.0f, 1.0f},
|
||||
|
||||
{ 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f},
|
||||
{2080.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f},
|
||||
{2080.0f, 2080.0f, 1.0f, 1.0f, 1.0f, 1.0f},
|
||||
{2048.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f},
|
||||
{2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f},
|
||||
};
|
||||
|
||||
void d3d_init(HWND h)
|
||||
@@ -135,19 +135,18 @@ void d3d_init_objects()
|
||||
&v_buffer,
|
||||
NULL);
|
||||
|
||||
d3ddev->CreateTexture(2080, 2080, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL);
|
||||
d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL);
|
||||
|
||||
r.top = r.left = 0;
|
||||
r.bottom = 2079;
|
||||
r.right = 2079;
|
||||
r.bottom = r.right = 2047;
|
||||
|
||||
if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0)))
|
||||
fatal("LockRect failed\n");
|
||||
|
||||
for (y = 0; y < 2056; y++)
|
||||
for (y = 0; y < 2048; y++)
|
||||
{
|
||||
uint32_t *p = (uint32_t *)(dr.pBits + (y * dr.Pitch));
|
||||
memset(p, 0, 2064 * 4);
|
||||
memset(p, 0, 2048 * 4);
|
||||
}
|
||||
|
||||
d3dTexture->UnlockRect(0);
|
||||
@@ -242,7 +241,7 @@ void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
|
||||
{
|
||||
video_blit_complete();
|
||||
return; /*Nothing to do*/
|
||||
}
|
||||
}
|
||||
|
||||
r.top = y1;
|
||||
r.left = 0;
|
||||
@@ -263,10 +262,10 @@ void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
|
||||
else
|
||||
video_blit_complete();
|
||||
|
||||
d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0;
|
||||
d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0;
|
||||
d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0;
|
||||
d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2080.0;
|
||||
d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2080.0;
|
||||
d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0;
|
||||
d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0;
|
||||
|
||||
GetClientRect(d3d_hwnd, &r);
|
||||
d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5;
|
||||
@@ -321,7 +320,7 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h)
|
||||
int yy, xx;
|
||||
HRESULT hr = D3D_OK;
|
||||
|
||||
if (h == 0)
|
||||
if (h == 0)
|
||||
{
|
||||
video_blit_complete();
|
||||
return; /*Nothing to do*/
|
||||
@@ -330,7 +329,7 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h)
|
||||
r.top = 0;
|
||||
r.left = 0;
|
||||
r.bottom = h;
|
||||
r.right = 2079;
|
||||
r.right = 2047;
|
||||
|
||||
if (hr == D3D_OK)
|
||||
{
|
||||
@@ -353,6 +352,24 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h)
|
||||
else
|
||||
video_blit_complete();
|
||||
|
||||
d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0;
|
||||
d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0;
|
||||
d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0;
|
||||
d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0;
|
||||
|
||||
GetClientRect(d3d_hwnd, &r);
|
||||
d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5;
|
||||
d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = -0.5;
|
||||
d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = (r.right - r.left) - 0.5;
|
||||
d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = (r.bottom - r.top) - 0.5;
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer
|
||||
if (hr == D3D_OK)
|
||||
memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); // copy the vertices to the locked buffer
|
||||
if (hr == D3D_OK)
|
||||
hr = v_buffer->Unlock(); // unlock the vertex buffer
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->BeginScene();
|
||||
|
||||
@@ -376,28 +393,8 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h)
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->EndScene();
|
||||
}
|
||||
else
|
||||
video_blit_complete();
|
||||
|
||||
d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0;
|
||||
d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0;
|
||||
d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0;
|
||||
d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0;
|
||||
|
||||
GetClientRect(d3d_hwnd, &r);
|
||||
d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5;
|
||||
d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = -0.5;
|
||||
d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = (r.right - r.left) - 0.5;
|
||||
d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = (r.bottom - r.top) - 0.5;
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer
|
||||
if (hr == D3D_OK)
|
||||
memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); // copy the vertices to the locked buffer
|
||||
if (hr == D3D_OK)
|
||||
hr = v_buffer->Unlock(); // unlock the vertex buffer
|
||||
|
||||
if (hr == D3D_OK)
|
||||
hr = d3ddev->Present(NULL, NULL, d3d_hwnd, NULL);
|
||||
|
||||
if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL)
|
||||
|
||||
@@ -103,8 +103,8 @@ void ddraw_fs_init(HWND h)
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
|
||||
ddsd.dwWidth = 2080;
|
||||
ddsd.dwHeight = 2080;
|
||||
ddsd.dwWidth = 2048;
|
||||
ddsd.dwHeight = 2048;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
|
||||
if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL)))
|
||||
fatal("CreateSurface back failed\n");
|
||||
|
||||
@@ -91,8 +91,8 @@ void ddraw_init(HWND h)
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
|
||||
ddsd.dwWidth = 2080;
|
||||
ddsd.dwHeight = 2080;
|
||||
ddsd.dwWidth = 2048;
|
||||
ddsd.dwHeight = 2048;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
|
||||
if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL)))
|
||||
fatal("CreateSurface back failed\n");
|
||||
@@ -101,8 +101,8 @@ void ddraw_init(HWND h)
|
||||
ddsd.dwSize = sizeof(ddsd);
|
||||
|
||||
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
|
||||
ddsd.dwWidth = 2080;
|
||||
ddsd.dwHeight = 2080;
|
||||
ddsd.dwWidth = 2048;
|
||||
ddsd.dwHeight = 2048;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
|
||||
if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back2, NULL)))
|
||||
fatal("CreateSurface back failed\n");
|
||||
|
||||
16
src/win.c
16
src/win.c
@@ -121,17 +121,25 @@ void updatewindowsize(int x, int y)
|
||||
if (x < 160) x = 160;
|
||||
if (y < 100) y = 100;
|
||||
|
||||
int temp_overscan_x = overscan_x;
|
||||
int temp_overscan_y = overscan_y;
|
||||
|
||||
if (suppress_overscan)
|
||||
{
|
||||
temp_overscan_x = temp_overscan_y = 0;
|
||||
}
|
||||
|
||||
winsizex=x; efwinsizey=y;
|
||||
|
||||
if (force_43)
|
||||
{
|
||||
/* Account for possible overscan. */
|
||||
if (overscan_y == 16)
|
||||
if (temp_overscan_y == 16)
|
||||
{
|
||||
/* CGA */
|
||||
winsizey = ((int) (((double) (x - overscan_x) / 4.0) * 3.0)) + overscan_y;
|
||||
winsizey = ((int) (((double) (x - temp_overscan_x) / 4.0) * 3.0)) + temp_overscan_y;
|
||||
}
|
||||
else if (overscan_y < 16)
|
||||
else if (temp_overscan_y < 16)
|
||||
{
|
||||
/* MDA/Hercules */
|
||||
winsizey = efwinsizey;
|
||||
@@ -141,7 +149,7 @@ void updatewindowsize(int x, int y)
|
||||
if (enable_overscan)
|
||||
{
|
||||
/* EGA/(S)VGA with overscan */
|
||||
winsizey = ((int) (((double) (x - overscan_x) / 4.0) * 3.0)) + overscan_y;
|
||||
winsizey = ((int) (((double) (x - temp_overscan_x) / 4.0) * 3.0)) + temp_overscan_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user