From cfb559de13b08b1412ecbf0ff88d1c9e4ab4f898 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 1 Nov 2020 04:21:55 +0100 Subject: [PATCH] Made the 808x interrupts delay again, fixes PCjr (TODO: Find why exactly that's needed because it sounds like a hack to me); Fixed compiling of the PIC code with logs enabled; A number of bugfixes in cpu/x86seg.c, fixes OS/2 1.0. --- src/cpu/808x.c | 8 ++++++-- src/cpu/x86seg.c | 39 +++++++++++++++++++++------------------ src/pic.c | 2 +- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/cpu/808x.c b/src/cpu/808x.c index c9a35cedc..ffdca9a63 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -98,7 +98,8 @@ static uint32_t *ovr_seg = NULL; static int prefetching = 1, completed = 1; static int in_rep = 0, repeating = 0; static int oldc, clear_lock = 0; -static int refresh = 0, cycdiff; +static int refresh = 0, takeint = 0; +static int cycdiff; /* Various things needed for 8087. */ @@ -946,6 +947,7 @@ reset_common(int hard) cpu_alt_reset = 0; prefetching = 1; + takeint = 0; cpu_ven_reset(); @@ -1129,11 +1131,13 @@ irq_pending(void) { uint8_t temp; - if ((cpu_state.flags & I_FLAG) && pic.int_pending && !noint) + if (takeint && !noint) temp = 1; else temp = (nmi && nmi_enable && nmi_mask) || ((cpu_state.flags & T_FLAG) && !noint); + takeint = (cpu_state.flags & I_FLAG) && pic.int_pending; + return temp; } diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index f0d909723..9ff257590 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -248,6 +248,9 @@ do_seg_load(x86seg *s, uint16_t *segdat) else cpu_cur_status |= CPU_STATUS_NOTFLATSS; } + + if (s->base == 0xffffffff) + fatal("do_seg_load(): %04X%04X%04X%04X\n", segdat[3], segdat[2], segdat[1], segdat[0]); } @@ -269,7 +272,7 @@ check_seg_valid(x86seg *s) int valid = 1; x86seg *dt = (s->seg & 0x0004) ? &ldt : &gdt; - if (((s->seg & 0xfff8) + 7) >= dt->limit) + if (((s->seg & 0xfff8) + 7) > dt->limit) valid = 0; switch (s->access & 0x1f) { @@ -522,7 +525,7 @@ loadcs(uint16_t seg) addr = seg & 0xfff8; dt = (seg & 0x0004)? &ldt : &gdt; - if ((addr + 7) >= dt->limit) { + if ((addr + 7) > dt->limit) { x86gpf("loadcs(): Protected mode selector > DT limit", seg & 0xfffc); return; } @@ -610,7 +613,7 @@ loadcsjmp(uint16_t seg, uint32_t old_pc) } addr = seg & 0xfff8; dt = (seg & 0x0004) ? &ldt : &gdt; - if ((addr + 7) >= dt->limit) { + if ((addr + 7) > dt->limit) { x86gpf("loacsjmp(): Selector > DT limit", seg & 0xfffc); return; } @@ -694,7 +697,7 @@ loadcsjmp(uint16_t seg, uint32_t old_pc) } addr = seg2 & 0xfff8; dt = (seg2 & 0x0004) ? &ldt : &gdt; - if ((addr + 7) >= dt->limit) { + if ((addr + 7) > dt->limit) { x86gpf("loadcsjmp(): Call gate selector > DT limit", seg2 & 0xfffc); return; } @@ -884,7 +887,7 @@ void loadcscall(uint16_t seg) } addr = seg & 0xfff8; dt = (seg & 0x0004) ? &ldt : &gdt; - if ((addr + 7) >= dt->limit) { + if ((addr + 7) > dt->limit) { x86gpf("loadcscall(): Selector > DT limit", seg & 0xfffc); return; } @@ -975,7 +978,7 @@ void loadcscall(uint16_t seg) } addr = seg2 & 0xfff8; dt = (seg2 & 0x0004) ? &ldt : &gdt; - if ((addr + 7) >= dt->limit) { + if ((addr + 7) > dt->limit) { x86gpf("loadcscall(): ex Selector > DT limit", seg2 & 0xfff8); return; } @@ -1239,7 +1242,7 @@ pmoderetf(int is32, uint16_t off) } addr = seg & 0xfff8; dt = (seg & 0x0004) ? &ldt : &gdt; - if ((addr + 7) >= dt->limit) { + if ((addr + 7) > dt->limit) { x86gpf("pmoderetf(): Selector > DT limit", seg & 0xfffc); return; } @@ -1352,7 +1355,7 @@ pmoderetf(int is32, uint16_t off) } addr = newss & 0xfff8; dt = (newss & 0x0004) ? &ldt : &gdt; - if ((addr + 7) >= dt->limit) { + if ((addr + 7) > dt->limit) { ESP = oldsp; x86gpf("pmoderetf(): New SS selector > DT limit", newss & 0xfffc); return; @@ -1444,7 +1447,7 @@ pmodeint(int num, int soft) return; } addr = (num << 3); - if ((addr + 7) >= idt.limit) { + if ((addr + 7) > idt.limit) { if (num == 0x08) { /* Triple fault - reset! */ softresetx86(); @@ -1490,7 +1493,7 @@ pmodeint(int num, int soft) addr = seg & 0xfff8; dt = (seg & 0x0004) ? &ldt : &gdt; - if ((addr + 7) >= dt->limit) { + if ((addr + 7) > dt->limit) { x86gpf("pmodeint(): Interrupt or trap gate selector > DT limit", seg & 0xfffc); return; } @@ -1535,7 +1538,7 @@ pmodeint(int num, int soft) } addr = newss & 0xfff8; dt = (newss & 0x0004) ? &ldt : &gdt; - if (addr >= dt->limit) { + if ((addr + 7) > dt->limit) { x86ss("pmodeint(): Interrupt or trap gate stack segment > DT", newss & 0xfffc); return; } @@ -1669,7 +1672,7 @@ pmodeint(int num, int soft) seg = segdat[1]; addr = seg & 0xfff8; dt = (seg & 0x0004) ? &ldt : &gdt; - if ((addr + 7) >= dt->limit) { + if ((addr + 7) > dt->limit) { x86gpf("pmodeint(): Task gate selector > DT limit", seg & 0xfffc); return; } @@ -1749,8 +1752,8 @@ pmodeiret(int is32) x86ts("pmodeiret(): Selector points to LDT", seg & 0xfffc); return; } else { - if (addr >= gdt.limit) { - x86ts(NULL,seg&~3); + if ((addr + 7) > gdt.limit) { + x86ts(NULL,seg & 0xfffc); return; } addr += gdt.base; @@ -1842,7 +1845,7 @@ pmodeiret(int is32) addr = seg & 0xfff8; dt = (seg & 0x0004) ? & ldt : &gdt; - if ((addr + 7) >= dt->limit) { + if ((addr + 7) > dt->limit) { ESP = oldsp; x86gpf("pmodeiret(): Selector > DT limit", seg & 0xfffc); return; @@ -1927,7 +1930,7 @@ pmodeiret(int is32) } addr = newss & 0xfff8; dt = (newss & 0x0004) ? &ldt : &gdt; - if ((addr + 7) >= dt->limit) { + if ((addr + 7) > dt->limit) { ESP = oldsp; x86gpf("pmodeiret(): New SS selector > DT limit", newss & 0xfffc); return; @@ -2138,7 +2141,7 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) } addr = new_cs & 0xfff8; dt = (new_cs & 0x0004) ? &ldt : &gdt; - if ((addr + 7) >= dt->limit) { + if ((addr + 7) > dt->limit) { x86ts("taskswitch286(): New CS selector > DT limit", new_cs & 0xfffc); return; } @@ -2300,7 +2303,7 @@ taskswitch286(uint16_t seg, uint16_t *segdat, int is32) } addr = new_cs & 0xfff8; dt = (new_cs & 0x0004) ? &ldt : &gdt; - if ((addr + 7) >= dt->limit) { + if ((addr + 7) > dt->limit) { x86ts(NULL, new_cs & 0xfffc); return; } diff --git a/src/pic.c b/src/pic.c index c2d92a263..01c595f0d 100644 --- a/src/pic.c +++ b/src/pic.c @@ -100,7 +100,7 @@ pic_elcr_read(uint16_t port, void *priv) { pic_t *dev = (pic_t *) priv; - pic_log("ELCR%i: READ %02X\n", port & 1, elcr[port & 1]); + pic_log("ELCR%i: READ %02X\n", port & 1, dev->elcr); return dev->elcr; }