The WIN_DRIVE_DIAGNOSTICS command now behaves correctly (but I'm redoing the IDE emulation anyway);
The IBM PS/2 Model 486 now uses its own rom set ID; The AHA-154x and Buslogic SCSI controllers no longer stop scanning for mailboxes when in aggressive round robin mode; PIC interrupt processing fixes - no more IRQ-caused triple faults in Windows 98 SE.
This commit is contained in:
@@ -1118,9 +1118,10 @@ void writeide(int ide_board, uint16_t addr, uint8_t val)
|
||||
else
|
||||
{
|
||||
ide->atastat = BUSY_STAT;
|
||||
ide_other->atastat = BUSY_STAT;
|
||||
}
|
||||
timer_process();
|
||||
callbackide(ide_board);
|
||||
/* callbackide(ide_board); */
|
||||
if (ide_drive_is_cdrom(ide))
|
||||
{
|
||||
cdrom[atapi_cdrom_drives[ide->channel]].callback = 200 * IDE_TIME;
|
||||
@@ -1502,6 +1503,7 @@ void callbackide(int ide_board)
|
||||
IDE *ide, *ide_other;
|
||||
int64_t snum;
|
||||
int cdrom_id;
|
||||
int cdrom_id_other;
|
||||
uint64_t full_size = 0;
|
||||
|
||||
ide = &ide_drives[cur_ide[ide_board]];
|
||||
@@ -1549,15 +1551,15 @@ void callbackide(int ide_board)
|
||||
}
|
||||
if (ide_drive_is_cdrom(ide_other))
|
||||
{
|
||||
cdrom_id = atapi_cdrom_drives[cur_ide[ide_board] ^ 1];
|
||||
cdrom[cdrom_id].status = READY_STAT | DSC_STAT;
|
||||
cdrom[cdrom_id].error = 1;
|
||||
cdrom[cdrom_id].phase = 1;
|
||||
cdrom[cdrom_id].request_length=0xEB14;
|
||||
cdrom_id_other = atapi_cdrom_drives[cur_ide[ide_board] ^ 1];
|
||||
cdrom[cdrom_id_other].status = READY_STAT | DSC_STAT;
|
||||
cdrom[cdrom_id_other].error = 1;
|
||||
cdrom[cdrom_id_other].phase = 1;
|
||||
cdrom[cdrom_id_other].request_length=0xEB14;
|
||||
ide_other->cylinder = 0xEB14;
|
||||
if (cdrom_drives[cdrom_id].handler->stop)
|
||||
if (cdrom_drives[cdrom_id_other].handler->stop)
|
||||
{
|
||||
cdrom_drives[cdrom_id].handler->stop(cdrom_id);
|
||||
cdrom_drives[cdrom_id_other].handler->stop(cdrom_id_other);
|
||||
}
|
||||
}
|
||||
if (ide_other->type == IDE_NONE)
|
||||
@@ -1568,6 +1570,7 @@ void callbackide(int ide_board)
|
||||
}
|
||||
|
||||
cdrom_id = atapi_cdrom_drives[cur_ide[ide_board]];
|
||||
cdrom_id_other = atapi_cdrom_drives[cur_ide[ide_board] ^ 1];
|
||||
|
||||
switch (ide->command)
|
||||
{
|
||||
@@ -1918,6 +1921,24 @@ void callbackide(int ide_board)
|
||||
ide->error = 1;
|
||||
ide_irq_raise(ide);
|
||||
}
|
||||
|
||||
ide_set_signature(ide_other);
|
||||
ide_other->error=1; /*No error detected*/
|
||||
|
||||
if (ide_drive_is_cdrom(ide_other))
|
||||
{
|
||||
cdrom[cdrom_id_other].status = 0;
|
||||
cdrom[cdrom_id_other].error = 1;
|
||||
// ide_irq_raise(ide_other);
|
||||
}
|
||||
else
|
||||
{
|
||||
ide_other->atastat = READY_STAT | DSC_STAT;
|
||||
ide_other->error = 1;
|
||||
// ide_irq_raise(ide_other);
|
||||
}
|
||||
|
||||
cur_ide[ide_board] &= ~1;
|
||||
return;
|
||||
|
||||
case WIN_SPECIFY: /* Initialize Drive Parameters */
|
||||
|
@@ -363,7 +363,7 @@ extern PPI ppi;
|
||||
/*PIC*/
|
||||
typedef struct PIC
|
||||
{
|
||||
uint8_t icw1,icw4,mask,ins,pend,mask2;
|
||||
uint8_t icw1,icw3,icw4,mask,ins,pend,mask2;
|
||||
int icw;
|
||||
uint8_t vector;
|
||||
int read;
|
||||
@@ -484,6 +484,7 @@ enum
|
||||
ROM_IBMPS1_2133,
|
||||
|
||||
ROM_PRESIDENT, /*President Award 430FX PCI / 430FX / Award BIOS / Unknown Super I/O chip*/
|
||||
ROM_IBMPS2_M80_486,
|
||||
|
||||
ROM_MAX
|
||||
};
|
||||
|
@@ -823,10 +823,7 @@ uint8_t keyboard_at_read(uint16_t port, void *priv)
|
||||
case 0x60:
|
||||
temp = keyboard_at.out;
|
||||
keyboard_at.status &= ~(STAT_OFULL/* | STAT_MFULL*/);
|
||||
if (keyboard_at.last_irq != 0x1000)
|
||||
{
|
||||
picintc(keyboard_at.last_irq);
|
||||
}
|
||||
picintc(keyboard_at.last_irq);
|
||||
keyboard_at.last_irq = 0;
|
||||
break;
|
||||
|
||||
|
@@ -128,7 +128,7 @@ machine_t machines[] =
|
||||
{"[486 ISA] DTK PKM-0038S E-2", ROM_DTK486, "dtk486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_AT | MACHINE_HAS_IDE, 1, 64, 1, 127, machine_at_dtk486_init, NULL },
|
||||
{"[486 ISA] IBM PS/1 machine 2133", ROM_IBMPS1_2133, "ibmps1_2133", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_AT | MACHINE_PS2 | MACHINE_HAS_IDE, 1, 64, 1, 127, machine_ps1_m2133_init, NULL },
|
||||
|
||||
{"[486 MCA] IBM PS/2 model 80-486", ROM_IBMPS2_M80, "ibmps2_m80-486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 1, MACHINE_AT | MACHINE_PS2 | MACHINE_PS2_HDD | MACHINE_MCA, 1, 32, 1, 63, machine_ps2_model_80_486_init, NULL },
|
||||
{"[486 MCA] IBM PS/2 model 80-486", ROM_IBMPS2_M80_486, "ibmps2_m80-486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 1, MACHINE_AT | MACHINE_PS2 | MACHINE_PS2_HDD | MACHINE_MCA, 1, 32, 1, 63, machine_ps2_model_80_486_init, NULL },
|
||||
|
||||
{"[486 PCI] Rise Computer R418", ROM_R418, "r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MACHINE_AT | MACHINE_HAS_IDE | MACHINE_PCI, 1, 64, 1, 127, machine_at_r418_init, NULL },
|
||||
|
||||
|
@@ -852,6 +852,7 @@ int loadbios()
|
||||
return 1;
|
||||
|
||||
case ROM_IBMPS2_M80:
|
||||
case ROM_IBMPS2_M80_486:
|
||||
f=romfopen(L"roms/machines/ibmps2_m80/15f6637.bin",L"rb");
|
||||
ff=romfopen(L"roms/machines/ibmps2_m80/15f6639.bin",L"rb");
|
||||
if (!f || !ff) break;
|
||||
|
40
src/pci.c
40
src/pci.c
@@ -133,9 +133,17 @@ static uint8_t pci_read(uint16_t port, void *priv)
|
||||
static void elcr_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
/* pci_log("ELCR%i: WRITE %02X\n", port & 1, val); */
|
||||
if (port & 1)
|
||||
{
|
||||
val &= 0xDE;
|
||||
}
|
||||
else
|
||||
{
|
||||
val &= 0xF8;
|
||||
}
|
||||
elcr[port & 1] = val;
|
||||
|
||||
/* printf("ELCR %i: %c %c %c %c %c %c %c %c\n", port & 1, (val & 1) ? 'L' : 'E', (val & 2) ? 'L' : 'E', (val & 4) ? 'L' : 'E', (val & 8) ? 'L' : 'E', (val & 0x10) ? 'L' : 'E', (val & 0x20) ? 'L' : 'E', (val & 0x40) ? 'L' : 'E', (val & 0x80) ? 'L' : 'E'); */
|
||||
printf("ELCR %i: %c %c %c %c %c %c %c %c\n", port & 1, (val & 1) ? 'L' : 'E', (val & 2) ? 'L' : 'E', (val & 4) ? 'L' : 'E', (val & 8) ? 'L' : 'E', (val & 0x10) ? 'L' : 'E', (val & 0x20) ? 'L' : 'E', (val & 0x40) ? 'L' : 'E', (val & 0x80) ? 'L' : 'E');
|
||||
}
|
||||
|
||||
static uint8_t elcr_read(uint16_t port, void *priv)
|
||||
@@ -147,7 +155,9 @@ static uint8_t elcr_read(uint16_t port, void *priv)
|
||||
static void elcr_reset(void)
|
||||
{
|
||||
pic_reset();
|
||||
elcr[0] = elcr[1] = 0;
|
||||
/* elcr[0] = elcr[1] = 0; */
|
||||
elcr[0] = 0x98;
|
||||
elcr[1] = 0x00;
|
||||
}
|
||||
|
||||
static void pci_type2_write(uint16_t port, uint8_t val, void *priv);
|
||||
@@ -236,10 +246,15 @@ void pci_set_mirq_routing(int mirq, int irq)
|
||||
pci_mirqs[mirq].irq_line = irq;
|
||||
}
|
||||
|
||||
static int pci_irq_is_level(int irq)
|
||||
int pci_irq_is_level(int irq)
|
||||
{
|
||||
int real_irq = irq & 7;
|
||||
|
||||
if ((irq <= 2) || (irq == 8) || (irq == 13))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (irq > 7)
|
||||
{
|
||||
return !!(elcr[1] & (1 << real_irq));
|
||||
@@ -250,21 +265,6 @@ static int pci_irq_is_level(int irq)
|
||||
}
|
||||
}
|
||||
|
||||
static void pci_issue_irq(int irq)
|
||||
{
|
||||
/* pci_log("Issuing PCI IRQ %i: ", irq); */
|
||||
if (pci_irq_is_level(irq))
|
||||
{
|
||||
/* pci_log("Level\n"); */
|
||||
picintlevel(1 << irq);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* pci_log("Edge\n"); */
|
||||
picint(1 << irq);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t pci_use_mirq(uint8_t mirq)
|
||||
{
|
||||
if (!PCI || !pci_mirqs[0].enabled)
|
||||
@@ -328,7 +328,7 @@ void pci_set_mirq(uint8_t mirq, uint8_t channel)
|
||||
pci_mirq_log("pci_set_mirq(%02X, %02X): Issuing %s-triggered IRQ (%sheld)\n", mirq, channel, level ? "level" : "edge", pci_irq_hold[irq_line] ? "" : "not ");
|
||||
|
||||
/* Only raise the interrupt if it's edge-triggered or level-triggered and not yet being held. */
|
||||
pci_issue_irq(irq_line);
|
||||
picintlevel(1 << irq_line);
|
||||
}
|
||||
else if (level && pci_irq_hold[irq_line])
|
||||
{
|
||||
@@ -417,7 +417,7 @@ void pci_set_irq(uint8_t card, uint8_t pci_int)
|
||||
pci_log("pci_set_irq(%02X, %02X): Issuing %s-triggered IRQ (%sheld)\n", card, pci_int, level ? "level" : "edge", pci_irq_hold[irq_line] ? "" : "not ");
|
||||
|
||||
/* Only raise the interrupt if it's edge-triggered or level-triggered and not yet being held. */
|
||||
pci_issue_irq(irq_line);
|
||||
picintlevel(1 << irq_line);
|
||||
}
|
||||
else if (level && pci_irq_hold[irq_line])
|
||||
{
|
||||
|
@@ -5,6 +5,8 @@ void pci_set_mirq_routing(int mirq, int irq);
|
||||
|
||||
uint8_t pci_use_mirq(uint8_t mirq);
|
||||
|
||||
int pci_irq_is_level(int irq);
|
||||
|
||||
void pci_set_mirq(uint8_t mirq, uint8_t channel);
|
||||
void pci_set_irq(uint8_t card, uint8_t pci_int);
|
||||
void pci_clear_mirq(uint8_t mirq, uint8_t channel);
|
||||
|
259
src/pic.c
259
src/pic.c
@@ -1,5 +1,6 @@
|
||||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "pci.h"
|
||||
#include "pic.h"
|
||||
#include "pit.h"
|
||||
|
||||
@@ -18,14 +19,14 @@ void pic_updatepending()
|
||||
if (AT)
|
||||
{
|
||||
if ((pic2.pend&~pic2.mask)&~pic2.mask2)
|
||||
pic.pend |= (1 << 2);
|
||||
pic.pend |= pic.icw3;
|
||||
else
|
||||
pic.pend &= ~(1 << 2);
|
||||
pic.pend &= ~pic.icw3;
|
||||
}
|
||||
pic_intpending = (pic.pend & ~pic.mask) & ~pic.mask2;
|
||||
if (AT)
|
||||
{
|
||||
if (!((pic.mask | pic.mask2) & (1 << 2)))
|
||||
if (!((pic.mask | pic.mask2) & pic.icw3))
|
||||
{
|
||||
temp_pending = ((pic2.pend&~pic2.mask)&~pic2.mask2);
|
||||
temp_pending <<= 8;
|
||||
@@ -66,6 +67,25 @@ void pic_update_mask(uint8_t *mask, uint8_t ins)
|
||||
}
|
||||
}
|
||||
|
||||
static int picint_is_level(uint16_t irq)
|
||||
{
|
||||
if (PCI)
|
||||
{
|
||||
return pci_irq_is_level(irq);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (irq < 8)
|
||||
{
|
||||
return (pic.icw1 & 8) ? 1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (pic2.icw1 & 8) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pic_autoeoi()
|
||||
{
|
||||
int c;
|
||||
@@ -79,8 +99,16 @@ static void pic_autoeoi()
|
||||
|
||||
if (AT)
|
||||
{
|
||||
if (c == 2 && (pic2.pend&~pic2.mask)&~pic2.mask2)
|
||||
pic.pend |= (1 << 2);
|
||||
if (((1 << c) == pic.icw3) && (pic2.pend&~pic2.mask)&~pic2.mask2)
|
||||
pic.pend |= pic.icw3;
|
||||
}
|
||||
|
||||
if ((pic_current & (1 << c)) && picint_is_level(c))
|
||||
{
|
||||
if (((1 << c) != pic.icw3) || !AT)
|
||||
{
|
||||
pic.pend |= 1 << c;
|
||||
}
|
||||
}
|
||||
|
||||
pic_updatepending();
|
||||
@@ -106,6 +134,8 @@ void pic_write(uint16_t addr, uint8_t val, void *priv)
|
||||
else pic.icw=2;
|
||||
break;
|
||||
case 2: /*ICW3*/
|
||||
pic.icw3 = val;
|
||||
pclog("PIC1 ICW3 now %02X\n", val);
|
||||
if (pic.icw1&1) pic.icw=3;
|
||||
else pic.icw=0;
|
||||
break;
|
||||
@@ -134,9 +164,18 @@ void pic_write(uint16_t addr, uint8_t val, void *priv)
|
||||
pic_update_mask(&pic.mask2, pic.ins);
|
||||
if (AT)
|
||||
{
|
||||
if ((val&7) == 2 && (pic2.pend&~pic2.mask)&~pic2.mask2)
|
||||
pic.pend |= (1 << 2);
|
||||
if (((val&7) == pic2.icw3) && (pic2.pend&~pic2.mask)&~pic2.mask2)
|
||||
pic.pend |= pic.icw3;
|
||||
}
|
||||
|
||||
if ((pic_current & (1 << (val & 7))) && picint_is_level(val & 7))
|
||||
{
|
||||
if ((((1 << (val & 7)) != pic.icw3) || !AT))
|
||||
{
|
||||
pic.pend |= 1 << (val & 7);
|
||||
}
|
||||
}
|
||||
|
||||
pic_updatepending();
|
||||
}
|
||||
else
|
||||
@@ -150,8 +189,16 @@ void pic_write(uint16_t addr, uint8_t val, void *priv)
|
||||
|
||||
if (AT)
|
||||
{
|
||||
if (c == 2 && (pic2.pend&~pic2.mask)&~pic2.mask2)
|
||||
pic.pend |= (1 << 2);
|
||||
if (((1 << c) == pic.icw3) && (pic2.pend&~pic2.mask)&~pic2.mask2)
|
||||
pic.pend |= pic.icw3;
|
||||
}
|
||||
|
||||
if ((pic_current & (1 << c)) && picint_is_level(c))
|
||||
{
|
||||
if ((((1 << c) != pic.icw3) || !AT))
|
||||
{
|
||||
pic.pend |= 1 << c;
|
||||
}
|
||||
}
|
||||
|
||||
if (c==1 && keywaiting)
|
||||
@@ -195,6 +242,12 @@ static void pic2_autoeoi()
|
||||
pic2.ins &= ~(1 << c);
|
||||
pic_update_mask(&pic2.mask2, pic2.ins);
|
||||
|
||||
if (pic_current & (0x100 << c) && picint_is_level(c + 8))
|
||||
{
|
||||
pic2.pend |= (1 << c);
|
||||
pic.pend |= (1 << pic2.icw3);
|
||||
}
|
||||
|
||||
pic_updatepending();
|
||||
return;
|
||||
}
|
||||
@@ -219,6 +272,8 @@ void pic2_write(uint16_t addr, uint8_t val, void *priv)
|
||||
else pic2.icw=2;
|
||||
break;
|
||||
case 2: /*ICW3*/
|
||||
pic2.icw3 = val;
|
||||
pclog("PIC2 ICW3 now %02X\n", val);
|
||||
if (pic2.icw1&1) pic2.icw=3;
|
||||
else pic2.icw=0;
|
||||
break;
|
||||
@@ -246,6 +301,12 @@ void pic2_write(uint16_t addr, uint8_t val, void *priv)
|
||||
pic2.ins&=~(1<<(val&7));
|
||||
pic_update_mask(&pic2.mask2, pic2.ins);
|
||||
|
||||
if (pic_current & (0x100 << (val & 7)) && picint_is_level((val & 7) + 8))
|
||||
{
|
||||
pic2.pend |= (1 << (val & 7));
|
||||
pic.pend |= (1 << pic2.icw3);
|
||||
}
|
||||
|
||||
pic_updatepending();
|
||||
}
|
||||
else
|
||||
@@ -256,7 +317,13 @@ void pic2_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
pic2.ins &= ~(1<<c);
|
||||
pic_update_mask(&pic2.mask2, pic2.ins);
|
||||
|
||||
|
||||
if (pic_current & (0x100 << c) && picint_is_level(c + 8))
|
||||
{
|
||||
pic2.pend |= (1 << c);
|
||||
pic.pend |= (1 << pic2.icw3);
|
||||
}
|
||||
|
||||
pic_updatepending();
|
||||
return;
|
||||
}
|
||||
@@ -290,76 +357,98 @@ void clearpic()
|
||||
pic_updatepending();
|
||||
}
|
||||
|
||||
void picint(uint16_t num)
|
||||
{
|
||||
if (AT && (num == (1 << 2)))
|
||||
num = 1 << 9;
|
||||
if (num>0xFF)
|
||||
{
|
||||
if (!AT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pic2.pend|=(num>>8);
|
||||
if ((pic2.pend&~pic2.mask)&~pic2.mask2)
|
||||
pic.pend |= (1 << 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
pic.pend|=num;
|
||||
}
|
||||
/* if (num == 0x40)
|
||||
{
|
||||
pclog("picint : PEND now %02X %02X\n", pic.pend, pic2.pend);
|
||||
} */
|
||||
pic_updatepending();
|
||||
/* if (num == 0x40)
|
||||
{
|
||||
pclog("Processing FDC interrupt, pending: %s, previously pending: %s, masked: %s, masked (2): %s, T: %s, I: %s\n", (pic_intpending & num) ? "yes" : "no", (old_pend & num) ? "yes" : "no", (pic.mask & num) ? "yes" : "no", (pic.mask2 & num) ? "yes" : "no", (flags & 0x100) ? "yes" : "no", (flags&I_FLAG) ? "yes" : "no");
|
||||
} */
|
||||
}
|
||||
|
||||
void picintlevel(uint16_t num)
|
||||
void picint_common(uint16_t num, int level)
|
||||
{
|
||||
int c = 0;
|
||||
while (!(num & (1 << c))) c++;
|
||||
if (AT && (c == 2))
|
||||
{
|
||||
c = 9;
|
||||
|
||||
if (!num)
|
||||
{
|
||||
/* pclog("Attempting to raise null IRQ\n"); */
|
||||
return;
|
||||
}
|
||||
|
||||
if (AT && (num == pic.icw3) && (pic.icw3 == 4))
|
||||
{
|
||||
num = 1 << 9;
|
||||
}
|
||||
if (!(pic_current & num))
|
||||
}
|
||||
|
||||
while (!(num & (1 << c))) c++;
|
||||
|
||||
if (AT && (num == pic.icw3) && (pic.icw3 != 4))
|
||||
{
|
||||
/* pclog("Attempting to raise cascaded IRQ %i\n"); */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(pic_current & num) || !level)
|
||||
{
|
||||
pic_current |= num;
|
||||
if (num>0xFF)
|
||||
{
|
||||
/* pclog("Raising IRQ %i\n", c); */
|
||||
|
||||
if (level)
|
||||
{
|
||||
pic_current |= num;
|
||||
}
|
||||
|
||||
if (num>0xFF)
|
||||
{
|
||||
if (!AT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pic2.pend|=(num>>8);
|
||||
}
|
||||
else
|
||||
{
|
||||
pic.pend|=num;
|
||||
}
|
||||
}
|
||||
pic_updatepending();
|
||||
pic2.pend|=(num>>8);
|
||||
if ((pic2.pend&~pic2.mask)&~pic2.mask2)
|
||||
{
|
||||
pic.pend |= (1 << pic2.icw3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pic.pend|=num;
|
||||
}
|
||||
pic_updatepending();
|
||||
}
|
||||
}
|
||||
|
||||
void picint(uint16_t num)
|
||||
{
|
||||
picint_common(num, 0);
|
||||
}
|
||||
|
||||
void picintlevel(uint16_t num)
|
||||
{
|
||||
picint_common(num, 1);
|
||||
}
|
||||
|
||||
void picintc(uint16_t num)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
if (!num)
|
||||
{
|
||||
/* pclog("Attempting to lower null IRQ\n"); */
|
||||
return;
|
||||
while (!(num & (1 << c))) c++;
|
||||
if (AT && (c == 2))
|
||||
{
|
||||
c = 9;
|
||||
}
|
||||
|
||||
if (AT && (num == pic.icw3) && (pic.icw3 == 4))
|
||||
{
|
||||
num = 1 << 9;
|
||||
}
|
||||
pic_current &= ~num;
|
||||
}
|
||||
|
||||
while (!(num & (1 << c))) c++;
|
||||
|
||||
if (AT && (num == pic.icw3) && (pic.icw3 != 4))
|
||||
{
|
||||
/* pclog("Attempting to lower cascaded IRQ %i\n"); */
|
||||
return;
|
||||
}
|
||||
|
||||
if (pic_current & num)
|
||||
{
|
||||
pic_current &= ~num;
|
||||
}
|
||||
|
||||
/* pclog("Lowering IRQ %i\n", c); */
|
||||
|
||||
if (num > 0xff)
|
||||
{
|
||||
@@ -370,7 +459,9 @@ void picintc(uint16_t num)
|
||||
|
||||
pic2.pend &= ~(num >> 8);
|
||||
if (!((pic2.pend&~pic2.mask)&~pic2.mask2))
|
||||
pic.pend &= ~(1 << 2);
|
||||
{
|
||||
pic.pend &= ~(1 << pic2.icw3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -394,20 +485,17 @@ static uint8_t pic_process_interrupt(PIC* target_pic, int c)
|
||||
int pic_int = c & 7;
|
||||
int pic_int_num = 1 << pic_int;
|
||||
|
||||
int pic_cur_num = 1 << c;
|
||||
/* int pic_cur_num = 1 << c; */
|
||||
|
||||
if (pending & pic_int_num)
|
||||
{
|
||||
if (!(pic_current & pic_cur_num))
|
||||
{
|
||||
target_pic->pend &= ~pic_int_num;
|
||||
}
|
||||
target_pic->pend &= ~pic_int_num;
|
||||
target_pic->ins |= pic_int_num;
|
||||
pic_update_mask(&target_pic->mask2, target_pic->ins);
|
||||
|
||||
if (c >= 8)
|
||||
{
|
||||
pic.ins |= (1 << 2); /*Cascade IRQ*/
|
||||
pic.ins |= (1 << pic2.icw3); /*Cascade IRQ*/
|
||||
pic_update_mask(&pic.mask2, pic.ins);
|
||||
}
|
||||
|
||||
@@ -433,47 +521,34 @@ static uint8_t pic_process_interrupt(PIC* target_pic, int c)
|
||||
|
||||
uint8_t picinterrupt()
|
||||
{
|
||||
int c;
|
||||
int c, d;
|
||||
uint8_t ret;
|
||||
|
||||
uint8_t irq2_pending = (pic.pend & ~pic.mask) & (1 << 2);
|
||||
|
||||
for (c = 0; c <= 1; c++)
|
||||
for (c = 0; c <= 7; c++)
|
||||
{
|
||||
ret = pic_process_interrupt(&pic, c);
|
||||
if (ret != 0xFF) return ret;
|
||||
}
|
||||
if (irq2_pending)
|
||||
{
|
||||
if (AT)
|
||||
if (AT && ((1 << c) == pic.icw3))
|
||||
{
|
||||
for (c = 8; c <= 15; c++)
|
||||
for (d = 8; d <= 15; d++)
|
||||
{
|
||||
ret = pic_process_interrupt(&pic2, c);
|
||||
pclog("Processing IRQ %i: %02X\n", c, ret);
|
||||
ret = pic_process_interrupt(&pic2, d);
|
||||
if (ret != 0xFF) return ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = pic_process_interrupt(&pic, 2);
|
||||
ret = pic_process_interrupt(&pic, c);
|
||||
if (ret != 0xFF) return ret;
|
||||
}
|
||||
}
|
||||
for (c = 3; c <= 7; c++)
|
||||
{
|
||||
ret = pic_process_interrupt(&pic, c);
|
||||
if (ret != 0xFF) return ret;
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
void dumppic()
|
||||
{
|
||||
pclog("PIC1 : MASK %02X PEND %02X INS %02X VECTOR %02X\n",pic.mask,pic.pend,pic.ins,pic.vector);
|
||||
pclog("PIC1 : MASK %02X PEND %02X INS %02X LEVEL %02X VECTOR %02X CASCADE %02X\n", pic.mask, pic.pend, pic.ins, (pic.icw1 & 8) ? 1 : 0, pic.vector, pic.icw3);
|
||||
if (AT)
|
||||
{
|
||||
pclog("PIC2 : MASK %02X PEND %02X INS %02X VECTOR %02X\n",pic2.mask,pic2.pend,pic2.ins,pic2.vector);
|
||||
pclog("PIC2 : MASK %02X PEND %02X INS %02X LEVEL %02X VECTOR %02X CASCADE %02X\n", pic2.mask, pic2.pend, pic2.ins, (pic2.icw1 & 8) ? 1 : 0, pic2.vector, pic2.icw3);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -422,7 +422,6 @@ typedef struct {
|
||||
int PendingInterrupt;
|
||||
int Lock;
|
||||
event_t *evt;
|
||||
int scan_restart;
|
||||
} aha_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
@@ -638,7 +637,6 @@ aha_reset(aha_t *dev)
|
||||
}
|
||||
|
||||
dev->ResetCB = 0;
|
||||
dev->scan_restart = 0;
|
||||
|
||||
dev->Status = STAT_IDLE | STAT_INIT;
|
||||
dev->Geometry = 0x80;
|
||||
@@ -1220,7 +1218,7 @@ aha_mbo_adv(aha_t *dev)
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
static void
|
||||
aha_do_mail(aha_t *dev)
|
||||
{
|
||||
Mailbox32_t mb32;
|
||||
@@ -1247,7 +1245,7 @@ aha_do_mail(aha_t *dev)
|
||||
DMAPageWrite(Outgoing + CodeOffset, (char *)&CmdStatus, sizeof(CmdStatus));
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (dev->MailboxOutInterrupts) {
|
||||
@@ -1266,8 +1264,6 @@ aha_do_mail(aha_t *dev)
|
||||
} else {
|
||||
aha_log("Invalid action code: %02X\n", mb32.u.out.ActionCode);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1276,13 +1272,12 @@ aha_cmd_thread(void *priv)
|
||||
{
|
||||
aha_t *dev = (aha_t *)priv;
|
||||
|
||||
aha_event_restart:
|
||||
/* Create a waitable event. */
|
||||
dev->evt = thread_create_event();
|
||||
|
||||
aha_scan_restart:
|
||||
while (aha_do_mail(dev) && dev->MailboxCount)
|
||||
while (dev->MailboxCount)
|
||||
{
|
||||
aha_do_mail(dev);
|
||||
}
|
||||
|
||||
if (!dev->MailboxCount)
|
||||
@@ -1293,22 +1288,8 @@ aha_scan_restart:
|
||||
return;
|
||||
}
|
||||
|
||||
if (dev->scan_restart)
|
||||
{
|
||||
dev->scan_restart = 0;
|
||||
goto aha_scan_restart;
|
||||
}
|
||||
|
||||
thread_destroy_event(dev->evt);
|
||||
dev->evt = NULL;
|
||||
|
||||
if (dev->scan_restart)
|
||||
{
|
||||
dev->scan_restart = 0;
|
||||
goto aha_event_restart;
|
||||
}
|
||||
|
||||
poll_tid = NULL;
|
||||
dev->evt = poll_tid = NULL;
|
||||
|
||||
aha_log("%s: Callback: polling stopped.\n", dev->name);
|
||||
}
|
||||
@@ -1400,10 +1381,6 @@ aha_write(uint16_t port, uint8_t val, void *priv)
|
||||
if (! poll_tid) {
|
||||
aha_log("%s: starting thread..\n", dev->name);
|
||||
poll_tid = thread_create(aha_cmd_thread, dev);
|
||||
dev->scan_restart = 0;
|
||||
}
|
||||
else {
|
||||
dev->scan_restart = 1;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@@ -1489,7 +1489,7 @@ BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
|
||||
bl->scan_restart = 0;
|
||||
}
|
||||
else {
|
||||
bl->scan_restart = 1;
|
||||
bl->scan_restart = bl->LocalRAM.structured.autoSCSIData.fAggressiveRoundRobinMode ? 0 : 1;
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -2571,8 +2571,18 @@ BuslogicEventRestart:
|
||||
bl->evt = thread_create_event();
|
||||
|
||||
BuslogicScanRestart:
|
||||
while (BuslogicProcessMailbox(bl) && bl->MailboxCount)
|
||||
if (bl->LocalRAM.structured.autoSCSIData.fAggressiveRoundRobinMode)
|
||||
{
|
||||
while (bl->MailboxCount)
|
||||
{
|
||||
BuslogicProcessMailbox(bl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (BuslogicProcessMailbox(bl) && bl->MailboxCount)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (!bl->MailboxCount)
|
||||
|
Reference in New Issue
Block a user