Added some things that were missing from the DMA controller;
Fixed a link-breaking bug in cdrom.c; The AHA-154x now supports commands 0x28 (GET EXTENDED BIOS INFO) and 0x29 (UNLOCK MAILBOX) and no longer reports a firmware revision with scatter/gather bug; The BusLogic now supports command 0x20 (RESET); Fixed the GPIO register mapping on the National Semiconductors PC87306 Super I/O chip.
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1363,6 +1369,18 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
|
||||
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];
|
||||
@@ -1397,6 +1415,43 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
|
||||
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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
145
src/dma.c
145
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:
|
||||
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)
|
||||
@@ -103,13 +108,29 @@ void dma_write(uint16_t addr, uint8_t val, void *priv)
|
||||
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,6 +213,22 @@ 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*/
|
||||
@@ -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*/
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -308,6 +308,7 @@ typedef struct DMA
|
||||
uint8_t page[4];
|
||||
uint8_t stat;
|
||||
uint8_t command;
|
||||
uint8_t request;
|
||||
} DMA;
|
||||
|
||||
DMA dma,dma16;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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,10 +84,13 @@ 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);
|
||||
}
|
||||
}
|
||||
// pclog("PIIX write %02X %02X\n", addr, val);
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user