diff --git a/src/cpu/808x.c b/src/cpu/808x.c index c85a75b..b97aef7 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -8,7 +8,7 @@ * * 808x CPU emulation. * - * Version: @(#)808x.c 1.0.10 2019/02/12 + * Version: @(#)808x.c 1.0.11 2019/02/15 * * Authors: Miran Grca, * Andrew Jenner, @@ -56,78 +56,74 @@ /* Misc */ -int use32, stack32; -int oldcpl; +int use32, stack32; +int oldcpl; /* The previous value of the CS segment register. */ -uint16_t oldcs; +uint16_t oldcs; /* The opcode of the instruction currently being executed. */ -uint8_t opcode; +uint8_t opcode; /* The tables to speed up the setting of the Z, N, and P flags. */ -uint8_t znptable8[256]; -uint16_t znptable16[65536]; +uint8_t znptable8[256]; +uint16_t znptable16[65536]; /* A 16-bit zero, needed because some speed-up arrays contain pointers to it. */ -uint16_t zero = 0; +uint16_t zero = 0; /* MOD and R/M stuff. */ -uint16_t *mod1add[2][8]; -uint32_t *mod1seg[8]; -int rmdat; +uint16_t *mod1add[2][8]; +uint32_t *mod1seg[8]; +int rmdat; /* XT CPU multiplier. */ -int xt_cpu_multi; +int xt_cpu_multi; /* Is the CPU 8088 or 8086. */ -int is8086 = 0; +int is8086 = 0; /* Variables for handling the non-maskable interrupts. */ -int nmi = 0, nmi_auto_clear = 0; -int nmi_enable = 1; +int nmi = 0, nmi_auto_clear = 0; +int nmi_enable = 1; /* Was the CPU ever reset? */ -int x86_was_reset = 0; +int x86_was_reset = 0; /* Variables used elsewhere in the emulator. */ -int tempc; +int tempc; -/* Amount of instructions executed - used to calculate the % shown in the title bar. */ -int ins = 0; +/* Number of instructions executed - used to calculate the % shown in the title bar. */ +int ins = 0; /* Is the TRAP flag on? */ -int trap = 0; +int trap = 0; /* The current effective address's segment. */ -uint32_t easeg; - +uint32_t easeg; /* The prefetch queue (4 bytes for 8088, 6 bytes for 8086). */ -static uint8_t pfq[6]; +static uint8_t pfq[6]; /* Variables to aid with the prefetch queue operation. */ -static int fetchcycles = 0; -static int fetchclocks, pfq_pos = 0; +static int fetchcycles = 0, + pfq_pos = 0; /* The IP equivalent of the current prefetch queue position. */ static uint16_t pfq_ip; -/* Where is this even used?! */ -static int nextcyc = 0; - /* Pointer tables needed for segment overrides. */ -static uint32_t *opseg[4]; -static x86seg *_opseg[4]; +static uint32_t *opseg[4]; +static x86seg *_opseg[4]; -static int takeint = 0, noint = 0; -static int in_lock = 0, halt = 0; -static int cpu_alu_op, pfq_size; +static int takeint = 0, noint = 0; +static int in_lock = 0, halt = 0; +static int cpu_alu_op, pfq_size; -static uint16_t cpu_src = 0, cpu_dest = 0; -static uint16_t cpu_data = 0; +static uint16_t cpu_src = 0, cpu_dest = 0; +static uint16_t cpu_data = 0; -static uint32_t *ovr_seg = NULL; +static uint32_t *ovr_seg = NULL; int indump = 0; @@ -190,7 +186,8 @@ static void set_pzs(int bits); static int irq_pending(void) { - if ((nmi && nmi_enable && nmi_mask) || ((flags & I_FLAG) && (pic.pend & ~pic.mask) && !noint)) + if ((nmi && nmi_enable && nmi_mask) || + ((flags & I_FLAG) && (pic.pend & ~pic.mask) && !noint)) return 1; return 0; @@ -198,10 +195,11 @@ irq_pending(void) static void -wait(int c, int bus) +cpu_wait(int c, int bus) { cycles -= c; - if (!bus) + + if (! bus) pfq_add(c); } @@ -209,6 +207,26 @@ wait(int c, int bus) #undef readmemb #undef readmemw + +/* Common read function. */ +static uint8_t +readmemb_common(uint32_t a) +{ + uint8_t ret; + + if (readlookup2 == NULL) + ret = readmembl(a); + else { + if (readlookup2[(a) >> 12] == ((uintptr_t) -1)) + ret = readmembl(a); + else + ret = *(uint8_t *)(readlookup2[(a) >> 12] + (a)); + } + + return ret; +} + + /* Reads a byte from the memory and accounts for memory transfer cycles to subtract from the cycles to use for adding to the prefetch queue. */ static uint8_t @@ -216,16 +234,8 @@ readmemb(uint32_t a) { uint8_t ret; - wait(4, 1); - - if (readlookup2 == NULL) - ret = readmembl(a); - else { - if (readlookup2[(a) >> 12] == -1) - ret = readmembl(a); - else - ret = *(uint8_t *)(readlookup2[(a) >> 12] + (a)); - } + cpu_wait(4, 1); + ret = readmemb_common(a); return ret; } @@ -241,14 +251,7 @@ readmembf(uint32_t a) a = cs + (a & 0xffff); - if (readlookup2 == NULL) - ret = readmembl(a); - else { - if (readlookup2[(a) >> 12] == -1) - ret = readmembl(a); - else - ret = *(uint8_t *)(readlookup2[(a) >> 12] + (a)); - } + ret = readmemb_common(a); return ret; } @@ -256,26 +259,39 @@ readmembf(uint32_t a) /* Reads a word from the memory and accounts for memory transfer cycles to subtract from the cycles to use for adding to the prefetch queue. */ +static uint16_t +readmemw_common(uint32_t s, uint16_t a) +{ + uint16_t ret; + + ret = readmemb_common(s + a); + ret |= readmemb_common(s + ((a + 1) & 0xffff)) << 8; + + return ret; +} + + static uint16_t readmemw(uint32_t s, uint16_t a) { uint16_t ret; - if (!is8086 || (a & 1)) { - ret = readmemb(s + a); - ret |= readmemb(s + ((a + 1) & 0xffff)) << 8; - } else { - wait(4, 1); + if (is8086 && !(a & 1)) + cpu_wait(4, 1); + else + cpu_wait(8, 1); + ret = readmemw_common(s, a); - if (readlookup2 == NULL) - ret = readmemwl(s, a); - else { - if ((readlookup2[((s) + (a)) >> 12] == -1 || (s) == 0xFFFFFFFF)) - ret = readmemwl(s, a); - else - ret = *(uint16_t *)(readlookup2[(s + a) >> 12] + s + a); - } - } + return ret; +} + + +static uint16_t +readmemwf(uint16_t a) +{ + uint16_t ret; + + ret = readmemw_common(cs, a & 0xffff); return ret; } @@ -284,14 +300,12 @@ readmemw(uint32_t s, uint16_t a) /* Writes a byte from the memory and accounts for memory transfer cycles to subtract from the cycles to use for adding to the prefetch queue. */ static void -writememb(uint32_t a, uint8_t v) +writememb_common(uint32_t a, uint8_t v) { - wait(4, 1); - if (writelookup2 == NULL) writemembl(a, v); else { - if (writelookup2[(a) >> 12] == -1) + if (writelookup2[(a) >> 12] == ((uintptr_t) -1)) writemembl(a, v); else *(uint8_t *)(writelookup2[a >> 12] + a) = v; @@ -299,56 +313,92 @@ writememb(uint32_t a, uint8_t v) } +static void +writememb(uint32_t a, uint8_t v) +{ + cpu_wait(4, 1); + + writememb_common(a, v); +} + + /* Writes a word from the memory and accounts for memory transfer cycles to subtract from the cycles to use for adding to the prefetch queue. */ static void writememw(uint32_t s, uint32_t a, uint16_t v) { - if (!is8086 || (a & 1)) { - writememb(s + a, v & 0xff); - writememb(s + ((a + 1) & 0xffff), v >> 8); - } else { - wait(4, 1); + if (is8086 && !(a & 1)) + cpu_wait(4, 1); + else + cpu_wait(8, 1); - if (writelookup2 == NULL) - writememwl(s, a, v); - else { - if ((writelookup2[((s) + (a)) >> 12]== -1) || ((s) == 0xFFFFFFFF)) - writememwl(s, a, v); - else - *(uint16_t *) (writelookup2[(s + a) >> 12] + s + a) = v; - } + writememb_common(s + a, v & 0xff); + writememb_common(s + ((a + 1) & 0xffff), v >> 8); +} + + +static void +pfq_write(void) +{ + uint16_t tempw; + + /* On 8086 and even IP, fetch *TWO* bytes at once. */ + if (pfq_pos < pfq_size) { + /* If we're filling the last byte of the prefetch queue, do *NOT* + read more than one byte even on the 8086. */ + if (is8086 && !(pfq_ip & 1) && !(pfq_pos & 1)) { + tempw = readmemwf(pfq_ip); + *(uint16_t *) &(pfq[pfq_pos]) = tempw; + pfq_ip += 2; + pfq_pos += 2; + } else { + pfq[pfq_pos] = readmembf(pfq_ip); + pfq_ip++; + pfq_pos++; + } } } +static uint8_t +pfq_read(void) +{ + uint8_t temp, i; + + temp = pfq[0]; + + for (i = 0; i < (pfq_size - 1); i++) + pfq[i] = pfq[i + 1]; + pfq_pos--; + + cpu_state.pc++; + + return temp; +} + + /* Fetches a byte from the prefetch queue, or from memory if the queue has been drained. */ static uint8_t pfq_fetchb(void) { - uint8_t temp, i; + uint8_t temp; if (pfq_pos == 0) { - cycles -= (4 - (fetchcycles & 3)); - fetchclocks += (4 - (fetchcycles & 3)); + /* Extra cycles due to having to fetch on read. */ + cpu_wait(4 - (fetchcycles & 3), 1); fetchcycles = 4; - temp = readmembf(cpu_state.pc); - pfq_ip = cpu_state.pc = cpu_state.pc + 1; - if (is8086 && (cpu_state.pc & 1)) { - pfq[0] = readmembf(cpu_state.pc); - pfq_ip++; - pfq_pos++; - } - } else { - temp = pfq[0]; - for (i = 0; i < (pfq_size - 1); i++) - pfq[i] = pfq[i + 1]; - pfq_pos--; + /* Reset prefetch queue internal position. */ + pfq_ip = cpu_state.pc; + /* Fill the queue. */ + pfq_write(); + } else fetchcycles -= 4; - cpu_state.pc++; - } - wait(1, 0); + + /* Fetch. */ + temp = pfq_read(); + cpu_wait(1, 0); + return temp; } @@ -375,16 +425,7 @@ pfq_add(int c) d = c + (fetchcycles & 3); while ((d > 3) && (pfq_pos < pfq_size)) { d -= 4; - if (is8086 && !(pfq_ip & 1)) { - pfq[pfq_pos] = readmembf(pfq_ip); - pfq_ip++; - pfq_pos++; - } - if (pfq_pos < pfq_size) { - pfq[pfq_pos] = readmembf(pfq_ip); - pfq_ip++; - pfq_pos++; - } + pfq_write(); } fetchcycles += c; if (fetchcycles > 16) @@ -392,46 +433,12 @@ pfq_add(int c) } -/* Completes a fetch (called by refreshread()). */ -static void -pfq_complete(void) -{ - if (!(fetchcycles & 3)) - return; - if (pfq_pos >= pfq_size) - return; - if (!pfq_pos) - nextcyc = (4 - (fetchcycles & 3)); - cycles -= (4 - (fetchcycles & 3)); - fetchclocks += (4 - (fetchcycles & 3)); - if (is8086 && !(pfq_ip & 1)) { - pfq[pfq_pos] = readmembf(pfq_ip); - pfq_ip++; - pfq_pos++; - } - if (pfq_pos < pfq_size) { - pfq[pfq_pos] = readmembf(pfq_ip); - pfq_ip++; - pfq_pos++; - } - fetchcycles += (4 - (fetchcycles & 3)); -} - - /* Clear the prefetch queue - called on reset and on anything that affects either CS or IP. */ static void -pfq_clear() +pfq_clear(void) { pfq_ip = cpu_state.pc; pfq_pos = 0; - fetchclocks = 0; -} - - -/* Memory refresh read - called by reads and writes on DMA channel 0. */ -void -refreshread(void) { - pfq_complete(); } @@ -486,22 +493,22 @@ do_mod_rm(void) if (cpu_mod == 3) return; - wait(3, 0); + cpu_wait(3, 0); if (!cpu_mod && (cpu_rm == 6)) { - wait(2, 0); + cpu_wait(2, 0); cpu_state.eaaddr = pfq_fetchw(); easeg = ds; - wait(1, 0); + cpu_wait(1, 0); } else { switch (cpu_rm) { case 0: case 3: - wait(2, 0); + cpu_wait(2, 0); break; case 1: case 2: - wait(3, 0); + cpu_wait(3, 0); break; } @@ -510,15 +517,15 @@ do_mod_rm(void) switch (cpu_mod) { case 1: - wait(4, 0); + cpu_wait(4, 0); cpu_state.eaaddr += (uint16_t) (int8_t) pfq_fetchb(); break; case 2: - wait(4, 0); + cpu_wait(4, 0); cpu_state.eaaddr += pfq_fetchw(); break; } - wait(2, 0); + cpu_wait(2, 0); } cpu_state.eaaddr &= 0xffff; @@ -555,6 +562,7 @@ geteaw(void) { if (cpu_mod == 3) return cpu_state.regs[cpu_rm].w; + return readmemw(easeg, cpu_state.eaaddr); } @@ -569,7 +577,8 @@ read_ea(int memory_only, int bits) cpu_data = readmemb(easeg + cpu_state.eaaddr); return; } - if (!memory_only) { + + if (! memory_only) { if (bits == 8) { cpu_data = getr8(cpu_rm); } else @@ -609,6 +618,7 @@ seteaw(uint16_t val) writememw(easeg, cpu_state.eaaddr, val); } + /* Prepare the ZNP table needed to speed up the setting of the Z, N, and P flags. */ static void makeznptable(void) @@ -638,6 +648,8 @@ makeznptable(void) znptable8[c] = P_FLAG; if (c == 0xb1) DEBUG("znp8 b1 = %i %02X\n", d, znptable8[c]); + if (c == 0x65b1) + DEBUG("znp16 65b1 = %i %02X\n", d, znptable16[c]); if (!c) znptable8[c] |= Z_FLAG; if (c & 0x80) @@ -739,149 +751,158 @@ reset_common(int hard) } -/* Hard reset. */ -void -resetx86(void) -{ - reset_common(1); -} - - -/* Soft reset. */ -void -softresetx86(void) -{ - reset_common(0); -} - - /* Pushes a word to the stack. */ static void -push_ex(uint16_t val) +do_push_ex(uint16_t val) { - writememw(ss, (SP & 0xFFFF), val); + writememw(ss, (SP & 0xffff), val); cpu_state.last_ea = SP; } static void -push(uint16_t val) +do_push(uint16_t val) { SP -= 2; - push_ex(val); + + do_push_ex(val); } /* Pops a word from the stack. */ static uint16_t -pop(void) +do_pop(void) { uint16_t tempw; tempw = readmemw(ss, SP); SP += 2; cpu_state.last_ea = SP; + return tempw; } static void -access(int num, int bits) +do_access(int num, int bits) { switch (num) { case 0: case 61: case 63: case 64: case 67: case 69: case 71: case 72: default: break; + case 1: case 6: case 8: case 9: case 17: case 20: case 21: case 24: case 28: case 55: case 56: - wait(1 + (cycles % 3), 0); + cpu_wait(1 + (cycles % 3), 0); break; + case 2: case 15: case 22: case 23: case 25: case 26: case 46: case 53: - wait(2 + (cycles % 3), 0); + cpu_wait(2 + (cycles % 3), 0); break; + case 3: case 44: case 45: case 52: case 54: - wait(2 + (cycles & 1), 0); + cpu_wait(2 + (cycles & 1), 0); break; + case 4: - wait(5 + (cycles & 1), 0); + cpu_wait(5 + (cycles & 1), 0); break; + case 5: if (opcode == 0xcc) - wait(7 + (cycles % 3), 0); + cpu_wait(7 + (cycles % 3), 0); else - wait(4 + (cycles & 1), 0); + cpu_wait(4 + (cycles & 1), 0); break; + case 7: case 47: case 48: case 49: case 50: case 51: - wait(1 + (cycles % 4), 0); + cpu_wait(1 + (cycles % 4), 0); break; + case 10: case 11: case 18: case 19: case 43: - wait(3 + (cycles % 3), 0); + cpu_wait(3 + (cycles % 3), 0); break; + case 12: case 13: case 14: case 29: case 30: case 33: - wait(4 + (cycles % 3), 0); + cpu_wait(4 + (cycles % 3), 0); break; + case 16: if (!(opcode & 1) && (cycles & 1)) - wait(1, 0); - /* Fall through. */ + cpu_wait(1, 0); + /*FALLTHROUGH*/ + case 42: - wait(3 + (cycles & 1), 0); + cpu_wait(3 + (cycles & 1), 0); break; + case 27: case 32: case 37: - wait(3, 0); + cpu_wait(3, 0); break; + case 31: - wait(6 + (cycles % 3), 0); + cpu_wait(6 + (cycles % 3), 0); break; + case 34: case 39: case 41: case 60: - wait(4, 0); + cpu_wait(4, 0); break; + case 35: - wait(2, 0); + cpu_wait(2, 0); break; + case 36: - wait(5 + (cycles & 1), 0); + cpu_wait(5 + (cycles & 1), 0); if (cpu_mod != 3) - wait(1, 0); + cpu_wait(1, 0); break; + case 38: - wait(5 + (cycles % 3), 0); + cpu_wait(5 + (cycles % 3), 0); break; + case 40: - wait(6, 0); + cpu_wait(6, 0); break; + case 57: if (cpu_mod != 3) - wait(2, 0); - wait(4 + (cycles & 1), 0); + cpu_wait(2, 0); + cpu_wait(4 + (cycles & 1), 0); break; + case 58: if (cpu_mod != 3) - wait(1, 0); - wait(4 + (cycles & 1), 0); + cpu_wait(1, 0); + cpu_wait(4 + (cycles & 1), 0); break; + case 59: if (cpu_mod != 3) - wait(1, 0); - wait(5 + (cycles & 1), 0); + cpu_wait(1, 0); + cpu_wait(5 + (cycles & 1), 0); break; + case 62: - wait(1, 0); + cpu_wait(1, 0); break; + case 65: - wait(3 + (cycles & 1), 0); + cpu_wait(3 + (cycles & 1), 0); if (cpu_mod != 3) - wait(1, 0); + cpu_wait(1, 0); break; + case 70: - wait(5, 0); + cpu_wait(5, 0); break; } } @@ -889,31 +910,31 @@ access(int num, int bits) /* Calls an interrupt. */ static void -interrupt(uint16_t addr, int cli) +do_intr(uint16_t addr, int cli) { uint16_t old_cs, old_ip; uint16_t new_cs, new_ip; addr <<= 2; old_cs = CS; - access(5, 16); + do_access(5, 16); new_ip = readmemw(0, addr); - wait(1, 0); - access(6, 16); + cpu_wait(1, 0); + do_access(6, 16); new_cs = readmemw(0, (addr + 2) & 0xffff); - access(39, 16); - push(flags & 0x0fd7); + do_access(39, 16); + do_push(flags & 0x0fd7); if (cli) flags &= ~I_FLAG; flags &= ~T_FLAG; - access(40, 16); - push(old_cs); + do_access(40, 16); + do_push(old_cs); old_ip = cpu_state.pc; loadcs(new_cs); - access(68, 16); + do_access(68, 16); cpu_state.pc = new_ip; - access(41, 16); - push(old_ip); + do_access(41, 16); + do_push(old_ip); pfq_clear(); } @@ -925,38 +946,45 @@ rep_action(int *completed, int *repeating, int in_rep, int bits) if (in_rep == 0) return 0; - wait(2, 0); + + cpu_wait(2, 0); t = CX; if (irq_pending()) { - access(71, bits); + do_access(71, bits); pfq_clear(); cpu_state.pc = cpu_state.pc - 2; t = 0; } + if (t == 0) { - wait(1, 0); + cpu_wait(1, 0); *completed = 1; *repeating = 0; return 1; } + --CX; *completed = 0; - wait(2, 0); - if (!*repeating) - wait(2, 0); + + cpu_wait(2, 0); + if (! *repeating) + cpu_wait(2, 0); + return 0; } static uint16_t -jump(uint16_t delta) +do_jump(uint16_t delta) { uint16_t old_ip; - access(67, 8); - wait(5, 0); + + do_access(67, 8); + cpu_wait(5, 0); old_ip = cpu_state.pc; cpu_state.pc = (cpu_state.pc + delta) & 0xffff; pfq_clear(); + return old_ip; } @@ -969,30 +997,31 @@ sign_extend(uint8_t data) static void -jump_short(void) +do_jump_short(void) { - jump(sign_extend((uint8_t) cpu_data)); + do_jump(sign_extend((uint8_t) cpu_data)); } static uint16_t -jump_near(void) +do_jump_near(void) { - return jump(pfq_fetchw()); + return do_jump(pfq_fetchw()); } -/* Performs a conditional jump. */ +/* Performs a conditional do_jump. */ static void -jcc(uint8_t opcode, int cond) +do_jcc(uint8_t opcode, int cond) { /* int8_t offset; */ - wait(1, 0); + cpu_wait(1, 0); cpu_data = pfq_fetchb(); - wait(1, 0); - if ((!cond) == (opcode & 0x01)) - jump_short(); + cpu_wait(1, 0); + + if ((! cond) == (opcode & 0x01)) + do_jump_short(); } @@ -1027,7 +1056,7 @@ bitwise(int bits, uint16_t data) static void -test(int bits, uint16_t dest, uint16_t src) +do_test(int bits, uint16_t dest, uint16_t src) { cpu_dest = dest; cpu_src = src; @@ -1089,7 +1118,7 @@ set_apzs(int bits) static void -add(int bits) +do_add(int bits) { int size_mask = (1 << bits) - 1; @@ -1107,7 +1136,7 @@ add(int bits) static void -sub(int bits) +do_sub(int bits) { int size_mask = (1 << bits) - 1; @@ -1131,23 +1160,30 @@ alu_op(int bits) case 1: bitwise(bits, (cpu_dest | cpu_src)); break; + case 2: if (flags & C_FLAG) cpu_src++; - /* Fall through. */ + /*FALLTHROUGH*/ + case 0: - add(bits); + do_add(bits); break; + case 3: if (flags & C_FLAG) cpu_src++; - /* Fall through. */ - case 5: case 7: - sub(bits); + /*FALLTHROUGH*/ + + case 5: + case 7: + do_sub(bits); break; + case 4: - test(bits, cpu_dest, cpu_src); + do_test(bits, cpu_dest, cpu_src); break; + case 6: bitwise(bits, (cpu_dest ^ cpu_src)); break; @@ -1165,7 +1201,7 @@ set_sf(int bits) static void set_pf(void) { - static uint8_t table[0x100] = { + static const uint8_t table[0x100] = { 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0, @@ -1188,7 +1224,7 @@ set_pf(void) static void -mul(uint16_t a, uint16_t b) +do_mul(uint16_t a, uint16_t b) { int negate = 0; int bit_count = 8; @@ -1204,32 +1240,32 @@ mul(uint16_t a, uint16_t b) bit_count = 16; high_bit = 0x8000; } else - wait(8, 0); + cpu_wait(8, 0); size_mask = (1 << bit_count) - 1; if ((rmdat & 0x38) == 0x28) { - if (!top_bit(a, bit_count)) { + if (! top_bit(a, bit_count)) { if (top_bit(b, bit_count)) { - wait(1, 0); + cpu_wait(1, 0); if ((b & size_mask) != ((opcode & 1) ? 0x8000 : 0x80)) - wait(1, 0); + cpu_wait(1, 0); b = ~b + 1; negate = 1; } } else { - wait(1, 0); + cpu_wait(1, 0); a = ~a + 1; negate = 1; if (top_bit(b, bit_count)) { b = ~b + 1; negate = 0; } else - wait(4, 0); + cpu_wait(4, 0); } - wait(10, 0); + cpu_wait(10, 0); } - wait(3, 0); + cpu_wait(3, 0); } c = 0; @@ -1237,13 +1273,13 @@ mul(uint16_t a, uint16_t b) carry = (a & 1) != 0; a >>= 1; for (i = 0; i < bit_count; ++i) { - wait(7, 0); + cpu_wait(7, 0); if (carry) { cpu_src = c; cpu_dest = b; - add(bit_count); + do_add(bit_count); c = cpu_data & size_mask; - wait(1, 0); + cpu_wait(1, 0); carry = !!(flags & C_FLAG); } r = (c >> 1) + (carry ? high_bit : 0); @@ -1253,12 +1289,13 @@ mul(uint16_t a, uint16_t b) carry = (a & 1) != 0; a = r; } + if (negate) { c = ~c; a = (~a + 1) & size_mask; if (a == 0) ++c; - wait(9, 0); + cpu_wait(9, 0); } cpu_data = a; cpu_dest = c; @@ -1294,21 +1331,21 @@ set_pzs(int bits) static void -set_co_mul(int carry) +set_co_do_mul(int carry) { set_cf(carry); set_of(carry); if (!carry) - wait(1, 0); + cpu_wait(1, 0); } static int -div(uint16_t l, uint16_t h) +do_div(uint16_t l, uint16_t h) { int b, bit_count = 8; int negative = 0; - int dividend_negative = 0; + int do_dividend_negative = 0; int size_mask, carry; uint16_t r; @@ -1329,29 +1366,29 @@ div(uint16_t l, uint16_t h) ++h; h &= size_mask; negative = 1; - dividend_negative = 1; - wait(4, 0); + do_dividend_negative = 1; + cpu_wait(4, 0); } if (top_bit(cpu_src, bit_count)) { cpu_src = ~cpu_src + 1; negative = !negative; } else - wait(1, 0); - wait(9, 0); + cpu_wait(1, 0); + cpu_wait(9, 0); } - wait(3, 0); + cpu_wait(3, 0); } - cycles -= 8; + cpu_wait(8, 0); cpu_src &= size_mask; if (h >= cpu_src) { if (opcode != 0xd4) - wait(1, 0); - interrupt(0, 1); + cpu_wait(1, 0); + do_intr(0, 1); return 0; } if (opcode != 0xd4) - wait(1, 0); - wait(2, 0); + cpu_wait(1, 0); + cpu_wait(2, 0); carry = 1; for (b = 0; b < bit_count; ++b) { r = (l << 1) + (carry ? 1 : 0); @@ -1360,35 +1397,35 @@ div(uint16_t l, uint16_t h) r = (h << 1) + (carry ? 1 : 0); carry = top_bit(h, bit_count); h = r; - wait(8, 0); + cpu_wait(8, 0); if (carry) { carry = 0; h -= cpu_src; if (b == bit_count - 1) - wait(2, 0); + cpu_wait(2, 0); } else { carry = cpu_src > h; if (!carry) { h -= cpu_src; - wait(1, 0); + cpu_wait(1, 0); if (b == bit_count - 1) - wait(2, 0); + cpu_wait(2, 0); } } } l = ~((l << 1) + (carry ? 1 : 0)); if (opcode != 0xd4 && (rmdat & 0x38) == 0x38) { - wait(4, 0); + cpu_wait(4, 0); if (top_bit(l, bit_count)) { if (cpu_mod == 3) - wait(1, 0); - interrupt(0, 1); + cpu_wait(1, 0); + do_intr(0, 1); return 0; } - wait(7, 0); + cpu_wait(7, 0); if (negative) l = ~l + 1; - if (dividend_negative) + if (do_dividend_negative) h = ~h + 1; } if (opcode == 0xd4) { @@ -1407,7 +1444,7 @@ div(uint16_t l, uint16_t h) static void -lods(int bits) +do_lods(int bits) { if (bits == 16) cpu_data = readmemw((ovr_seg ? *ovr_seg : ds), SI); @@ -1421,7 +1458,7 @@ lods(int bits) static void -stos(int bits) +do_stos(int bits) { if (bits == 16) writememw(es, DI, cpu_data); @@ -1435,19 +1472,21 @@ stos(int bits) static void -da(void) +do_da(void) { set_pzs(8); - wait(2, 0); + + cpu_wait(2, 0); } static void -aa(void) +do_aa(void) { set_of(0); AL &= 0x0f; - wait(6, 0); + + cpu_wait(6, 0); } @@ -1482,54 +1521,61 @@ execx86(int cycs) while (cycles > 0) { timer_start_period(cycles * xt_cpu_multi); - wait(nextcyc, 0); - nextcyc = 0; - fetchclocks = 0; cpu_state.oldpc = cpu_state.pc; in_rep = repeating = 0; completed = 0; opcodestart: if (halt) { - wait(2, 0); + cpu_wait(2, 0); goto on_halt; } - if (!repeating) { + if (! repeating) { opcode = pfq_fetchb(); oldc = flags & C_FLAG; trap = flags & T_FLAG; - wait(1, 0); + cpu_wait(1, 0); - /* if (!in_rep && !ovr_seg && (CS < 0xf000)) - pclog("%04X:%04X %02X\n", CS, (cpu_state.pc - 1) & 0xFFFF, opcode); */ +#if 0 + if (!in_rep && !ovr_seg && (CS < 0xf000)) + DEBUG("%04X:%04X %02X\n", + CS, (cpu_state.pc - 1) & 0xffff, opcode); +#endif } switch (opcode) { - case 0x06: case 0x0E: case 0x16: case 0x1E: /* PUSH seg */ - access(29, 16); - push(_opseg[(opcode >> 3) & 0x03]->seg); + case 0x06: /* PUSH seg */ + case 0x0e: + case 0x16: + case 0x1e: + do_access(29, 16); + do_push(_opseg[(opcode >> 3) & 0x03]->seg); break; - case 0x07: case 0x0F: case 0x17: case 0x1F: /* POP seg */ - access(22, 16); - if (opcode == 0x0F) { - loadcs(pop()); + + case 0x07: /* POP seg */ + case 0x0f: + case 0x17: + case 0x1f: + do_access(22, 16); + if (opcode == 0x0f) { + loadcs(do_pop()); pfq_clear(); } else - loadseg(pop(), _opseg[(opcode >> 3) & 0x03]); - wait(1, 0); + loadseg(do_pop(), _opseg[(opcode >> 3) & 0x03]); + cpu_wait(1, 0); noint = 1; break; - case 0x26: /*ES:*/ - case 0x2E: /*CS:*/ - case 0x36: /*SS:*/ - case 0x3E: /*DS:*/ - wait(1, 0); + case 0x26: /* ES: */ + case 0x2e: /* CS: */ + case 0x36: /* SS: */ + case 0x3e: /* DS: */ + cpu_wait(1, 0); ovr_seg = opseg[(opcode >> 3) & 0x03]; goto opcodestart; - case 0x00: case 0x01: case 0x02: case 0x03: + case 0x00: case 0x01: case 0x02: case 0x03: /* alu rm, r / r, rm */ case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x10: case 0x11: case 0x12: case 0x13: case 0x18: case 0x19: case 0x1a: case 0x1b: @@ -1537,10 +1583,9 @@ opcodestart: case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x30: case 0x31: case 0x32: case 0x33: case 0x38: case 0x39: case 0x3a: case 0x3b: - /* alu rm, r / r, rm */ bits = 8 << (opcode & 1); do_mod_rm(); - access(46, bits); + do_access(46, bits); if (opcode & 1) tempw = geteaw(); else @@ -1554,36 +1599,35 @@ opcodestart: cpu_src = tempw; } if (cpu_mod != 3) - wait(2, 0); - wait(1, 0); + cpu_wait(2, 0); + cpu_wait(1, 0); alu_op(bits); if (cpu_alu_op != 7) { - if ((opcode & 2) == 0) { - access(10, bits); + if (opcode & 2) { + if (opcode & 1) + cpu_state.regs[cpu_reg].w = cpu_data; + else + setr8(cpu_reg, (uint8_t)(cpu_data & 0xff)); + cpu_wait(1, 0); + } else { + do_access(10, bits); if (opcode & 1) seteaw(cpu_data); else seteab((uint8_t) (cpu_data & 0xff)); if (cpu_mod == 3) - wait(1, 0); - } else { - if (opcode & 1) - cpu_state.regs[cpu_reg].w = cpu_data; - else - setr8(cpu_reg, (uint8_t)(cpu_data & 0xff)); - wait(1, 0); + cpu_wait(1, 0); } } else - wait(1, 0); + cpu_wait(1, 0); break; - case 0x04: case 0x05: case 0x0c: case 0x0d: + case 0x04: case 0x05: case 0x0c: case 0x0d: /* alu A, imm */ case 0x14: case 0x15: case 0x1c: case 0x1d: case 0x24: case 0x25: case 0x2c: case 0x2d: case 0x34: case 0x35: case 0x3c: case 0x3d: - /* alu A, imm */ bits = 8 << (opcode & 1); - wait(1, 0); + cpu_wait(1, 0); if (opcode & 1) { cpu_data = pfq_fetchw(); cpu_dest = AX; @@ -1600,71 +1644,73 @@ opcodestart: else AL = cpu_data & 0xff; } - wait(1, 0); + cpu_wait(1, 0); break; - case 0x27: /*DAA*/ - wait(1, 0); + case 0x27: /* DAA */ + cpu_wait(1, 0); if ((flags & A_FLAG) || (AL & 0x0f) > 9) { cpu_data = AL + 6; - AL = (uint8_t) cpu_data; + AL = (uint8_t)cpu_data; set_af(1); - if ((cpu_data & 0x100) != 0) + if ((cpu_data & 0x0100) != 0) set_cf(1); } if ((flags & C_FLAG) || AL > 0x9f) { AL += 0x60; set_cf(1); } - da(); + do_da(); break; - case 0x2F: /*DAS*/ - wait(1, 0); + + case 0x2f: /* DAS */ + cpu_wait(1, 0); temp = AL; - if ((flags & A_FLAG) || ((AL & 0xf) > 9)) { + if ((flags & A_FLAG) || ((AL & 0x0f) > 9)) { cpu_data = AL - 6; - AL = (uint8_t) cpu_data; + AL = (uint8_t)cpu_data; set_af(1); - if ((cpu_data & 0x100) != 0) + if ((cpu_data & 0x0100) != 0) set_cf(1); } if ((flags & C_FLAG) || temp > 0x9f) { AL -= 0x60; set_cf(1); } - da(); - break; - case 0x37: /*AAA*/ - wait(1, 0); - if ((flags & A_FLAG) || ((AL & 0xf) > 9)) { - AL += 6; - ++AH; - set_ca(); - } else { - clear_ca(); - wait(1, 0); - } - aa(); - break; - case 0x3F: /*AAS*/ - wait(1, 0); - if ((flags & A_FLAG) || ((AL & 0xf) > 9)) { - AL -= 6; - --AH; - set_ca(); - } else { - clear_ca(); - wait(1, 0); - } - aa(); + do_da(); break; - case 0x40: case 0x41: case 0x42: case 0x43: + case 0x37: /* AAA */ + cpu_wait(1, 0); + if ((flags & A_FLAG) || ((AL & 0x0f) > 9)) { + AL += 6; + AH++; + set_ca(); + } else { + clear_ca(); + cpu_wait(1, 0); + } + do_aa(); + break; + + case 0x3f: /* AAS */ + cpu_wait(1, 0); + if ((flags & A_FLAG) || ((AL & 0x0f) > 9)) { + AL -= 6; + AH--; + set_ca(); + } else { + clear_ca(); + cpu_wait(1, 0); + } + do_aa(); + break; + + case 0x40: case 0x41: case 0x42: case 0x43: /* INCDEC rw */ case 0x44: case 0x45: case 0x46: case 0x47: - case 0x48: case 0x49: case 0x4A: case 0x4B: - case 0x4C: case 0x4D: case 0x4E: case 0x4F: - /* INCDEC rw */ - wait(1, 0); + case 0x48: case 0x49: case 0x4a: case 0x4b: + case 0x4c: case 0x4d: case 0x4e: case 0x4f: + cpu_wait(1, 0); cpu_dest = cpu_state.regs[opcode & 7].w; cpu_src = 1; bits = 16; @@ -1680,135 +1726,143 @@ opcodestart: cpu_state.regs[opcode & 7].w = cpu_data; break; - case 0x50: case 0x51: case 0x52: case 0x53: /*PUSH r16*/ + case 0x50: case 0x51: case 0x52: case 0x53: /* PUSH r16 */ case 0x54: case 0x55: case 0x56: case 0x57: - access(30, 16); + do_access(30, 16); if (opcode == 0x54) { SP -= 2; - push_ex(cpu_state.regs[opcode & 0x07].w); + do_push_ex(cpu_state.regs[opcode & 0x07].w); } else - push(cpu_state.regs[opcode & 0x07].w); - break; - case 0x58: case 0x59: case 0x5A: case 0x5B: /*POP r16*/ - case 0x5C: case 0x5D: case 0x5E: case 0x5F: - access(23, 16); - cpu_state.regs[opcode & 0x07].w = pop(); - wait(1, 0); + do_push(cpu_state.regs[opcode & 0x07].w); break; - case 0x60: /*JO alias*/ - case 0x70: /*JO*/ - case 0x61: /*JNO alias*/ - case 0x71: /*JNO*/ - jcc(opcode, flags & V_FLAG); - break; - case 0x62: /*JB alias*/ - case 0x72: /*JB*/ - case 0x63: /*JNB alias*/ - case 0x73: /*JNB*/ - jcc(opcode, flags & C_FLAG); - break; - case 0x64: /*JE alias*/ - case 0x74: /*JE*/ - case 0x65: /*JNE alias*/ - case 0x75: /*JNE*/ - jcc(opcode, flags & Z_FLAG); - break; - case 0x66: /*JBE alias*/ - case 0x76: /*JBE*/ - case 0x67: /*JNBE alias*/ - case 0x77: /*JNBE*/ - jcc(opcode, flags & (C_FLAG | Z_FLAG)); - break; - case 0x68: /*JS alias*/ - case 0x78: /*JS*/ - case 0x69: /*JNS alias*/ - case 0x79: /*JNS*/ - jcc(opcode, flags & N_FLAG); - break; - case 0x6A: /*JP alias*/ - case 0x7A: /*JP*/ - case 0x6B: /*JNP alias*/ - case 0x7B: /*JNP*/ - jcc(opcode, flags & P_FLAG); - break; - case 0x6C: /*JL alias*/ - case 0x7C: /*JL*/ - case 0x6D: /*JNL alias*/ - case 0x7D: /*JNL*/ - temp = (flags & N_FLAG) ? 1 : 0; - temp2 = (flags & V_FLAG) ? 1 : 0; - jcc(opcode, temp ^ temp2); - break; - case 0x6E: /*JLE alias*/ - case 0x7E: /*JLE*/ - case 0x6F: /*JNLE alias*/ - case 0x7F: /*JNLE*/ - temp = (flags & N_FLAG) ? 1 : 0; - temp2 = (flags & V_FLAG) ? 1 : 0; - jcc(opcode, (flags & Z_FLAG) || (temp != temp2)); + case 0x58: case 0x59: case 0x5a: case 0x5b: /* POP r16 */ + case 0x5c: case 0x5d: case 0x5e: case 0x5f: + do_access(23, 16); + cpu_state.regs[opcode & 0x07].w = do_pop(); + cpu_wait(1, 0); break; - case 0x80: case 0x81: case 0x82: case 0x83: - /* alu rm, imm */ + case 0x60: /* JO alias */ + case 0x70: /* JO */ + case 0x61: /* JNO alias */ + case 0x71: /* JNO */ + do_jcc(opcode, flags & V_FLAG); + break; + + case 0x62: /* JB alias */ + case 0x72: /* JB */ + case 0x63: /* JNB alias */ + case 0x73: /* JNB */ + do_jcc(opcode, flags & C_FLAG); + break; + + case 0x64: /* JE alias */ + case 0x74: /* JE */ + case 0x65: /* JNE alias */ + case 0x75: /* JNE */ + do_jcc(opcode, flags & Z_FLAG); + break; + + case 0x66: /* JBE alias */ + case 0x76: /* JBE */ + case 0x67: /* JNBE alias */ + case 0x77: /* JNBE */ + do_jcc(opcode, flags & (C_FLAG | Z_FLAG)); + break; + + case 0x68: /* JS alias */ + case 0x78: /* JS */ + case 0x69: /* JNS alias */ + case 0x79: /* JNS */ + do_jcc(opcode, flags & N_FLAG); + break; + + case 0x6a: /* JP alias */ + case 0x7a: /* JP */ + case 0x6b: /* JNP alias */ + case 0x7b: /* JNP */ + do_jcc(opcode, flags & P_FLAG); + break; + + case 0x6c: /* JL alias */ + case 0x7c: /* JL */ + case 0x6d: /* JNL alias */ + case 0x7d: /* JNL */ + temp = (flags & N_FLAG) ? 1 : 0; + temp2 = (flags & V_FLAG) ? 1 : 0; + do_jcc(opcode, temp ^ temp2); + break; + + case 0x6e: /* JLE alias */ + case 0x7e: /* JLE */ + case 0x6f: /* JNLE alias */ + case 0x7f: /* JNLE */ + temp = (flags & N_FLAG) ? 1 : 0; + temp2 = (flags & V_FLAG) ? 1 : 0; + do_jcc(opcode, (flags & Z_FLAG) || (temp != temp2)); + break; + + case 0x80: case 0x81: case 0x82: case 0x83: /* alu rm, imm */ bits = 8 << (opcode & 1); do_mod_rm(); - access(47, bits); + do_access(47, bits); if (opcode & 1) cpu_data = geteaw(); else cpu_data = geteab(); cpu_dest = cpu_data; if (cpu_mod != 3) - wait(3, 0); + cpu_wait(3, 0); if (opcode == 0x81) { if (cpu_mod == 3) - wait(1, 0); + cpu_wait(1, 0); cpu_src = pfq_fetchw(); } else { if (cpu_mod == 3) - wait(1, 0); + cpu_wait(1, 0); if (opcode == 0x83) cpu_src = sign_extend(pfq_fetchb()); else cpu_src = pfq_fetchb() | 0xff00; } - wait(1, 0); + cpu_wait(1, 0); cpu_alu_op = (rmdat & 0x38) >> 3; alu_op(bits); if (cpu_alu_op != 7) { - access(11, bits); + do_access(11, bits); if (opcode & 1) seteaw(cpu_data); else seteab((uint8_t)(cpu_data & 0xff)); } else { if (cpu_mod != 3) - wait(1, 0); + cpu_wait(1, 0); } break; - case 0x84: case 0x85: - /* TEST rm, reg */ + case 0x84: /* TEST rm, reg */ + case 0x85: bits = 8 << (opcode & 1); do_mod_rm(); - access(48, bits); + do_access(48, bits); if (opcode & 1) { cpu_data = geteaw(); - test(bits, cpu_data, cpu_state.regs[cpu_reg].w); + do_test(bits, cpu_data, cpu_state.regs[cpu_reg].w); } else { cpu_data = geteab(); - test(bits, cpu_data, getr8(cpu_reg)); + do_test(bits, cpu_data, getr8(cpu_reg)); } if (cpu_mod == 3) - wait(2, 0); - wait(2, 0); + cpu_wait(2, 0); + cpu_wait(2, 0); break; - case 0x86: case 0x87: - /* XCHG rm, reg */ + + case 0x86: /* XCHG rm, reg */ + case 0x87: bits = 8 << (opcode & 1); do_mod_rm(); - access(49, bits); + do_access(49, bits); if (opcode & 1) { cpu_data = geteaw(); cpu_src = cpu_state.regs[cpu_reg].w; @@ -1818,252 +1872,269 @@ opcodestart: cpu_src = getr8(cpu_reg); setr8(cpu_reg, (uint8_t)(cpu_data & 0xff)); } - wait(3, 0); - access(12, bits); + cpu_wait(3, 0); + do_access(12, bits); if (opcode & 1) seteaw(cpu_src); else seteab((uint8_t)(cpu_src & 0xff)); break; - case 0x88: case 0x89: - /* MOV rm, reg */ + case 0x88: /* MOV rm, reg */ + case 0x89: bits = 8 << (opcode & 1); do_mod_rm(); - wait(1, 0); - access(13, bits); + cpu_wait(1, 0); + do_access(13, bits); if (opcode & 1) seteaw(cpu_state.regs[cpu_reg].w); else seteab(getr8(cpu_reg)); break; - case 0x8A: case 0x8B: - /* MOV reg, rm */ + + case 0x8a: /* MOV reg, rm */ + case 0x8b: bits = 8 << (opcode & 1); do_mod_rm(); - access(50, bits); + do_access(50, bits); if (opcode & 1) cpu_state.regs[cpu_reg].w = geteaw(); else setr8(cpu_reg, geteab()); - wait(1, 0); + cpu_wait(1, 0); if (cpu_mod != 3) - wait(2, 0); + cpu_wait(2, 0); break; - case 0x8C: /*MOV w,sreg*/ + case 0x8c: /* MOV w,sreg */ do_mod_rm(); if (cpu_mod == 3) - wait(1, 0); - access(14, 16); + cpu_wait(1, 0); + do_access(14, 16); switch (rmdat & 0x38) { - case 0x00: /*ES*/ + case 0x00: /* ES */ seteaw(ES); break; - case 0x08: /*CS*/ + + case 0x08: /* CS */ seteaw(CS); break; - case 0x18: /*DS*/ + + case 0x18: /* DS */ seteaw(DS); break; - case 0x10: /*SS*/ + + case 0x10: /* SS */ seteaw(SS); break; } break; - case 0x8D: /*LEA*/ + case 0x8d: /* LEA */ do_mod_rm(); cpu_state.regs[cpu_reg].w = (cpu_mod == 3) ? cpu_state.last_ea : cpu_state.eaaddr; - wait(1, 0); + cpu_wait(1, 0); if (cpu_mod != 3) - wait(2, 0); + cpu_wait(2, 0); break; - case 0x8E: /*MOV sreg,w*/ + case 0x8e: /* MOV sreg,w */ do_mod_rm(); - access(51, 16); + do_access(51, 16); tempw = geteaw(); switch (rmdat & 0x38) { - case 0x00: /*ES*/ + case 0x00: /* ES */ loadseg(tempw, &_es); break; - case 0x08: /*CS - 8088/8086 only*/ + + case 0x08: /* CS - 8088/8086 only */ loadcs(tempw); pfq_clear(); break; - case 0x18: /*DS*/ + + case 0x18: /* DS */ loadseg(tempw, &_ds); break; - case 0x10: /*SS*/ + + case 0x10: /* SS */ loadseg(tempw, &_ss); break; } - wait(1, 0); + cpu_wait(1, 0); if (cpu_mod != 3) - wait(2, 0); + cpu_wait(2, 0); noint = 1; break; - case 0x8F: /*POPW*/ + case 0x8f: /* POPW */ do_mod_rm(); - wait(1, 0); + cpu_wait(1, 0); cpu_src = cpu_state.eaaddr; - access(24, 16); + do_access(24, 16); if (cpu_mod != 3) - wait(2, 0); - cpu_data = pop(); + cpu_wait(2, 0); + cpu_data = do_pop(); cpu_state.eaaddr = cpu_src; - wait(2, 0); - access(15, 16); + cpu_wait(2, 0); + do_access(15, 16); seteaw(cpu_data); break; - case 0x90: case 0x91: case 0x92: case 0x93: + case 0x90: case 0x91: case 0x92: case 0x93: /* XCHG AX, rw */ case 0x94: case 0x95: case 0x96: case 0x97: - /* XCHG AX, rw */ - wait(1, 0); + cpu_wait(1, 0); cpu_data = cpu_state.regs[opcode & 7].w; cpu_state.regs[opcode & 7].w = AX; AX = cpu_data; - wait(1, 0); + cpu_wait(1, 0); break; - case 0x98: /*CBW*/ - wait(1, 0); + case 0x98: /* CBW */ + cpu_wait(1, 0); AX = sign_extend(AL); break; - case 0x99: /*CWD*/ - wait(4, 0); - if (!top_bit(AX, 16)) - DX = 0; - else { - wait(1, 0); + + case 0x99: /* CWD */ + cpu_wait(4, 0); + if (top_bit(AX, 16)) { + cpu_wait(1, 0); DX = 0xffff; - } + } else + DX = 0; break; - case 0x9A: /*CALL FAR*/ - wait(1, 0); + + case 0x9a: /* CALL FAR */ + cpu_wait(1, 0); new_ip = pfq_fetchw(); - wait(1, 0); + cpu_wait(1, 0); new_cs = pfq_fetchw(); - access(31, 16); - push(CS); - access(60, 16); + do_access(31, 16); + do_push(CS); + do_access(60, 16); cpu_state.oldpc = cpu_state.pc; loadcs(new_cs); cpu_state.pc = new_ip; - access(32, 16); - push(cpu_state.oldpc); + do_access(32, 16); + do_push(cpu_state.oldpc); pfq_clear(); break; - case 0x9B: /*WAIT*/ - cycles -= 4; + + case 0x9b: /* WAIT */ + cpu_wait(4, 0); break; - case 0x9C: /*PUSHF*/ - access(33, 16); - push((flags & 0x0fd7) | 0xf000); + + case 0x9c: /* PUSHF */ + do_access(33, 16); + do_push((flags & 0x0fd7) | 0xf000); break; - case 0x9D: /*POPF*/ - access(25, 16); - flags = pop() | 2; - wait(1, 0); + + case 0x9d: /* POPF */ + do_access(25, 16); + flags = do_pop() | 2; + cpu_wait(1, 0); break; - case 0x9E: /*SAHF*/ - wait(1, 0); + + case 0x9e: /* SAHF */ + cpu_wait(1, 0); flags = (flags & 0xff02) | AH; - wait(2, 0); + cpu_wait(2, 0); break; - case 0x9F: /*LAHF*/ - wait(1, 0); + + case 0x9f: /* LAHF */ + cpu_wait(1, 0); AH = flags & 0xd7; break; - case 0xA0: case 0xA1: - /* MOV A, [iw] */ + case 0xa0: /* MOV A, [iw] */ + case 0xa1: bits = 8 << (opcode & 1); - wait(1, 0); + cpu_wait(1, 0); addr = pfq_fetchw(); - access(1, bits); + do_access(1, bits); if (opcode & 1) AX = readmemw((ovr_seg ? *ovr_seg : ds), addr); else AL = readmemb((ovr_seg ? *ovr_seg : ds) + addr); - wait(1, 0); + cpu_wait(1, 0); break; - case 0xA2: case 0xA3: - /* MOV [iw], A */ + + case 0xa2: /* MOV [iw], A */ + case 0xa3: bits = 8 << (opcode & 1); - wait(1, 0); + cpu_wait(1, 0); addr = pfq_fetchw(); - access(7, bits); + do_access(7, bits); if (opcode & 1) writememw((ovr_seg ? *ovr_seg : ds), addr, AX); else writememb((ovr_seg ? *ovr_seg : ds) + addr, AL); break; - case 0xA4: case 0xA5: /* MOVS */ - case 0xAC: case 0xAD: /* LODS */ + case 0xa4: /* MOVS */ + case 0xa5: + case 0xac: /* LODS */ + case 0xad: bits = 8 << (opcode & 1); - if (!repeating) { - wait(1 /*2*/, 0); + if (! repeating) { + cpu_wait(1 /*2*/, 0); if ((opcode & 8) == 0 && in_rep != 0) - wait(1, 0); + cpu_wait(1, 0); } if (rep_action(&completed, &repeating, in_rep, bits)) { - wait(1, 0); + cpu_wait(1, 0); if ((opcode & 8) != 0) - wait(1, 0); + cpu_wait(1, 0); break; } if (in_rep != 0 && (opcode & 8) != 0) - wait(1, 0); - access(20, bits); - lods(bits); + cpu_wait(1, 0); + do_access(20, bits); + do_lods(bits); if ((opcode & 8) == 0) { - access(27, bits); - stos(bits); + do_access(27, bits); + do_stos(bits); } else { if (opcode & 1) AX = cpu_data; else AL = (uint8_t)(cpu_data & 0xff); if (in_rep != 0) - wait(2, 0); + cpu_wait(2, 0); } if (in_rep == 0) { - wait(3, 0); + cpu_wait(3, 0); if ((opcode & 8) != 0) - wait(1, 0); + cpu_wait(1, 0); break; } repeating = 1; timer_end_period(cycles * xt_cpu_multi); goto opcodestart; - case 0xA6: case 0xA7: /* CMPS */ - case 0xAE: case 0xAF: /* SCAS */ + case 0xa6: /* CMPS */ + case 0xa7: + case 0xae: /* SCAS */ + case 0xaf: bits = 8 << (opcode & 1); - if (!repeating) - wait(1, 0); + if (! repeating) + cpu_wait(1, 0); if (rep_action(&completed, &repeating, in_rep, bits)) { - wait(2, 0); + cpu_wait(2, 0); break; } if (in_rep != 0) - wait(1, 0); + cpu_wait(1, 0); if (opcode & 1) cpu_dest = AX; else cpu_dest = AL; if ((opcode & 8) == 0) { - access(21, bits); - lods(bits); - wait(1, 0); + do_access(21, bits); + do_lods(bits); + cpu_wait(1, 0); cpu_dest = cpu_data; } - access(2, bits); + do_access(2, bits); if (opcode & 1) cpu_data = readmemw(es, DI); else @@ -2073,188 +2144,209 @@ opcodestart: else DI += (bits >> 3); cpu_src = cpu_data; - sub(bits); - wait(2, 0); + do_sub(bits); + cpu_wait(2, 0); if (in_rep == 0) { - wait(3, 0); + cpu_wait(3, 0); break; } if ((!!(flags & Z_FLAG)) == (in_rep == 1)) { - wait(4, 0); + cpu_wait(4, 0); break; } repeating = 1; timer_end_period(cycles * xt_cpu_multi); goto opcodestart; - case 0xA8: case 0xA9: - /* TEST A, imm */ + case 0xa8: /* TEST A, imm */ + case 0xa9: bits = 8 << (opcode & 1); - wait(1, 0); + cpu_wait(1, 0); if (opcode & 1) { cpu_data = pfq_fetchw(); - test(bits, AX, cpu_data); + do_test(bits, AX, cpu_data); } else { cpu_data = pfq_fetchb(); - test(bits, AL, cpu_data); + do_test(bits, AL, cpu_data); } - wait(1, 0); + cpu_wait(1, 0); break; - case 0xAA: case 0xAB: /* STOS */ + case 0xaa: /* STOS */ + case 0xab: bits = 8 << (opcode & 1); - if (!repeating) { + if (! repeating) { if (opcode & 1) - wait(1, 0); + cpu_wait(1, 0); if (in_rep != 0) - wait(1, 0); + cpu_wait(1, 0); } if (rep_action(&completed, &repeating, in_rep, bits)) { - wait(1, 0); + cpu_wait(1, 0); break; } cpu_data = AX; - access(28, bits); - stos(bits); + do_access(28, bits); + do_stos(bits); if (in_rep == 0) { - wait(3, 0); + cpu_wait(3, 0); break; } repeating = 1; timer_end_period(cycles * xt_cpu_multi); goto opcodestart; - case 0xB0: case 0xB1: case 0xB2: case 0xB3: /*MOV cpu_reg,#8*/ - case 0xB4: case 0xB5: case 0xB6: case 0xB7: - wait(1, 0); + case 0xb0: /* MOV cpu_reg,#8 */ + case 0xb1: + case 0xb2: + case 0xb3: + case 0xb4: + case 0xb5: + case 0xb6: + case 0xb7: + cpu_wait(1, 0); if (opcode & 0x04) cpu_state.regs[opcode & 0x03].b.h = pfq_fetchb(); else cpu_state.regs[opcode & 0x03].b.l = pfq_fetchb(); - wait(1, 0); + cpu_wait(1, 0); break; - case 0xB8: case 0xB9: case 0xBA: case 0xBB: /*MOV cpu_reg,#16*/ - case 0xBC: case 0xBD: case 0xBE: case 0xBF: - wait(1, 0); + case 0xb8: /* MOV cpu_reg,#16 */ + case 0xb9: + case 0xba: + case 0xbb: + case 0xbc: + case 0xbd: + case 0xbe: + case 0xbf: + cpu_wait(1, 0); cpu_state.regs[opcode & 0x07].w = pfq_fetchw(); - wait(1, 0); + cpu_wait(1, 0); break; - case 0xC0: case 0xC1: case 0xC2: case 0xC3: - case 0xC8: case 0xC9: case 0xCA: case 0xCB: - /* RET */ + case 0xc0: /* RET */ + case 0xc1: + case 0xc2: + case 0xc3: + case 0xc8: + case 0xc9: + case 0xca: + case 0xcb: bits = 8 + (opcode & 0x08); if ((opcode & 9) != 1) - wait(1, 0); - if (!(opcode & 1)) { + cpu_wait(1, 0); + if (! (opcode & 1)) { cpu_src = pfq_fetchw(); - wait(1, 0); + cpu_wait(1, 0); } if ((opcode & 9) == 9) - wait(1, 0); - access(26, bits); - new_ip = pop(); - wait(2, 0); - if ((opcode & 8) == 0) - new_cs = CS; - else { - access(42, bits); - new_cs = pop(); + cpu_wait(1, 0); + do_access(26, bits); + new_ip = do_pop(); + cpu_wait(2, 0); + if (opcode & 8) { + do_access(42, bits); + new_cs = do_pop(); if (opcode & 1) - wait(1, 0); - } - if (!(opcode & 1)) { + cpu_wait(1, 0); + } else + new_cs = CS; + if (! (opcode & 1)) { SP += cpu_src; - wait(1, 0); + cpu_wait(1, 0); } loadcs(new_cs); - access(72, bits); + do_access(72, bits); cpu_state.pc = new_ip; pfq_clear(); break; - case 0xC4: case 0xC5: - /* LsS rw, rmd */ + case 0xc4: /* LSS rw, rmd */ + case 0xc5: do_mod_rm(); bits = 16; - access(52, bits); + do_access(52, bits); cpu_state.regs[cpu_reg].w = readmemw(easeg, cpu_state.eaaddr); tempw = readmemw(easeg, (cpu_state.eaaddr + 2) & 0xFFFF); loadseg(tempw, (opcode & 0x01) ? &_ds : &_es); - wait(1, 0); + cpu_wait(1, 0); noint = 1; break; - case 0xC6: case 0xC7: - /* MOV rm, imm */ + case 0xc6: /* MOV rm, imm */ + case 0xc7: bits = 8 << (opcode & 1); do_mod_rm(); - wait(1, 0); + cpu_wait(1, 0); if (cpu_mod != 3) - wait(2, 0); + cpu_wait(2, 0); if (opcode & 1) cpu_data = pfq_fetchw(); else cpu_data = pfq_fetchb(); if (cpu_mod == 3) - wait(1, 0); - access(16, bits); + cpu_wait(1, 0); + do_access(16, bits); if (opcode & 1) seteaw(cpu_data); else seteab((uint8_t)(cpu_data & 0xff)); break; - case 0xCC: /*INT 3*/ - interrupt(3, 1); + case 0xcc: /* INT 3 */ + do_intr(3, 1); break; - case 0xCD: /*INT*/ - wait(1, 0); - interrupt(pfq_fetchb(), 1); + + case 0xcd: /* INT */ + cpu_wait(1, 0); + do_intr(pfq_fetchb(), 1); break; - case 0xCE: /*INTO*/ - wait(3, 0); + + case 0xce: /* INTO */ + cpu_wait(3, 0); if (flags & V_FLAG) { - wait(2, 0); - interrupt(4, 1); + cpu_wait(2, 0); + do_intr(4, 1); } break; - case 0xCF: /*IRET*/ - access(43, 8); - new_ip = pop(); - wait(3, 0); - access(44, 8); - new_cs = pop(); + case 0xcf: /* IRET */ + do_access(43, 8); + new_ip = do_pop(); + cpu_wait(3, 0); + do_access(44, 8); + new_cs = do_pop(); loadcs(new_cs); - access(62, 8); + do_access(62, 8); cpu_state.pc = new_ip; - access(45, 8); - flags = pop() | 2; - wait(5, 0); + do_access(45, 8); + flags = do_pop() | 2; + cpu_wait(5, 0); noint = 1; nmi_enable = 1; pfq_clear(); break; - case 0xD0: case 0xD1: case 0xD2: case 0xD3: - /* rot rm */ + case 0xd0: /* rot rm */ + case 0xd1: + case 0xd2: + case 0xd3: bits = 8 << (opcode & 1); do_mod_rm(); if (cpu_mod == 3) - wait(1, 0); - access(53, bits); + cpu_wait(1, 0); + do_access(53, bits); if (opcode & 1) cpu_data = geteaw(); else cpu_data = geteab(); - if ((opcode & 2) == 0) { - cpu_src = 1; - wait((cpu_mod != 3) ? 4 : 0, 0); - } else { + if (opcode & 2) { cpu_src = CL; - wait((cpu_mod != 3) ? 9 : 6, 0); + cpu_wait((cpu_mod != 3) ? 9 : 6, 0); + } else { + cpu_src = 1; + cpu_wait((cpu_mod != 3) ? 4 : 0, 0); } while (cpu_src != 0) { cpu_dest = cpu_data; @@ -2266,6 +2358,7 @@ opcodestart: cpu_data |= ((flags & C_FLAG) ? 1 : 0); set_of_rotate(bits); break; + case 0x08: /* ROR */ set_cf((cpu_data & 1) != 0); cpu_data >>= 1; @@ -2273,11 +2366,13 @@ opcodestart: cpu_data |= (!(opcode & 1) ? 0x80 : 0x8000); set_of_rotate(bits); break; + case 0x10: /* RCL */ set_cf(top_bit(cpu_data, bits)); cpu_data = (cpu_data << 1) | (oldc ? 1 : 0); set_of_rotate(bits); break; + case 0x18: /* RCR */ set_cf((cpu_data & 1) != 0); cpu_data >>= 1; @@ -2286,12 +2381,14 @@ opcodestart: set_cf((cpu_dest & 1) != 0); set_of_rotate(bits); break; + case 0x20: /* SHL */ set_cf(top_bit(cpu_data, bits)); cpu_data <<= 1; set_of_rotate(bits); set_pzs(bits); break; + case 0x28: /* SHR */ set_cf((cpu_data & 1) != 0); cpu_data >>= 1; @@ -2299,6 +2396,7 @@ opcodestart: set_af(1); set_pzs(bits); break; + case 0x30: /* SETMO - undocumented? */ bitwise(bits, 0xffff); set_cf(0); @@ -2306,6 +2404,7 @@ opcodestart: set_af(0); set_pzs(bits); break; + case 0x38: /* SAR */ set_cf((cpu_data & 1) != 0); cpu_data >>= 1; @@ -2319,68 +2418,79 @@ opcodestart: break; } if ((opcode & 2) != 0) - wait(4, 0); - --cpu_src; + cpu_wait(4, 0); + cpu_src--; } - access(17, bits); + do_access(17, bits); if (opcode & 1) seteaw(cpu_data); else seteab((uint8_t)(cpu_data & 0xff)); break; - case 0xD4: /*AAM*/ - wait(1, 0); + case 0xd4: /* AAM */ + cpu_wait(1, 0); cpu_src = pfq_fetchb(); - if (div(AL, 0)) + if (do_div(AL, 0)) set_pzs(16); break; - case 0xD5: /*AAD*/ - wait(1, 0); - mul(pfq_fetchb(), AH); + + case 0xd5: /* AAD */ + cpu_wait(1, 0); + do_mul(pfq_fetchb(), AH); AL += cpu_data; AH = 0x00; set_pzs(16); break; - case 0xD6: /*SALC*/ - wait(1, 0); + + case 0xd6: /* SALC */ + cpu_wait(1, 0); AL = (flags & C_FLAG) ? 0xff : 0x00; - wait(1, 0); + cpu_wait(1, 0); break; - case 0xD7: /*XLATB*/ + + case 0xd7: /* XLATB */ addr = BX + AL; cpu_state.last_ea = addr; - access(4, 8); + do_access(4, 8); AL = readmemb((ovr_seg ? *ovr_seg : ds) + addr); - wait(1, 0); + cpu_wait(1, 0); break; - case 0xD8: case 0xD9: case 0xDA: case 0xDB: - case 0xDD: case 0xDC: case 0xDE: case 0xDF: - /* esc i, r, rm */ + case 0xd8: /* esc i, r, rm */ + case 0xd9: + case 0xda: + case 0xdb: + case 0xdd: + case 0xdc: + case 0xde: + case 0xdf: do_mod_rm(); - access(54, 16); + do_access(54, 16); geteaw(); - wait(1, 0); + cpu_wait(1, 0); if (cpu_mod != 3) - wait(2, 0); + cpu_wait(2, 0); break; - case 0xE0: case 0xE1: case 0xE2: case 0xE3: - /* LOOP */ - wait(3, 0); + case 0xe0: /* LOOP */ + case 0xe1: + case 0xe2: + case 0xe3: + cpu_wait(3, 0); cpu_data = pfq_fetchb(); if (opcode != 0xe2) - wait(1, 0); + cpu_wait(1, 0); if (opcode != 0xe3) { - --CX; + CX--; oldc = (CX != 0); switch (opcode) { - case 0xE0: + case 0xe0: if (flags & Z_FLAG) oldc = 0; break; - case 0xE1: + + case 0xe1: if (!(flags & Z_FLAG)) oldc = 0; break; @@ -2388,189 +2498,206 @@ opcodestart: } else oldc = (CX == 0); if (oldc) - jump_short(); + do_jump_short(); break; - case 0xE4: case 0xE5: case 0xE6: case 0xE7: - case 0xEC: case 0xED: case 0xEE: case 0xEF: + case 0xe4: + case 0xe5: + case 0xe6: + case 0xe7: + case 0xec: + case 0xed: + case 0xee: + case 0xef: bits = 8 << (opcode & 1); if ((opcode & 0x0e) != 0x0c) - wait(1, 0); - if ((opcode & 8) == 0) - cpu_data = pfq_fetchb(); - else + cpu_wait(1, 0); + if (opcode & 8) cpu_data = DX; - if ((opcode & 2) == 0) { - access(3, bits); - if ((opcode & 1) && is8086) { - AX = inw(cpu_data); - wait(4, 1); /* I/O access and wait state. */ - } else { - AL = inb(cpu_data); - if (opcode & 1) - AH = inb(temp + 1); - wait(bits >> 1, 1); /* I/O access. */ - } - wait(1, 0); - } else { - if ((opcode & 8) == 0) - access(8, bits); + else + cpu_data = pfq_fetchb(); + if (opcode & 2) { + if (opcode & 8) + do_access(9, bits); else - access(9, bits); - if ((opcode & 1) && is8086) { + do_access(8, bits); + if ((opcode & 1) && is8086 && !(cpu_data & 1)) { outw(cpu_data, AX); - wait(4, 1); + cpu_wait(4, 1); } else { outb(cpu_data, AL); if (opcode & 1) outb(cpu_data + 1, AH); - wait(bits >> 1, 1); /* I/O access. */ + cpu_wait(bits >> 1, 1); /* I/O do_access. */ } + } else { + do_access(3, bits); + if ((opcode & 1) && is8086 && !(cpu_data & 1)) { + AX = inw(cpu_data); + cpu_wait(4, 1); /* I/O do_access and cpu_wait state. */ + } else { + AL = inb(cpu_data); + if (opcode & 1) + AH = inb(temp + 1); + cpu_wait(bits >> 1, 1); /* I/O do_access. */ + } + cpu_wait(1, 0); } break; - case 0xE8: /*CALL rel 16*/ - wait(1, 0); - cpu_state.oldpc = jump_near(); - access(34, 8); - push(cpu_state.oldpc); + case 0xe8: /* CALL rel 16 */ + cpu_wait(1, 0); + cpu_state.oldpc = do_jump_near(); + do_access(34, 8); + do_push(cpu_state.oldpc); pfq_clear(); break; - case 0xE9: /*JMP rel 16*/ - wait(1, 0); - jump_near(); + + case 0xe9: /* JMP rel 16 */ + cpu_wait(1, 0); + do_jump_near(); break; - case 0xEA: /*JMP far*/ - wait(1, 0); + + case 0xea: /* JMP far */ + cpu_wait(1, 0); addr = pfq_fetchw(); - wait(1, 0); + cpu_wait(1, 0); tempw = pfq_fetchw(); loadcs(tempw); - access(70, 8); + do_access(70, 8); cpu_state.pc = addr; pfq_clear(); break; - case 0xEB: /*JMP rel*/ - wait(1, 0); + + case 0xeb: /* JMP rel */ + cpu_wait(1, 0); cpu_data = (int8_t) pfq_fetchb(); - jump_short(); - wait(1, 0); + do_jump_short(); + cpu_wait(1, 0); pfq_clear(); break; - case 0xF0: case 0xF1: /*LOCK - F1 is alias*/ + case 0xf0: /* LOCK - F1 is alias */ + case 0xf1: in_lock = 1; - wait(1, 0); + cpu_wait(1, 0); goto opcodestart; - case 0xF2: /*REPNE*/ - case 0xF3: /*REPE*/ - wait(1, 0); + case 0xf2: /* REPNE */ + case 0xf3: /* REPE */ + cpu_wait(1, 0); in_rep = (opcode == 0xf2 ? 1 : 2); repeating = 0; completed = 0; goto opcodestart; - case 0xF4: /*HLT*/ + case 0xf4: /* HLT */ halt = 1; pfq_clear(); - wait(2, 0); + cpu_wait(2, 0); break; - case 0xF5: /*CMC*/ - wait(1, 0); + + case 0xf5: /* CMC */ + cpu_wait(1, 0); flags ^= C_FLAG; break; - case 0xF6: case 0xF7: + case 0xf6: + case 0xf7: bits = 8 << (opcode & 1); do_mod_rm(); - access(55, bits); + do_access(55, bits); if (opcode & 1) cpu_data = geteaw(); else cpu_data = geteab(); switch (rmdat & 0x38) { - case 0x00: case 0x08: - /* TEST */ - wait(2, 0); + case 0x00: /* TEST */ + case 0x08: + cpu_wait(2, 0); if (cpu_mod != 3) - wait(1, 0); + cpu_wait(1, 0); if (opcode & 1) cpu_src = pfq_fetchw(); else cpu_src = pfq_fetchb(); - wait(1, 0); - test(bits, cpu_data, cpu_src); + cpu_wait(1, 0); + do_test(bits, cpu_data, cpu_src); if (cpu_mod != 3) - wait(1, 0); + cpu_wait(1, 0); break; + case 0x10: /* NOT */ case 0x18: /* NEG */ - wait(2, 0); + cpu_wait(2, 0); if ((rmdat & 0x38) == 0x10) cpu_data = ~cpu_data; else { cpu_src = cpu_data; cpu_dest = 0; - sub(bits); + do_sub(bits); } - access(18, bits); + do_access(18, bits); if (opcode & 1) seteaw(cpu_data); else seteab((uint8_t)(cpu_data & 0xff)); break; + case 0x20: /* MUL */ case 0x28: /* IMUL */ - wait(1, 0); + cpu_wait(1, 0); if (opcode & 1) { - mul(AX, cpu_data); + do_mul(AX, cpu_data); AX = cpu_data; DX = cpu_dest; cpu_data |= DX; - set_co_mul((DX != ((AX & 0x8000) == 0) || ((rmdat & 0x38) == 0x20) ? 0 : 0xffff)); + set_co_do_mul((DX != ((AX & 0x8000) == 0) || ((rmdat & 0x38) == 0x20) ? 0 : 0xffff)); } else { - mul(AL, cpu_data); - AL = (uint8_t) cpu_data; - AH = (uint8_t) cpu_dest; - set_co_mul(AH != (((AL & 0x80) == 0) || ((rmdat & 0x38) == 0x20) ? 0 : 0xff)); + do_mul(AL, cpu_data); + AL = (uint8_t)cpu_data; + AH = (uint8_t)cpu_dest; + set_co_do_mul(AH != (((AL & 0x80) == 0) || ((rmdat & 0x38) == 0x20) ? 0 : 0xff)); } set_zf(bits); if (cpu_mod != 3) - wait(1, 0); + cpu_wait(1, 0); break; + case 0x30: /* DIV */ case 0x38: /* IDIV */ if (cpu_mod != 3) - wait(1, 0); + cpu_wait(1, 0); cpu_src = cpu_data; - if (div(AL, AH)) - wait(1, 0); + if (do_div(AL, AH)) + cpu_wait(1, 0); break; } break; - case 0xF8: case 0xF9: - /* CLCSTC */ - wait(1, 0); + case 0xf8: /* CLCSTC */ + case 0xf9: + cpu_wait(1, 0); set_cf(opcode & 1); break; - case 0xFA: case 0xFB: - /* CLISTI */ - wait(1, 0); + + case 0xfa: /* CLISTI */ + case 0xfb: + cpu_wait(1, 0); set_if(opcode & 1); break; - case 0xFC: case 0xFD: - /* CLDSTD */ - wait(1, 0); + + case 0xfc: /* CLDSTD */ + case 0xfd: + cpu_wait(1, 0); set_df(opcode & 1); break; - case 0xFE: case 0xFF: - /* misc */ + case 0xfe: /* misc */ + case 0xff: bits = 8 << (opcode & 1); do_mod_rm(); - access(56, bits); + do_access(56, bits); read_ea(((rmdat & 0x38) == 0x18) || ((rmdat & 0x38) == 0x28), bits); switch (rmdat & 0x38) { case 0x00: /* INC rm */ @@ -2586,94 +2713,99 @@ opcodestart: } do_af(); set_pzs(bits); - wait(2, 0); - access(19, bits); + cpu_wait(2, 0); + do_access(19, bits); if (opcode & 1) seteaw(cpu_data); else seteab((uint8_t)(cpu_data & 0xff)); break; + case 0x10: /* CALL rm */ - if (!(opcode & 1)) { + if (! (opcode & 1)) { if (cpu_mod != 3) cpu_data |= 0xff00; else cpu_data = cpu_state.regs[cpu_rm].w; } - access(63, bits); - wait(5, 0); + do_access(63, bits); + cpu_wait(5, 0); if (cpu_mod != 3) - wait(1, 0); - wait(1, 0); /* Wait. */ + cpu_wait(1, 0); + cpu_wait(1, 0); cpu_state.oldpc = cpu_state.pc; cpu_state.pc = cpu_data; - wait(2, 0); - access(35, bits); - push(cpu_state.oldpc); + cpu_wait(2, 0); + do_access(35, bits); + do_push(cpu_state.oldpc); pfq_clear(); break; + case 0x18: /* CALL rmd */ new_ip = cpu_data; - access(58, bits); + do_access(58, bits); read_ea2(bits); - if (!(opcode & 1)) + if (! (opcode & 1)) cpu_data |= 0xff00; new_cs = cpu_data; - access(36, bits); - push(CS); - access(64, bits); - wait(4, 0); + do_access(36, bits); + do_push(CS); + do_access(64, bits); + cpu_wait(4, 0); cpu_state.oldpc = cpu_state.pc; loadcs(new_cs); cpu_state.pc = new_ip; - access(37, bits); - push(cpu_state.oldpc); + do_access(37, bits); + do_push(cpu_state.oldpc); pfq_clear(); break; + case 0x20: /* JMP rm */ - if (!(opcode & 1)) { + if (! (opcode & 1)) { if (cpu_mod != 3) cpu_data |= 0xff00; else cpu_data = cpu_state.regs[cpu_rm].w; } - access(65, bits); + do_access(65, bits); cpu_state.pc = cpu_data; pfq_clear(); break; + case 0x28: /* JMP rmd */ new_ip = cpu_data; - access(59, bits); + do_access(59, bits); read_ea2(bits); - if (!(opcode & 1)) + if (! (opcode & 1)) cpu_data |= 0xff00; new_cs = cpu_data; loadcs(new_cs); - access(66, bits); + do_access(66, bits); cpu_state.pc = new_ip; pfq_clear(); break; + case 0x30: /* PUSH rm */ case 0x38: if (cpu_mod != 3) - wait(1, 0); - access(38, bits); + cpu_wait(1, 0); + do_access(38, bits); if ((cpu_mod == 3) && (cpu_rm == 4)) - push(cpu_data - 2); + do_push(cpu_data - 2); else - push(cpu_data); + do_push(cpu_data); break; } break; default: - ERRLOG("CPU: illegal opcode: %02X\n", opcode); + ERRLOG("CPU: illegal opcode: %02x\n", opcode); pfq_fetchb(); - wait(8, 0); + cpu_wait(8, 0); break; } - cpu_state.pc &= 0xFFFF; + cpu_state.pc &= 0xffff; on_halt: if (ovr_seg) @@ -2686,16 +2818,16 @@ on_halt: if (trap && (flags & T_FLAG) && !noint) { halt = 0; - interrupt(1, 1); + do_intr(1, 1); } else if (nmi && nmi_enable && nmi_mask) { halt = 0; - interrupt(2, 1); + do_intr(2, 1); nmi_enable = 0; } else if (takeint && !noint) { temp = picinterrupt(); if (temp != 0xFF) { halt = 0; - interrupt(temp, 1); + do_intr(temp, 1); } } takeint = (flags & I_FLAG) && (pic.pend &~ pic.mask); @@ -2706,3 +2838,49 @@ on_halt: ins++; } } + + +/* Memory refresh read - called by reads and writes on DMA channel 0. */ +void +refreshread(void) +{ + if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed > 4772728) + cpu_wait(8, 1); /* insert extra wait states */ + + /* + * Do the actual refresh stuff. + * + * If there is no extra cycles left to consume, return. + */ + if (! (fetchcycles & 3)) + return; + + /* If the prefetch queue is full, return. */ + if (pfq_pos >= pfq_size) + return; + + /* Subtract from 1 to 8 cycles. */ + cpu_wait(8 - (fetchcycles % 7), 1); + + /* Write to the prefetch queue. */ + pfq_write(); + + /* Add those cycles to fetchcycles. */ + fetchcycles += (4 - (fetchcycles & 3)); +} + + +/* Hard reset. */ +void +resetx86(void) +{ + reset_common(1); +} + + +/* Soft reset. */ +void +softresetx86(void) +{ + reset_common(0); +} diff --git a/src/devices/input/keyboard_xt.c b/src/devices/input/keyboard_xt.c index 5c4c463..6d0d6e7 100644 --- a/src/devices/input/keyboard_xt.c +++ b/src/devices/input/keyboard_xt.c @@ -8,7 +8,7 @@ * * Implementation of the XT-style keyboard. * - * Version: @(#)keyboard_xt.c 1.0.13 2019/02/12 + * Version: @(#)keyboard_xt.c 1.0.14 2019/02/14 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -54,6 +54,7 @@ #include "../sound/sound.h" #include "../sound/snd_speaker.h" #include "../video/video.h" +#include #include "keyboard.h" @@ -482,21 +483,10 @@ kbd_write(uint16_t port, uint8_t val, void *priv) speaker_enable = val & 2; if (kbd->type <= KBC_PC82) { - /* - * Cassette Port present. - * - * Normally, the PC BIOS will disable the - * PC Speaker when doing cassette I/O, as - * they share the same hardware. - * - * For us, it is more fun to actually have - * that audio, so we do some tricks here. - */ - if (! (val & 0x08)) { - /* PB3, MotorOn - enable audio */ - speaker_gated = 1; - speaker_enable = 1; - } +#ifdef USE_CASSETTE + if (cassette_enabled) + cassette_motor(! (val & 0x08)); +#endif } if (speaker_enable) diff --git a/src/devices/system/pit.c b/src/devices/system/pit.c index a22727e..03ea6ac 100644 --- a/src/devices/system/pit.c +++ b/src/devices/system/pit.c @@ -13,7 +13,7 @@ * B4 to 40, two writes to 43, then two reads * - value _does_ change! * - * Version: @(#)pit.c 1.0.9 2019/02/12 + * Version: @(#)pit.c 1.0.10 2019/02/14 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -54,6 +54,9 @@ #include "../../timer.h" #include "../sound/sound.h" #include "../sound/snd_speaker.h" +#ifdef USE_CASSETTE +# include +#endif #include "../video/video.h" #include "nmi.h" #include "dma.h" @@ -403,6 +406,13 @@ pit_write(uint16_t addr, uint8_t val, void *priv) case 2: t = addr & 3; switch (dev->wm[t]) { + case 0: + dev->l[t] &= 0xff; + dev->l[t] |= (val << 8); + pit_load(dev, t); + dev->wm[t] = 3; + break; + case 1: dev->l[t] = val; pit_load(dev, t); @@ -413,17 +423,15 @@ pit_write(uint16_t addr, uint8_t val, void *priv) pit_load(dev, t); break; - case 0: - dev->l[t] &= 0xff; - dev->l[t] |= (val << 8); - pit_load(dev, t); - dev->wm[t] = 3; - break; - case 3: dev->l[t] &= 0xff00; dev->l[t] |= val; dev->wm[t] = 0; +#ifdef USE_CASSETTE + if (t == 2) { + cassette_write(dev->l[t]); + } +#endif break; }