diff --git a/src/Makefile.mingw b/src/Makefile.mingw index e3e69794a..4854b83e5 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,7 +2,7 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -g DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ @@ -33,8 +33,8 @@ 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 10 - strip "86Box.exe" - sleep 10 +a.exe: strip "86Box.exe" +a.exe: sleep 10 all : 86Box.exe diff --git a/src/buslogic.c b/src/buslogic.c index 5c94fee82..d131846a3 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -516,6 +516,7 @@ typedef struct __attribute__((packed)) Buslogic_t int MailboxOutInterrupts; int MbiActive[256]; int PendingInterrupt; + int Lock; } Buslogic_t; int scsi_model = 1; @@ -600,6 +601,7 @@ static void BuslogicReset(Buslogic_t *Buslogic) Buslogic->MailboxInPosCur = 0; Buslogic->MailboxOutInterrupts = 0; Buslogic->PendingInterrupt = 0; + Buslogic->Lock = 0; BuslogicInOperation = 0; BuslogicClearInterrupt(Buslogic); @@ -1136,6 +1138,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) case 0x04: case 0x0A: case 0x0B: + case 0x20: case 0x23: case 0x84: case 0x85: @@ -1183,8 +1186,11 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Buslogic->CmdParamLeft = scsi_model ? sizeof(MailboxInitExtended_t) : 0; break; - case 0x28: case 0x29: + Buslogic->CmdParamLeft = scsi_model ? 0 : 2; + break; + + case 0x28: case 0x86: //Valid only for PCI case 0x95: //Valid only for PCI Buslogic->CmdParamLeft = 0; @@ -1230,8 +1236,8 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) case 0x04: Buslogic->DataBuf[0] = 0x41; Buslogic->DataBuf[1] = scsi_model ? 0x41 : 0x30; - Buslogic->DataBuf[2] = scsi_model ? '5' : '3'; - Buslogic->DataBuf[3] = scsi_model ? '0' : '1'; + Buslogic->DataBuf[2] = '5'; + Buslogic->DataBuf[3] = '0'; Buslogic->DataReplyLeft = 4; break; @@ -1362,7 +1368,19 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Buslogic->DataBuf[0] = Buslogic->CmdBuf[0]; Buslogic->DataReplyLeft = 1; break; - + + case 0x20: + Buslogic->DataReplyLeft = 0; + if (scsi_model) + { + BuslogicResetControl(Buslogic, 1); + } + else + { + Buslogic->Status |= STAT_INVCMD; + } + break; + case 0x21: if (Buslogic->CmdParam == 1) Buslogic->CmdParamLeft = Buslogic->CmdBuf[0]; @@ -1396,7 +1414,44 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) BuslogicLog("Lowering IRQ %i\n", Buslogic->Irq); picintc(1 << Buslogic->Irq); break; - + + case 0x28: + if (!scsi_model) + { + Buslogic->DataBuf[0] = 0x08; + Buslogic->DataBuf[1] = Buslogic->Lock; + Buslogic->DataReplyLeft = 2; + } + else + { + Buslogic->DataReplyLeft = 0; + Buslogic->Status |= STAT_INVCMD; + } + break; + + case 0x29: + if (!scsi_model) + { + if (Buslogic->CmdBuf[1] = Buslogic->Lock) + { + if (Buslogic->CmdBuf[0] & 1) + { + Buslogic->Lock = 1; + } + else + { + Buslogic->Lock = 0; + } + } + Buslogic->DataReplyLeft = 0; + } + else + { + Buslogic->DataReplyLeft = 0; + Buslogic->Status |= STAT_INVCMD; + } + break; + case 0x81: { if (scsi_model) @@ -1546,8 +1601,8 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) default: case 0x22: //undocumented - case 0x28: //only for the Adaptec 154xC series - case 0x29: //only for the Adaptec 154xC series + // case 0x28: //only for the Adaptec 154xC series + // case 0x29: //only for the Adaptec 154xC series case 0x86: //PCI only, not ISA case 0x95: //PCI only, not ISA Buslogic->DataReplyLeft = 0; diff --git a/src/cdrom.c b/src/cdrom.c index 66de19852..b86ffd284 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -2322,7 +2322,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) if (cdb[3] == 1) { cdbufferb[1] = cdrom_drives[id].handler->getcurrentsubchannel(id, &cdbufferb[5], msf); - if (((cdbufferb[1] == 0x13) && !completed) || (cd_status == CD_STATUS_DATA_ONLY)) + if (((cdbufferb[1] == 0x13) && !completed) || (cdrom[id].cd_status == CD_STATUS_DATA_ONLY)) { cdbufferb[1] = 0x15; } diff --git a/src/dma.c b/src/dma.c index 723c2c7a4..59ae03401 100644 --- a/src/dma.c +++ b/src/dma.c @@ -66,18 +66,23 @@ uint8_t dma_read(uint16_t addr, void *priv) case 8: /*Status register*/ temp = dma.stat; - dma.stat = 0; + dma.stat &= 0xf0; return temp; - - case 0xd: - return 0; + + case 0xd: /*Temporary register*/ + return dmaregs[addr & 0xd]; + + case 0xf: /*Mask register*/ + return dma16.m; + + default: + return 0; } -// printf("Bad DMA read %04X %04X:%04X\n",addr,CS,pc); - return dmaregs[addr & 0xf]; } void dma_write(uint16_t addr, uint8_t val, void *priv) { + int channel = val & 3; // printf("Write DMA %04X %02X %04X:%04X\n",addr,val,CS,pc); dmaregs[addr & 0xf] = val; switch (addr & 0xf) @@ -102,14 +107,30 @@ void dma_write(uint16_t addr, uint8_t val, void *priv) case 8: /*Control register*/ dma.command = val; return; + + case 9: /*Request register*/ + if (val & 4) + { + dma.request |= (1 << (channel + 4)); + if (dma.command & 1) + { + dma.request |= (1 << channel); + } + } + else + { + dma.request &= ~(1 << (channel + 4)); + } + return; case 0xa: /*Mask*/ if (val & 4) dma.m |= (1 << (val & 3)); else dma.m &= ~(1 << (val & 3)); return; - + case 0xb: /*Mode*/ - dma.mode[val & 3] = val; + dma.mode[val & 3] = val & 0xfc; + dma.stat &= ~(1 << (val & 3)); return; case 0xc: /*Clear FF*/ @@ -135,7 +156,7 @@ void dma_write(uint16_t addr, uint8_t val, void *priv) uint8_t dma16_read(uint16_t addr, void *priv) { uint8_t temp; -// printf("Read DMA %04X %04X:%04X\n",addr,cs>>4,pc); + // printf("Read DMA %04X %04X:%04X\n",addr,cs>>4,cpu_state.pc); addr >>= 1; switch (addr & 0xf) { @@ -153,15 +174,24 @@ uint8_t dma16_read(uint16_t addr, void *priv) case 8: /*Status register*/ temp = dma16.stat; - dma16.stat = 0; + dma16.stat &= 0xf0; return temp; + + case 0xd: /*Temporary register*/ + return dma16regs[addr & 0xd]; + + case 0xf: /*Mask register*/ + return dma16.m; + + default: + return 0; } - return dma16regs[addr & 0xf]; } void dma16_write(uint16_t addr, uint8_t val, void *priv) { -// printf("Write dma16 %04X %02X %04X:%04X\n",addr,val,CS,pc); + int channel = val & 3; + // printf("Write dma16 %04X %02X %04X:%04X\n",addr,val,CS,cpu_state.pc); addr >>= 1; dma16regs[addr & 0xf] = val; switch (addr & 0xf) @@ -183,7 +213,23 @@ void dma16_write(uint16_t addr, uint8_t val, void *priv) return; case 8: /*Control register*/ + dma16.command = val; return; + + case 9: /*Request register*/ + if (val & 4) + { + dma16.request |= (1 << (channel + 4)); + if (dma16.command & 1) + { + dma16.request |= (1 << channel); + } + } + else + { + dma16.request &= ~(1 << (channel + 4)); + } + return; case 0xa: /*Mask*/ if (val & 4) dma16.m |= (1 << (val & 3)); @@ -191,7 +237,8 @@ void dma16_write(uint16_t addr, uint8_t val, void *priv) return; case 0xb: /*Mode*/ - dma16.mode[val & 3] = val; + dma16.mode[val & 3] = val & 0xfc; + dma16.stat &= ~(1 << (val & 3)); return; case 0xc: /*Clear FF*/ @@ -209,7 +256,7 @@ void dma16_write(uint16_t addr, uint8_t val, void *priv) return; case 0xf: /*Mask write*/ - dma16.m = val&0xf; + dma16.m = val & 0xf; return; } } @@ -217,6 +264,7 @@ void dma16_write(uint16_t addr, uint8_t val, void *priv) void dma_page_write(uint16_t addr, uint8_t val, void *priv) { + // printf("Write dma16 Page %04X %02X %04X:%04X\n",addr,val,CS,cpu_state.pc); dmapages[addr & 0xf] = val; switch (addr & 0xf) { @@ -249,6 +297,7 @@ void dma_page_write(uint16_t addr, uint8_t val, void *priv) uint8_t dma_page_read(uint16_t addr, void *priv) { + // printf("Read DMA Page %04X %04X:%04X\n",addr,cs>>4,cpu_state.pc); return dmapages[addr & 0xf]; } @@ -357,6 +406,35 @@ DMA * get_dma_controller(int channel) } } +int dma_tc(DMA *dma_controller, int channel) +{ + if (dma_controller->command & 1) + { + /* Memory to memory command */ + dma_controller->stat |= (1 << 0); + dma_controller->stat |= (1 << 1); + dma_controller->request &= ~(1 << 0); + dma_controller->request &= ~(1 << 1); + } + else + { + dma_controller->stat |= (1 << channel); + dma_controller->request &= ~(1 << channel); + } + + if (dma_controller->mode[channel] & 0x10) /*Auto-init*/ + { + // pclog("DMA read auto-init\n"); + dma_controller->cc[channel] = dma_controller->cb[channel] & 0xffff; + dma_controller->ac[channel] = dma_controller->ab[channel] & 0xffff; + } + else + { + dma_controller->cc[channel] &= 0xffff; + dma_controller->m |= (1 << channel); + } +} + int dma_channel_read(int channel) { uint16_t temp; @@ -438,18 +516,7 @@ int dma_channel_read(int channel) if ((dma_controller->cc[real_channel] < 0) || mem_over) { tc = 1; - if (dma_controller->mode[real_channel] & 0x10) /*Auto-init*/ - { - // pclog("DMA read auto-init\n"); - dma_controller->cc[real_channel] = dma_controller->cb[real_channel] & 0xffff; - dma_controller->ac[real_channel] = dma_controller->ab[real_channel] & 0xffff; - } - else - { - dma_controller->cc[real_channel] &= 0xffff; - dma_controller->m |= (1 << real_channel); - } - dma_controller->stat |= (1 << real_channel); + dma_tc(dma_controller, real_channel); } if (tc) @@ -540,18 +607,7 @@ int dma_channel_write(int channel, uint16_t val) if ((dma_controller->cc[real_channel] < 0) || mem_over) { tc = 1; - if (dma_controller->mode[real_channel] & 0x10) /*Auto-init*/ - { - // pclog("DMA write auto-init\n"); - dma_controller->cc[real_channel] = dma_controller->cb[real_channel] & 0xffff; - dma_controller->ac[real_channel] = dma_controller->ab[real_channel] & 0xffff; - } - else - { - dma_controller->cc[real_channel] &= 0xffff; - dma_controller->m |= (1 << real_channel); - } - dma_controller->stat |= (1 << real_channel); + dma_tc(dma_controller, real_channel); } // if (dma_is_masked(channel)) @@ -565,38 +621,17 @@ int dma_channel_write(int channel, uint16_t val) return 0; } -#if 0 -static uint32_t PageLengthReadWrite(uint32_t PhysAddress, uint32_t TotalSize) -{ - uint32_t LengthSize; - uint32_t Page; - - Page = PhysAddress & 4095; - - if ((Page + TotalSize - 1) >= 4096) - { - TotalSize = 4096 - Page; - } - - return TotalSize; -} -#endif - //DMA Bus Master Page Read/Write void DMAPageRead(uint32_t PhysAddress, void *DataRead, uint32_t TotalSize) { - // uint32_t PageLen = PageLengthReadWrite(PhysAddress, TotalSize); memcpy(DataRead, &ram[PhysAddress], TotalSize); - // DataRead -= PageLen; DataRead -= TotalSize; } void DMAPageWrite(uint32_t PhysAddress, const void *DataWrite, uint32_t TotalSize) { - // uint32_t PageLen = PageLengthReadWrite(PhysAddress, 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 abcf11f4d..3f0ed78ee 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -308,6 +308,7 @@ typedef struct DMA uint8_t page[4]; uint8_t stat; uint8_t command; + uint8_t request; } DMA; DMA dma,dma16; diff --git a/src/pc87306.c b/src/pc87306.c index 9290c6209..d10fb4844 100644 --- a/src/pc87306.c +++ b/src/pc87306.c @@ -170,14 +170,21 @@ void pc87306_write(uint16_t port, uint8_t val, void *priv) if (tries) { if (pc87306_curreg <= 28) valxor = val ^ pc87306_regs[pc87306_curreg]; - if (pc87306_curreg == 0xF) pc87306_gpio_remove(); - if ((pc87306_curreg <= 28) && (pc87306_curreg != 8)) + tries = 0; + if ((pc87306_curreg <= 28) && (pc87306_curreg != 8) && (pc87306_curreg != 0x18)) { + if (pc87306_curreg == 0) + { + val &= 0x5f; + } + if ((pc87306_curreg == 0x0F) || (pc87306_curreg == 0x12)) + { + pc87306_gpio_remove(); + } pc87306_regs[pc87306_curreg] = val; // pclog("Register %02X set to: %02X (was: %02X)\n", pc87306_curreg, val, pc87306_regs[pc87306_curreg]); + goto process_value; } - tries = 0; - if ((pc87306_curreg <= 28) && (pc87306_curreg != 8)) goto process_value; } else { @@ -270,6 +277,7 @@ process_value: fdc_update_densel_polarity((val & 0x40) ? 1 : 0); break; case 0xF: + case 0x12: pc87306_gpio_init(); break; case 0x1C: @@ -342,7 +350,15 @@ void pc87306_gpio_remove() void pc87306_gpio_init() { - io_sethandler(pc87306_regs[0xF] << 2, 0x0002, pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, NULL); + if ((pc87306_regs[0x12]) & 0x10) + { + io_sethandler(pc87306_regs[0xF] << 2, 0x0001, pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, NULL); + } + + if ((pc87306_regs[0x12]) & 0x20) + { + io_sethandler((pc87306_regs[0xF] << 2) + 1, 0x0001, pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, NULL); + } } void pc87306_init() diff --git a/src/piix.c b/src/piix.c index ce3e33b0d..e4297d276 100644 --- a/src/piix.c +++ b/src/piix.c @@ -26,6 +26,7 @@ static uint8_t card_piix[256], card_piix_ide[256]; void piix_write(int func, int addr, uint8_t val, void *priv) { + uint16_t old_base = (card_piix_ide[0x20] & 0xf0) | (card_piix_ide[0x21] << 8); // pclog("piix_write: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, pc); if (func > 1) return; @@ -83,9 +84,12 @@ void piix_write(int func, int addr, uint8_t val, void *priv) if (addr == 4 || (addr & ~3) == 0x20) /*Bus master base address*/ { uint16_t base = (card_piix_ide[0x20] & 0xf0) | (card_piix_ide[0x21] << 8); - io_removehandler(0, 0x10000, piix_bus_master_read, NULL, NULL, piix_bus_master_write, NULL, NULL, NULL); + io_removehandler(old_base, 0x10, piix_bus_master_read, NULL, NULL, piix_bus_master_write, NULL, NULL, NULL); + pclog("Setting PIIX IDE bus master to new base address: %04X\n", base); if (card_piix_ide[0x04] & 1) - io_sethandler(base, 0x10, piix_bus_master_read, NULL, NULL, piix_bus_master_write, NULL, NULL, NULL); + { + io_sethandler(base, 0x10, piix_bus_master_read, NULL, NULL, piix_bus_master_write, NULL, NULL, NULL); + } } // pclog("PIIX write %02X %02X\n", addr, val); }