diff --git a/src/buslogic.c b/src/buslogic.c index 182765cd5..5c94fee82 100644 --- a/src/buslogic.c +++ b/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() diff --git a/src/cdrom.c b/src/cdrom.c index 03671d5a0..df218e204 100644 --- a/src/cdrom.c +++ b/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) { diff --git a/src/disc.c b/src/disc.c index ee4a4ccc3..8a273f463 100644 --- a/src/disc.c +++ b/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; } diff --git a/src/dma.c b/src/dma.c index d61e22cc3..723c2c7a4 100644 --- a/src/dma.c +++ b/src/dma.c @@ -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; } diff --git a/src/ibm.h b/src/ibm.h index ef2896d8f..abcf11f4d 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -607,3 +607,5 @@ extern int fdc_do_log; extern int ide_do_log; extern int ne2000_do_log; #endif + +extern int suppress_overscan; diff --git a/src/ide.c b/src/ide.c index a3b99b623..83ff385e4 100644 --- a/src/ide.c +++ b/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; diff --git a/src/pc.c b/src/pc.c index 764af631c..3067757bc 100644 --- a/src/pc.c +++ b/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(); diff --git a/src/scsi.h b/src/scsi.h index 1400823cc..3a441af95 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -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 */ diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index 1ed70ee5e..b74ad8d73 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -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) diff --git a/src/vid_cl_gd.c b/src/vid_cl_gd.c index b244f408a..b9b49c141 100644 --- a/src/vid_cl_gd.c +++ b/src/vid_cl_gd.c @@ -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) { diff --git a/src/vid_et4000w32.c b/src/vid_et4000w32.c index d5e879443..430bf7347 100644 --- a/src/vid_et4000w32.c +++ b/src/vid_et4000w32.c @@ -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; } diff --git a/src/vid_s3.c b/src/vid_s3.c index 896447174..4cb3134e6 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -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; diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index 5b0264633..24a315b15 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -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) diff --git a/src/vid_svga.c b/src/vid_svga.c index d0090aa75..0f3cc464c 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -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)) { diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 3306a3fc3..8d8afeb39 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -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) { diff --git a/src/video.c b/src/video.c index 9cd292101..9211ac742 100644 --- a/src/video.c +++ b/src/video.c @@ -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++) { diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc index 86d8b895f..4d129228d 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -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); diff --git a/src/win-d3d.cc b/src/win-d3d.cc index d73deb98e..a1e2fa8c5 100644 --- a/src/win-d3d.cc +++ b/src/win-d3d.cc @@ -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) diff --git a/src/win-ddraw-fs.cc b/src/win-ddraw-fs.cc index b1800d931..bfb9a5a1c 100644 --- a/src/win-ddraw-fs.cc +++ b/src/win-ddraw-fs.cc @@ -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"); diff --git a/src/win-ddraw.cc b/src/win-ddraw.cc index 251029db7..f786310ca 100644 --- a/src/win-ddraw.cc +++ b/src/win-ddraw.cc @@ -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"); diff --git a/src/win.c b/src/win.c index d9c98fe24..33840cd63 100644 --- a/src/win.c +++ b/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 {