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:
OBattler
2017-01-26 17:20:55 +01:00
parent 89840c7fc9
commit d4afd7c2c3
7 changed files with 188 additions and 77 deletions

View File

@@ -2,7 +2,7 @@ VPATH = . dosbox lzf resid-fp slirp
CPP = g++.exe CPP = g++.exe
CC = gcc.exe CC = gcc.exe
WINDRES = windres.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 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 \ 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 \ 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) 86Box.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ)
$(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS) $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS)
sleep 10 sleep 10
strip "86Box.exe" a.exe: strip "86Box.exe"
sleep 10 a.exe: sleep 10
all : 86Box.exe all : 86Box.exe

View File

@@ -516,6 +516,7 @@ typedef struct __attribute__((packed)) Buslogic_t
int MailboxOutInterrupts; int MailboxOutInterrupts;
int MbiActive[256]; int MbiActive[256];
int PendingInterrupt; int PendingInterrupt;
int Lock;
} Buslogic_t; } Buslogic_t;
int scsi_model = 1; int scsi_model = 1;
@@ -600,6 +601,7 @@ static void BuslogicReset(Buslogic_t *Buslogic)
Buslogic->MailboxInPosCur = 0; Buslogic->MailboxInPosCur = 0;
Buslogic->MailboxOutInterrupts = 0; Buslogic->MailboxOutInterrupts = 0;
Buslogic->PendingInterrupt = 0; Buslogic->PendingInterrupt = 0;
Buslogic->Lock = 0;
BuslogicInOperation = 0; BuslogicInOperation = 0;
BuslogicClearInterrupt(Buslogic); BuslogicClearInterrupt(Buslogic);
@@ -1136,6 +1138,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
case 0x04: case 0x04:
case 0x0A: case 0x0A:
case 0x0B: case 0x0B:
case 0x20:
case 0x23: case 0x23:
case 0x84: case 0x84:
case 0x85: case 0x85:
@@ -1183,8 +1186,11 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
Buslogic->CmdParamLeft = scsi_model ? sizeof(MailboxInitExtended_t) : 0; Buslogic->CmdParamLeft = scsi_model ? sizeof(MailboxInitExtended_t) : 0;
break; break;
case 0x28:
case 0x29: case 0x29:
Buslogic->CmdParamLeft = scsi_model ? 0 : 2;
break;
case 0x28:
case 0x86: //Valid only for PCI case 0x86: //Valid only for PCI
case 0x95: //Valid only for PCI case 0x95: //Valid only for PCI
Buslogic->CmdParamLeft = 0; Buslogic->CmdParamLeft = 0;
@@ -1230,8 +1236,8 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
case 0x04: case 0x04:
Buslogic->DataBuf[0] = 0x41; Buslogic->DataBuf[0] = 0x41;
Buslogic->DataBuf[1] = scsi_model ? 0x41 : 0x30; Buslogic->DataBuf[1] = scsi_model ? 0x41 : 0x30;
Buslogic->DataBuf[2] = scsi_model ? '5' : '3'; Buslogic->DataBuf[2] = '5';
Buslogic->DataBuf[3] = scsi_model ? '0' : '1'; Buslogic->DataBuf[3] = '0';
Buslogic->DataReplyLeft = 4; Buslogic->DataReplyLeft = 4;
break; break;
@@ -1362,7 +1368,19 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
Buslogic->DataBuf[0] = Buslogic->CmdBuf[0]; Buslogic->DataBuf[0] = Buslogic->CmdBuf[0];
Buslogic->DataReplyLeft = 1; Buslogic->DataReplyLeft = 1;
break; break;
case 0x20:
Buslogic->DataReplyLeft = 0;
if (scsi_model)
{
BuslogicResetControl(Buslogic, 1);
}
else
{
Buslogic->Status |= STAT_INVCMD;
}
break;
case 0x21: case 0x21:
if (Buslogic->CmdParam == 1) if (Buslogic->CmdParam == 1)
Buslogic->CmdParamLeft = Buslogic->CmdBuf[0]; 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); BuslogicLog("Lowering IRQ %i\n", Buslogic->Irq);
picintc(1 << Buslogic->Irq); picintc(1 << Buslogic->Irq);
break; 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: case 0x81:
{ {
if (scsi_model) if (scsi_model)
@@ -1546,8 +1601,8 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
default: default:
case 0x22: //undocumented case 0x22: //undocumented
case 0x28: //only for the Adaptec 154xC series // case 0x28: //only for the Adaptec 154xC series
case 0x29: //only for the Adaptec 154xC series // case 0x29: //only for the Adaptec 154xC series
case 0x86: //PCI only, not ISA case 0x86: //PCI only, not ISA
case 0x95: //PCI only, not ISA case 0x95: //PCI only, not ISA
Buslogic->DataReplyLeft = 0; Buslogic->DataReplyLeft = 0;

View File

@@ -2322,7 +2322,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb)
if (cdb[3] == 1) if (cdb[3] == 1)
{ {
cdbufferb[1] = cdrom_drives[id].handler->getcurrentsubchannel(id, &cdbufferb[5], msf); 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; cdbufferb[1] = 0x15;
} }

153
src/dma.c
View File

@@ -66,18 +66,23 @@ uint8_t dma_read(uint16_t addr, void *priv)
case 8: /*Status register*/ case 8: /*Status register*/
temp = dma.stat; temp = dma.stat;
dma.stat = 0; dma.stat &= 0xf0;
return temp; return temp;
case 0xd: case 0xd: /*Temporary register*/
return 0; 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) 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); // printf("Write DMA %04X %02X %04X:%04X\n",addr,val,CS,pc);
dmaregs[addr & 0xf] = val; dmaregs[addr & 0xf] = val;
switch (addr & 0xf) switch (addr & 0xf)
@@ -102,14 +107,30 @@ void dma_write(uint16_t addr, uint8_t val, void *priv)
case 8: /*Control register*/ case 8: /*Control register*/
dma.command = val; dma.command = val;
return; 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*/ case 0xa: /*Mask*/
if (val & 4) dma.m |= (1 << (val & 3)); if (val & 4) dma.m |= (1 << (val & 3));
else dma.m &= ~(1 << (val & 3)); else dma.m &= ~(1 << (val & 3));
return; return;
case 0xb: /*Mode*/ case 0xb: /*Mode*/
dma.mode[val & 3] = val; dma.mode[val & 3] = val & 0xfc;
dma.stat &= ~(1 << (val & 3));
return; return;
case 0xc: /*Clear FF*/ 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 dma16_read(uint16_t addr, void *priv)
{ {
uint8_t temp; 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; addr >>= 1;
switch (addr & 0xf) switch (addr & 0xf)
{ {
@@ -153,15 +174,24 @@ uint8_t dma16_read(uint16_t addr, void *priv)
case 8: /*Status register*/ case 8: /*Status register*/
temp = dma16.stat; temp = dma16.stat;
dma16.stat = 0; dma16.stat &= 0xf0;
return temp; 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) 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; addr >>= 1;
dma16regs[addr & 0xf] = val; dma16regs[addr & 0xf] = val;
switch (addr & 0xf) switch (addr & 0xf)
@@ -183,7 +213,23 @@ void dma16_write(uint16_t addr, uint8_t val, void *priv)
return; return;
case 8: /*Control register*/ case 8: /*Control register*/
dma16.command = val;
return; 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*/ case 0xa: /*Mask*/
if (val & 4) dma16.m |= (1 << (val & 3)); if (val & 4) dma16.m |= (1 << (val & 3));
@@ -191,7 +237,8 @@ void dma16_write(uint16_t addr, uint8_t val, void *priv)
return; return;
case 0xb: /*Mode*/ case 0xb: /*Mode*/
dma16.mode[val & 3] = val; dma16.mode[val & 3] = val & 0xfc;
dma16.stat &= ~(1 << (val & 3));
return; return;
case 0xc: /*Clear FF*/ case 0xc: /*Clear FF*/
@@ -209,7 +256,7 @@ void dma16_write(uint16_t addr, uint8_t val, void *priv)
return; return;
case 0xf: /*Mask write*/ case 0xf: /*Mask write*/
dma16.m = val&0xf; dma16.m = val & 0xf;
return; 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) 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; dmapages[addr & 0xf] = val;
switch (addr & 0xf) 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) 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]; 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) int dma_channel_read(int channel)
{ {
uint16_t temp; uint16_t temp;
@@ -438,18 +516,7 @@ int dma_channel_read(int channel)
if ((dma_controller->cc[real_channel] < 0) || mem_over) if ((dma_controller->cc[real_channel] < 0) || mem_over)
{ {
tc = 1; tc = 1;
if (dma_controller->mode[real_channel] & 0x10) /*Auto-init*/ dma_tc(dma_controller, real_channel);
{
// 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);
} }
if (tc) if (tc)
@@ -540,18 +607,7 @@ int dma_channel_write(int channel, uint16_t val)
if ((dma_controller->cc[real_channel] < 0) || mem_over) if ((dma_controller->cc[real_channel] < 0) || mem_over)
{ {
tc = 1; tc = 1;
if (dma_controller->mode[real_channel] & 0x10) /*Auto-init*/ dma_tc(dma_controller, real_channel);
{
// 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);
} }
// if (dma_is_masked(channel)) // if (dma_is_masked(channel))
@@ -565,38 +621,17 @@ int dma_channel_write(int channel, uint16_t val)
return 0; 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 //DMA Bus Master Page Read/Write
void DMAPageRead(uint32_t PhysAddress, void *DataRead, uint32_t TotalSize) void DMAPageRead(uint32_t PhysAddress, void *DataRead, uint32_t TotalSize)
{ {
// uint32_t PageLen = PageLengthReadWrite(PhysAddress, TotalSize);
memcpy(DataRead, &ram[PhysAddress], TotalSize); memcpy(DataRead, &ram[PhysAddress], TotalSize);
// DataRead -= PageLen;
DataRead -= TotalSize; DataRead -= TotalSize;
} }
void DMAPageWrite(uint32_t PhysAddress, const void *DataWrite, uint32_t 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); mem_invalidate_range(PhysAddress, PhysAddress + TotalSize - 1);
memcpy(&ram[PhysAddress], DataWrite, TotalSize); memcpy(&ram[PhysAddress], DataWrite, TotalSize);
// DataWrite -= PageLen;
DataWrite -= TotalSize; DataWrite -= TotalSize;
} }

View File

@@ -308,6 +308,7 @@ typedef struct DMA
uint8_t page[4]; uint8_t page[4];
uint8_t stat; uint8_t stat;
uint8_t command; uint8_t command;
uint8_t request;
} DMA; } DMA;
DMA dma,dma16; DMA dma,dma16;

View File

@@ -170,14 +170,21 @@ void pc87306_write(uint16_t port, uint8_t val, void *priv)
if (tries) if (tries)
{ {
if (pc87306_curreg <= 28) valxor = val ^ pc87306_regs[pc87306_curreg]; if (pc87306_curreg <= 28) valxor = val ^ pc87306_regs[pc87306_curreg];
if (pc87306_curreg == 0xF) pc87306_gpio_remove(); tries = 0;
if ((pc87306_curreg <= 28) && (pc87306_curreg != 8)) 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; pc87306_regs[pc87306_curreg] = val;
// pclog("Register %02X set to: %02X (was: %02X)\n", pc87306_curreg, val, pc87306_regs[pc87306_curreg]); // 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 else
{ {
@@ -270,6 +277,7 @@ process_value:
fdc_update_densel_polarity((val & 0x40) ? 1 : 0); fdc_update_densel_polarity((val & 0x40) ? 1 : 0);
break; break;
case 0xF: case 0xF:
case 0x12:
pc87306_gpio_init(); pc87306_gpio_init();
break; break;
case 0x1C: case 0x1C:
@@ -342,7 +350,15 @@ void pc87306_gpio_remove()
void pc87306_gpio_init() 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() void pc87306_init()

View File

@@ -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) 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); // pclog("piix_write: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, pc);
if (func > 1) if (func > 1)
return; 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*/ if (addr == 4 || (addr & ~3) == 0x20) /*Bus master base address*/
{ {
uint16_t base = (card_piix_ide[0x20] & 0xf0) | (card_piix_ide[0x21] << 8); 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) 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); // pclog("PIIX write %02X %02X\n", addr, val);
} }