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
|
else
|
||||||
{
|
{
|
||||||
ide->atastat = BUSY_STAT;
|
ide->atastat = BUSY_STAT;
|
||||||
|
ide_other->atastat = BUSY_STAT;
|
||||||
}
|
}
|
||||||
timer_process();
|
timer_process();
|
||||||
callbackide(ide_board);
|
/* callbackide(ide_board); */
|
||||||
if (ide_drive_is_cdrom(ide))
|
if (ide_drive_is_cdrom(ide))
|
||||||
{
|
{
|
||||||
cdrom[atapi_cdrom_drives[ide->channel]].callback = 200 * IDE_TIME;
|
cdrom[atapi_cdrom_drives[ide->channel]].callback = 200 * IDE_TIME;
|
||||||
@@ -1502,6 +1503,7 @@ void callbackide(int ide_board)
|
|||||||
IDE *ide, *ide_other;
|
IDE *ide, *ide_other;
|
||||||
int64_t snum;
|
int64_t snum;
|
||||||
int cdrom_id;
|
int cdrom_id;
|
||||||
|
int cdrom_id_other;
|
||||||
uint64_t full_size = 0;
|
uint64_t full_size = 0;
|
||||||
|
|
||||||
ide = &ide_drives[cur_ide[ide_board]];
|
ide = &ide_drives[cur_ide[ide_board]];
|
||||||
@@ -1549,15 +1551,15 @@ void callbackide(int ide_board)
|
|||||||
}
|
}
|
||||||
if (ide_drive_is_cdrom(ide_other))
|
if (ide_drive_is_cdrom(ide_other))
|
||||||
{
|
{
|
||||||
cdrom_id = atapi_cdrom_drives[cur_ide[ide_board] ^ 1];
|
cdrom_id_other = atapi_cdrom_drives[cur_ide[ide_board] ^ 1];
|
||||||
cdrom[cdrom_id].status = READY_STAT | DSC_STAT;
|
cdrom[cdrom_id_other].status = READY_STAT | DSC_STAT;
|
||||||
cdrom[cdrom_id].error = 1;
|
cdrom[cdrom_id_other].error = 1;
|
||||||
cdrom[cdrom_id].phase = 1;
|
cdrom[cdrom_id_other].phase = 1;
|
||||||
cdrom[cdrom_id].request_length=0xEB14;
|
cdrom[cdrom_id_other].request_length=0xEB14;
|
||||||
ide_other->cylinder = 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)
|
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 = atapi_cdrom_drives[cur_ide[ide_board]];
|
||||||
|
cdrom_id_other = atapi_cdrom_drives[cur_ide[ide_board] ^ 1];
|
||||||
|
|
||||||
switch (ide->command)
|
switch (ide->command)
|
||||||
{
|
{
|
||||||
@@ -1918,6 +1921,24 @@ void callbackide(int ide_board)
|
|||||||
ide->error = 1;
|
ide->error = 1;
|
||||||
ide_irq_raise(ide);
|
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;
|
return;
|
||||||
|
|
||||||
case WIN_SPECIFY: /* Initialize Drive Parameters */
|
case WIN_SPECIFY: /* Initialize Drive Parameters */
|
||||||
|
|||||||
@@ -363,7 +363,7 @@ extern PPI ppi;
|
|||||||
/*PIC*/
|
/*PIC*/
|
||||||
typedef struct PIC
|
typedef struct PIC
|
||||||
{
|
{
|
||||||
uint8_t icw1,icw4,mask,ins,pend,mask2;
|
uint8_t icw1,icw3,icw4,mask,ins,pend,mask2;
|
||||||
int icw;
|
int icw;
|
||||||
uint8_t vector;
|
uint8_t vector;
|
||||||
int read;
|
int read;
|
||||||
@@ -484,6 +484,7 @@ enum
|
|||||||
ROM_IBMPS1_2133,
|
ROM_IBMPS1_2133,
|
||||||
|
|
||||||
ROM_PRESIDENT, /*President Award 430FX PCI / 430FX / Award BIOS / Unknown Super I/O chip*/
|
ROM_PRESIDENT, /*President Award 430FX PCI / 430FX / Award BIOS / Unknown Super I/O chip*/
|
||||||
|
ROM_IBMPS2_M80_486,
|
||||||
|
|
||||||
ROM_MAX
|
ROM_MAX
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -823,10 +823,7 @@ uint8_t keyboard_at_read(uint16_t port, void *priv)
|
|||||||
case 0x60:
|
case 0x60:
|
||||||
temp = keyboard_at.out;
|
temp = keyboard_at.out;
|
||||||
keyboard_at.status &= ~(STAT_OFULL/* | STAT_MFULL*/);
|
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;
|
keyboard_at.last_irq = 0;
|
||||||
break;
|
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] 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 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 },
|
{"[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;
|
return 1;
|
||||||
|
|
||||||
case ROM_IBMPS2_M80:
|
case ROM_IBMPS2_M80:
|
||||||
|
case ROM_IBMPS2_M80_486:
|
||||||
f=romfopen(L"roms/machines/ibmps2_m80/15f6637.bin",L"rb");
|
f=romfopen(L"roms/machines/ibmps2_m80/15f6637.bin",L"rb");
|
||||||
ff=romfopen(L"roms/machines/ibmps2_m80/15f6639.bin",L"rb");
|
ff=romfopen(L"roms/machines/ibmps2_m80/15f6639.bin",L"rb");
|
||||||
if (!f || !ff) break;
|
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)
|
static void elcr_write(uint16_t port, uint8_t val, void *priv)
|
||||||
{
|
{
|
||||||
/* pci_log("ELCR%i: WRITE %02X\n", port & 1, val); */
|
/* pci_log("ELCR%i: WRITE %02X\n", port & 1, val); */
|
||||||
|
if (port & 1)
|
||||||
|
{
|
||||||
|
val &= 0xDE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
val &= 0xF8;
|
||||||
|
}
|
||||||
elcr[port & 1] = val;
|
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)
|
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)
|
static void elcr_reset(void)
|
||||||
{
|
{
|
||||||
pic_reset();
|
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);
|
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;
|
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;
|
int real_irq = irq & 7;
|
||||||
|
|
||||||
|
if ((irq <= 2) || (irq == 8) || (irq == 13))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (irq > 7)
|
if (irq > 7)
|
||||||
{
|
{
|
||||||
return !!(elcr[1] & (1 << real_irq));
|
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)
|
uint8_t pci_use_mirq(uint8_t mirq)
|
||||||
{
|
{
|
||||||
if (!PCI || !pci_mirqs[0].enabled)
|
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 ");
|
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. */
|
/* 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])
|
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 ");
|
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. */
|
/* 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])
|
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);
|
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_mirq(uint8_t mirq, uint8_t channel);
|
||||||
void pci_set_irq(uint8_t card, uint8_t pci_int);
|
void pci_set_irq(uint8_t card, uint8_t pci_int);
|
||||||
void pci_clear_mirq(uint8_t mirq, uint8_t channel);
|
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 "ibm.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
#include "pci.h"
|
||||||
#include "pic.h"
|
#include "pic.h"
|
||||||
#include "pit.h"
|
#include "pit.h"
|
||||||
|
|
||||||
@@ -18,14 +19,14 @@ void pic_updatepending()
|
|||||||
if (AT)
|
if (AT)
|
||||||
{
|
{
|
||||||
if ((pic2.pend&~pic2.mask)&~pic2.mask2)
|
if ((pic2.pend&~pic2.mask)&~pic2.mask2)
|
||||||
pic.pend |= (1 << 2);
|
pic.pend |= pic.icw3;
|
||||||
else
|
else
|
||||||
pic.pend &= ~(1 << 2);
|
pic.pend &= ~pic.icw3;
|
||||||
}
|
}
|
||||||
pic_intpending = (pic.pend & ~pic.mask) & ~pic.mask2;
|
pic_intpending = (pic.pend & ~pic.mask) & ~pic.mask2;
|
||||||
if (AT)
|
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 = ((pic2.pend&~pic2.mask)&~pic2.mask2);
|
||||||
temp_pending <<= 8;
|
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()
|
static void pic_autoeoi()
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
@@ -79,8 +99,16 @@ static void pic_autoeoi()
|
|||||||
|
|
||||||
if (AT)
|
if (AT)
|
||||||
{
|
{
|
||||||
if (c == 2 && (pic2.pend&~pic2.mask)&~pic2.mask2)
|
if (((1 << c) == pic.icw3) && (pic2.pend&~pic2.mask)&~pic2.mask2)
|
||||||
pic.pend |= (1 << 2);
|
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();
|
pic_updatepending();
|
||||||
@@ -106,6 +134,8 @@ void pic_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
else pic.icw=2;
|
else pic.icw=2;
|
||||||
break;
|
break;
|
||||||
case 2: /*ICW3*/
|
case 2: /*ICW3*/
|
||||||
|
pic.icw3 = val;
|
||||||
|
pclog("PIC1 ICW3 now %02X\n", val);
|
||||||
if (pic.icw1&1) pic.icw=3;
|
if (pic.icw1&1) pic.icw=3;
|
||||||
else pic.icw=0;
|
else pic.icw=0;
|
||||||
break;
|
break;
|
||||||
@@ -134,9 +164,18 @@ void pic_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
pic_update_mask(&pic.mask2, pic.ins);
|
pic_update_mask(&pic.mask2, pic.ins);
|
||||||
if (AT)
|
if (AT)
|
||||||
{
|
{
|
||||||
if ((val&7) == 2 && (pic2.pend&~pic2.mask)&~pic2.mask2)
|
if (((val&7) == pic2.icw3) && (pic2.pend&~pic2.mask)&~pic2.mask2)
|
||||||
pic.pend |= (1 << 2);
|
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();
|
pic_updatepending();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -150,8 +189,16 @@ void pic_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
|
|
||||||
if (AT)
|
if (AT)
|
||||||
{
|
{
|
||||||
if (c == 2 && (pic2.pend&~pic2.mask)&~pic2.mask2)
|
if (((1 << c) == pic.icw3) && (pic2.pend&~pic2.mask)&~pic2.mask2)
|
||||||
pic.pend |= (1 << 2);
|
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)
|
if (c==1 && keywaiting)
|
||||||
@@ -195,6 +242,12 @@ static void pic2_autoeoi()
|
|||||||
pic2.ins &= ~(1 << c);
|
pic2.ins &= ~(1 << c);
|
||||||
pic_update_mask(&pic2.mask2, pic2.ins);
|
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();
|
pic_updatepending();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -219,6 +272,8 @@ void pic2_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
else pic2.icw=2;
|
else pic2.icw=2;
|
||||||
break;
|
break;
|
||||||
case 2: /*ICW3*/
|
case 2: /*ICW3*/
|
||||||
|
pic2.icw3 = val;
|
||||||
|
pclog("PIC2 ICW3 now %02X\n", val);
|
||||||
if (pic2.icw1&1) pic2.icw=3;
|
if (pic2.icw1&1) pic2.icw=3;
|
||||||
else pic2.icw=0;
|
else pic2.icw=0;
|
||||||
break;
|
break;
|
||||||
@@ -246,6 +301,12 @@ void pic2_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
pic2.ins&=~(1<<(val&7));
|
pic2.ins&=~(1<<(val&7));
|
||||||
pic_update_mask(&pic2.mask2, pic2.ins);
|
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();
|
pic_updatepending();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -256,7 +317,13 @@ void pic2_write(uint16_t addr, uint8_t val, void *priv)
|
|||||||
{
|
{
|
||||||
pic2.ins &= ~(1<<c);
|
pic2.ins &= ~(1<<c);
|
||||||
pic_update_mask(&pic2.mask2, pic2.ins);
|
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();
|
pic_updatepending();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -290,76 +357,98 @@ void clearpic()
|
|||||||
pic_updatepending();
|
pic_updatepending();
|
||||||
}
|
}
|
||||||
|
|
||||||
void picint(uint16_t num)
|
void picint_common(uint16_t num, int level)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
int c = 0;
|
int c = 0;
|
||||||
while (!(num & (1 << c))) c++;
|
|
||||||
if (AT && (c == 2))
|
if (!num)
|
||||||
{
|
{
|
||||||
c = 9;
|
/* pclog("Attempting to raise null IRQ\n"); */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AT && (num == pic.icw3) && (pic.icw3 == 4))
|
||||||
|
{
|
||||||
num = 1 << 9;
|
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;
|
/* pclog("Raising IRQ %i\n", c); */
|
||||||
if (num>0xFF)
|
|
||||||
{
|
if (level)
|
||||||
|
{
|
||||||
|
pic_current |= num;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num>0xFF)
|
||||||
|
{
|
||||||
if (!AT)
|
if (!AT)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pic2.pend|=(num>>8);
|
pic2.pend|=(num>>8);
|
||||||
}
|
if ((pic2.pend&~pic2.mask)&~pic2.mask2)
|
||||||
else
|
{
|
||||||
{
|
pic.pend |= (1 << pic2.icw3);
|
||||||
pic.pend|=num;
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
pic_updatepending();
|
{
|
||||||
|
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)
|
void picintc(uint16_t num)
|
||||||
{
|
{
|
||||||
int c = 0;
|
int c = 0;
|
||||||
|
|
||||||
if (!num)
|
if (!num)
|
||||||
|
{
|
||||||
|
/* pclog("Attempting to lower null IRQ\n"); */
|
||||||
return;
|
return;
|
||||||
while (!(num & (1 << c))) c++;
|
}
|
||||||
if (AT && (c == 2))
|
|
||||||
{
|
if (AT && (num == pic.icw3) && (pic.icw3 == 4))
|
||||||
c = 9;
|
{
|
||||||
num = 1 << 9;
|
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)
|
if (num > 0xff)
|
||||||
{
|
{
|
||||||
@@ -370,7 +459,9 @@ void picintc(uint16_t num)
|
|||||||
|
|
||||||
pic2.pend &= ~(num >> 8);
|
pic2.pend &= ~(num >> 8);
|
||||||
if (!((pic2.pend&~pic2.mask)&~pic2.mask2))
|
if (!((pic2.pend&~pic2.mask)&~pic2.mask2))
|
||||||
pic.pend &= ~(1 << 2);
|
{
|
||||||
|
pic.pend &= ~(1 << pic2.icw3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -394,20 +485,17 @@ static uint8_t pic_process_interrupt(PIC* target_pic, int c)
|
|||||||
int pic_int = c & 7;
|
int pic_int = c & 7;
|
||||||
int pic_int_num = 1 << pic_int;
|
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 (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;
|
target_pic->ins |= pic_int_num;
|
||||||
pic_update_mask(&target_pic->mask2, target_pic->ins);
|
pic_update_mask(&target_pic->mask2, target_pic->ins);
|
||||||
|
|
||||||
if (c >= 8)
|
if (c >= 8)
|
||||||
{
|
{
|
||||||
pic.ins |= (1 << 2); /*Cascade IRQ*/
|
pic.ins |= (1 << pic2.icw3); /*Cascade IRQ*/
|
||||||
pic_update_mask(&pic.mask2, pic.ins);
|
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()
|
uint8_t picinterrupt()
|
||||||
{
|
{
|
||||||
int c;
|
int c, d;
|
||||||
uint8_t ret;
|
uint8_t ret;
|
||||||
|
|
||||||
uint8_t irq2_pending = (pic.pend & ~pic.mask) & (1 << 2);
|
for (c = 0; c <= 7; c++)
|
||||||
|
|
||||||
for (c = 0; c <= 1; c++)
|
|
||||||
{
|
{
|
||||||
ret = pic_process_interrupt(&pic, c);
|
if (AT && ((1 << c) == pic.icw3))
|
||||||
if (ret != 0xFF) return ret;
|
|
||||||
}
|
|
||||||
if (irq2_pending)
|
|
||||||
{
|
|
||||||
if (AT)
|
|
||||||
{
|
{
|
||||||
for (c = 8; c <= 15; c++)
|
for (d = 8; d <= 15; d++)
|
||||||
{
|
{
|
||||||
ret = pic_process_interrupt(&pic2, c);
|
ret = pic_process_interrupt(&pic2, d);
|
||||||
pclog("Processing IRQ %i: %02X\n", c, ret);
|
|
||||||
if (ret != 0xFF) return ret;
|
if (ret != 0xFF) return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = pic_process_interrupt(&pic, 2);
|
ret = pic_process_interrupt(&pic, c);
|
||||||
if (ret != 0xFF) return ret;
|
if (ret != 0xFF) return ret;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
for (c = 3; c <= 7; c++)
|
|
||||||
{
|
|
||||||
ret = pic_process_interrupt(&pic, c);
|
|
||||||
if (ret != 0xFF) return ret;
|
|
||||||
}
|
}
|
||||||
return 0xFF;
|
return 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dumppic()
|
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)
|
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 PendingInterrupt;
|
||||||
int Lock;
|
int Lock;
|
||||||
event_t *evt;
|
event_t *evt;
|
||||||
int scan_restart;
|
|
||||||
} aha_t;
|
} aha_t;
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
@@ -638,7 +637,6 @@ aha_reset(aha_t *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dev->ResetCB = 0;
|
dev->ResetCB = 0;
|
||||||
dev->scan_restart = 0;
|
|
||||||
|
|
||||||
dev->Status = STAT_IDLE | STAT_INIT;
|
dev->Status = STAT_IDLE | STAT_INIT;
|
||||||
dev->Geometry = 0x80;
|
dev->Geometry = 0x80;
|
||||||
@@ -1220,7 +1218,7 @@ aha_mbo_adv(aha_t *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint8_t
|
static void
|
||||||
aha_do_mail(aha_t *dev)
|
aha_do_mail(aha_t *dev)
|
||||||
{
|
{
|
||||||
Mailbox32_t mb32;
|
Mailbox32_t mb32;
|
||||||
@@ -1247,7 +1245,7 @@ aha_do_mail(aha_t *dev)
|
|||||||
DMAPageWrite(Outgoing + CodeOffset, (char *)&CmdStatus, sizeof(CmdStatus));
|
DMAPageWrite(Outgoing + CodeOffset, (char *)&CmdStatus, sizeof(CmdStatus));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->MailboxOutInterrupts) {
|
if (dev->MailboxOutInterrupts) {
|
||||||
@@ -1266,8 +1264,6 @@ aha_do_mail(aha_t *dev)
|
|||||||
} else {
|
} else {
|
||||||
aha_log("Invalid action code: %02X\n", mb32.u.out.ActionCode);
|
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_t *dev = (aha_t *)priv;
|
||||||
|
|
||||||
aha_event_restart:
|
|
||||||
/* Create a waitable event. */
|
/* Create a waitable event. */
|
||||||
dev->evt = thread_create_event();
|
dev->evt = thread_create_event();
|
||||||
|
|
||||||
aha_scan_restart:
|
while (dev->MailboxCount)
|
||||||
while (aha_do_mail(dev) && dev->MailboxCount)
|
|
||||||
{
|
{
|
||||||
|
aha_do_mail(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dev->MailboxCount)
|
if (!dev->MailboxCount)
|
||||||
@@ -1293,22 +1288,8 @@ aha_scan_restart:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->scan_restart)
|
|
||||||
{
|
|
||||||
dev->scan_restart = 0;
|
|
||||||
goto aha_scan_restart;
|
|
||||||
}
|
|
||||||
|
|
||||||
thread_destroy_event(dev->evt);
|
thread_destroy_event(dev->evt);
|
||||||
dev->evt = NULL;
|
dev->evt = poll_tid = NULL;
|
||||||
|
|
||||||
if (dev->scan_restart)
|
|
||||||
{
|
|
||||||
dev->scan_restart = 0;
|
|
||||||
goto aha_event_restart;
|
|
||||||
}
|
|
||||||
|
|
||||||
poll_tid = NULL;
|
|
||||||
|
|
||||||
aha_log("%s: Callback: polling stopped.\n", dev->name);
|
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) {
|
if (! poll_tid) {
|
||||||
aha_log("%s: starting thread..\n", dev->name);
|
aha_log("%s: starting thread..\n", dev->name);
|
||||||
poll_tid = thread_create(aha_cmd_thread, dev);
|
poll_tid = thread_create(aha_cmd_thread, dev);
|
||||||
dev->scan_restart = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dev->scan_restart = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1489,7 +1489,7 @@ BuslogicWrite(uint16_t Port, uint8_t Val, void *p)
|
|||||||
bl->scan_restart = 0;
|
bl->scan_restart = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bl->scan_restart = 1;
|
bl->scan_restart = bl->LocalRAM.structured.autoSCSIData.fAggressiveRoundRobinMode ? 0 : 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -2571,8 +2571,18 @@ BuslogicEventRestart:
|
|||||||
bl->evt = thread_create_event();
|
bl->evt = thread_create_event();
|
||||||
|
|
||||||
BuslogicScanRestart:
|
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)
|
if (!bl->MailboxCount)
|
||||||
|
|||||||
Reference in New Issue
Block a user