From c1f18d9abc9b578cd3bdfa5c8284db375bc438b2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 11 Feb 2019 01:33:15 +0100 Subject: [PATCH] More 808x fixed - fixed (kind of) the 8086 lock ups and the DRAM refresh wait states, also further fixed (and cleaned up) prefetch queue operation, applied a few warning fixes, and fixed the behavior of PUSH SP - anything that uses it to tell 808x apart from 286 is now fixed; Re-added the higher-clocked 8088's; Fixed PIT timings for 808x CPU's that don't run off an 14.3 MHz crystal; Fixed CGA cursor half blink rate setting - fixes insane cursor blinking speed in several cases; DMA now issues DMA refresh DRAM states on every channel; Gave the 1982 years to the previously emulated PC and XT's names, and added the 1981 IBM PC and 1986 IBM XT; Redid the PPI DIP switch redout for the PC/XT keyboard controller; Fixed a segmentation fault in hdc_ide.c that tended to occur on hard reset after switching machines; Implemented the port 3B8 color disable on the Hercules, Hercules Plus, and Hercules InColor cards; Fixed the joystick configuration dialog strings; Fixed a problem that would have prevented win_sdl.c from compiling with logging enabled. --- src/cpu/808x.c | 348 +++++++++++++++++++---------------- src/cpu/cpu.h | 1 + src/cpu/cpu_table.c | 11 +- src/disk/hdc_ide.c | 5 +- src/dma.c | 6 +- src/keyboard.h | 10 +- src/keyboard_xt.c | 147 ++++++++++++--- src/machine/m_xt.c | 40 +++- src/machine/machine.h | 5 +- src/machine/machine_table.c | 16 +- src/pc.c | 55 +----- src/pit.c | 129 ++++++++----- src/rom.c | 42 ++++- src/rom.h | 8 +- src/sound/snd_opl.c | 8 +- src/video/vid_cga.c | 15 +- src/video/vid_hercules.c | 53 ++++-- src/video/vid_herculesplus.c | 27 ++- src/video/vid_incolor.c | 31 +++- src/win/win_joystick.cpp | 8 +- src/win/win_sdl.c | 5 +- 21 files changed, 611 insertions(+), 359 deletions(-) diff --git a/src/cpu/808x.c b/src/cpu/808x.c index 859a98acf..dd5b08a6b 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -80,15 +80,11 @@ uint32_t easeg; 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]; @@ -196,6 +192,24 @@ 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 @@ -204,15 +218,7 @@ 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)); - } + ret = readmemb_common(a); return ret; } @@ -227,15 +233,7 @@ readmembf(uint32_t a) uint8_t ret; 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; } @@ -244,41 +242,53 @@ 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(uint32_t s, uint16_t a) +readmemw_common(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 (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); - } - } + 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)) + wait(4, 1); + else + wait(8, 1); + ret = readmemw_common(s, a); + + return ret; +} + + +static uint16_t +readmemwf(uint16_t a) +{ + uint16_t ret; + + ret = readmemw_common(cs, a & 0xffff); + + return ret; +} + + + /* 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; @@ -286,55 +296,85 @@ writememb(uint32_t a, uint8_t v) } +static void +writememb(uint32_t a, uint8_t v) +{ + 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)) + wait(4, 1); + else + wait(8, 1); + writememb_common(s + a, v & 0xff); + writememb_common(s + ((a + 1) & 0xffff), v >> 8); +} - 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; - } + +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. */ + 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++; - } + + /* Fetch. */ + temp = pfq_read(); wait(1, 0); return temp; } @@ -362,16 +402,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) @@ -379,46 +410,34 @@ 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_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(); + if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed > 4772728) + wait(8, 1); /* Insert extra wait states. */ + + /* Do the actual refresh stuff. */ + /* If there's 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. */ + wait(8 - (fetchcycles % 7), 1); + /* Write to the prefetch queue. */ + pfq_write(); + /* Add those cycles to fetchcycles. */ + fetchcycles += (4 - (fetchcycles & 3)); } @@ -516,12 +535,21 @@ do_mod_rm(void) } +#undef getr8 +#define getr8(r) ((r & 4) ? cpu_state.regs[r & 3].b.h : cpu_state.regs[r & 3].b.l) + +#undef setr8 +#define setr8(r,v) if (r & 4) cpu_state.regs[r & 3].b.h = v; \ + else cpu_state.regs[r & 3].b.l = v; + + /* Reads a byte from the effective address. */ static uint8_t geteab(void) { - if (cpu_mod == 3) - return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm & 3].b.l; + if (cpu_mod == 3) { + return (getr8(cpu_rm)); + } return readmemb(easeg + cpu_state.eaaddr); } @@ -548,9 +576,9 @@ read_ea(int memory_only, int bits) return; } if (!memory_only) { - if (bits == 8) - cpu_data = (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm & 3].b.l; - else + if (bits == 8) { + cpu_data = getr8(cpu_rm); + } else cpu_data = cpu_state.regs[cpu_rm].w; } } @@ -571,10 +599,7 @@ static void seteab(uint8_t val) { if (cpu_mod == 3) { - if (cpu_rm & 4) - cpu_state.regs[cpu_rm & 3].b.h = val; - else - cpu_state.regs[cpu_rm & 3].b.l = val; + setr8(cpu_rm, val); } else writememb(easeg + cpu_state.eaaddr, val); } @@ -590,14 +615,6 @@ seteaw(uint16_t val) writememw(easeg, cpu_state.eaaddr, val); } -#undef getr8 -#define getr8(r) ((r & 4) ? cpu_state.regs[r & 3].b.h : cpu_state.regs[r & 3].b.l) - -#undef setr8 -#define setr8(r,v) if (r & 4) cpu_state.regs[r & 3].b.h = v; \ - else cpu_state.regs[r & 3].b.l = v; - - /* Prepare the ZNP table needed to speed up the setting of the Z, N, and P flags. */ static void makeznptable(void) @@ -625,8 +642,10 @@ makeznptable(void) znptable8[c] = 0; else znptable8[c] = P_FLAG; +#ifdef ENABLE_808X_LOG if (c == 0xb1) x808x_log("znp8 b1 = %i %02X\n", d, znptable8[c]); +#endif if (!c) znptable8[c] |= Z_FLAG; if (c & 0x80) @@ -655,10 +674,12 @@ makeznptable(void) znptable16[c] = 0; else znptable16[c] = P_FLAG; +#ifdef ENABLE_808X_LOG if (c == 0xb1) x808x_log("znp16 b1 = %i %02X\n", d, znptable16[c]); if (c == 0x65b1) x808x_log("znp16 65b1 = %i %02X\n", d, znptable16[c]); +#endif if (!c) znptable16[c] |= Z_FLAG; if (c & 0x8000) @@ -672,7 +693,9 @@ static void reset_common(int hard) { if (hard) { +#ifdef ENABLE_808X_LOG x808x_log("x86 reset\n"); +#endif ins = 0; } use32 = 0; @@ -745,12 +768,19 @@ softresetx86(void) /* Pushes a word to the stack. */ +static void +push_ex(uint16_t val) +{ + writememw(ss, (SP & 0xFFFF), val); + cpu_state.last_ea = SP; +} + + static void push(uint16_t val) { - writememw(ss, ((SP - 2) & 0xFFFF), val); SP -= 2; - cpu_state.last_ea = SP; + push_ex(val); } @@ -1323,7 +1353,7 @@ div(uint16_t l, uint16_t h) } wait(3, 0); } - cycles -= 8; + wait(8, 0); cpu_src &= size_mask; if (h >= cpu_src) { if (opcode != 0xd4) @@ -1408,7 +1438,7 @@ stos(int bits) if (bits == 16) writememw(es, DI, cpu_data); else - writememb(es + DI, cpu_data); + writememb(es + DI, (uint8_t) (cpu_data & 0xff)); if (flags & D_FLAG) DI -= (bits >> 3); else @@ -1464,9 +1494,6 @@ 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; @@ -1482,10 +1509,10 @@ opcodestart: oldc = flags & C_FLAG; trap = flags & T_FLAG; wait(1, 0); - } - /* if ((CS >= 0xc800) && (CS <= 0xcfff)) - pclog("%04X:%04X %02X (%04X)\n", CS, cpu_state.pc, opcode, flags); */ + /* if (!in_rep && !ovr_seg && (CS < 0xf000)) + pclog("%04X:%04X %02X\n", CS, (cpu_state.pc - 1) & 0xFFFF, opcode); */ + } switch (opcode) { case 0x06: case 0x0E: case 0x16: case 0x1E: /* PUSH seg */ @@ -1545,14 +1572,14 @@ opcodestart: if (opcode & 1) seteaw(cpu_data); else - seteab(cpu_data); + 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, cpu_data); + setr8(cpu_reg, (uint8_t) (cpu_data & 0xff)); wait(1, 0); } } else @@ -1580,7 +1607,7 @@ opcodestart: if (opcode & 1) AX = cpu_data; else - AL = cpu_data & 0xff; + AL = (uint8_t) (cpu_data & 0xff); } wait(1, 0); break; @@ -1665,7 +1692,11 @@ opcodestart: case 0x50: case 0x51: case 0x52: case 0x53: /*PUSH r16*/ case 0x54: case 0x55: case 0x56: case 0x57: access(30, 16); - push(cpu_state.regs[opcode & 0x07].w); + if (opcode == 0x54) { + SP -= 2; + 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: @@ -1759,7 +1790,7 @@ opcodestart: if (opcode & 1) seteaw(cpu_data); else - seteab(cpu_data); + seteab((uint8_t) (cpu_data & 0xff)); } else { if (cpu_mod != 3) wait(1, 0); @@ -1801,7 +1832,7 @@ opcodestart: if (opcode & 1) seteaw(cpu_src); else - seteab(cpu_src); + seteab((uint8_t) (cpu_src & 0xff)); break; case 0x88: case 0x89: @@ -1813,7 +1844,7 @@ opcodestart: if (opcode & 1) seteaw(cpu_state.regs[cpu_reg].w); else - seteab(getr8(cpu_reg)); + seteab(getr8((uint8_t) (cpu_reg & 0xff))); break; case 0x8A: case 0x8B: /* MOV reg, rm */ @@ -1936,8 +1967,7 @@ opcodestart: pfq_clear(); break; case 0x9B: /*WAIT*/ - pclog("PCem: %02X\n", opcode); - cycles -= 4; + wait(4, 0); break; case 0x9C: /*PUSHF*/ access(33, 16); @@ -2007,7 +2037,7 @@ opcodestart: if (opcode & 1) AX = cpu_data; else - AL = cpu_data; + AL = (uint8_t) (cpu_data & 0xff); if (in_rep != 0) wait(2, 0); } @@ -2182,7 +2212,7 @@ opcodestart: if (opcode & 1) seteaw(cpu_data); else - seteab(cpu_data); + seteab((uint8_t) (cpu_data & 0xff)); break; case 0xCC: /*INT 3*/ @@ -2305,7 +2335,7 @@ opcodestart: if (opcode & 1) seteaw(cpu_data); else - seteab(cpu_data); + seteab((uint8_t) (cpu_data & 0xff)); break; case 0xD4: /*AAM*/ @@ -2381,7 +2411,7 @@ opcodestart: cpu_data = DX; if ((opcode & 2) == 0) { access(3, bits); - if ((opcode & 1) && is8086) { + if ((opcode & 1) && is8086 && !(cpu_data & 1)) { AX = inw(cpu_data); wait(4, 1); /* I/O access and wait state. */ } else { @@ -2396,7 +2426,7 @@ opcodestart: access(8, bits); else access(9, bits); - if ((opcode & 1) && is8086) { + if ((opcode & 1) && is8086 && !(cpu_data & 1)) { outw(cpu_data, AX); wait(4, 1); } else { @@ -2497,7 +2527,7 @@ opcodestart: if (opcode & 1) seteaw(cpu_data); else - seteab(cpu_data); + seteab((uint8_t) (cpu_data & 0xff)); break; case 0x20: /* MUL */ case 0x28: /* IMUL */ @@ -2550,7 +2580,7 @@ opcodestart: bits = 8 << (opcode & 1); do_mod_rm(); access(56, bits); - read_ea((rmdat & 0x38) == 0x18 || (rmdat & 0x38) == 0x28, bits); + read_ea(((rmdat & 0x38) == 0x18) || ((rmdat & 0x38) == 0x28), bits); switch (rmdat & 0x38) { case 0x00: /* INC rm */ case 0x08: /* DEC rm */ @@ -2570,7 +2600,7 @@ opcodestart: if (opcode & 1) seteaw(cpu_data); else - seteab(cpu_data); + seteab((uint8_t) (cpu_data & 0xff)); break; case 0x10: /* CALL rm */ if (!(opcode & 1)) { @@ -2637,7 +2667,10 @@ opcodestart: if (cpu_mod != 3) wait(1, 0); access(38, bits); - push(cpu_data); + if ((cpu_mod == 3) && (cpu_rm == 4)) + push(cpu_data - 2); + else + push(cpu_data); break; } break; @@ -2659,7 +2692,8 @@ on_halt: in_lock = 0; /* FIXME: Find out why this is needed. */ - if ((romset == ROM_IBMPC) && ((cs + cpu_state.pc) == 0xFE4A7)) { + if (((romset == ROM_IBMPC) && ((cs + cpu_state.pc) == 0xFE545)) || + ((romset == ROM_IBMPC82) && ((cs + cpu_state.pc) == 0xFE4A7))) { /* You didn't seriously think I was going to emulate the cassette, did you? */ CX = 1; BX = 0x500; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 11a7808a4..56e0ddf9c 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -71,6 +71,7 @@ #define CPU_SUPPORTS_DYNAREC 1 #define CPU_REQUIRES_DYNAREC 2 +#define CPU_ALTERNATE_XTAL 4 typedef struct { diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index a1050bd33..a61e05349 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -55,6 +55,9 @@ CPU cpus_8088[] = { {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"8088/7.16", CPU_8088, 1, 7159092, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"8088/8", CPU_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/10", CPU_8088, 1, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/12", CPU_8088, 1, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/16", CPU_8088, 1, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0} }; @@ -66,17 +69,17 @@ CPU cpus_pcjr[] = { CPU cpus_europc[] = { /*8088 EuroPC*/ - {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8088/7.16", CPU_8088, 1, 7159092, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, + {"8088/7.16", CPU_8088, 1, 7159092, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, {"8088/9.54", CPU_8088, 1, 9545456, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0} }; CPU cpus_8086[] = { /*8086 standard*/ - {"8086/7.16", CPU_8086, 1, 7159092, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/7.16", CPU_8086, 1, 7159092, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, {"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8086/9.54", CPU_8086, 1, 9545456, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, + {"8086/9.54", CPU_8086, 1, 9545456, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, {"8086/10", CPU_8086, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, {"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0} }; diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 72dea91e5..3ff2c3ea4 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -9,7 +9,7 @@ * Implementation of the IDE emulation for hard disks and ATAPI * CD-ROM devices. * - * Version: @(#)hdc_ide.c 1.0.59 2018/11/09 + * Version: @(#)hdc_ide.c 1.0.60 2019/02/10 * * Authors: Sarah Walker, * Miran Grca, @@ -2439,6 +2439,9 @@ ide_set_handlers(uint8_t board) static void ide_remove_handlers(uint8_t board) { + if (!ide_boards[board]) + return; + if (ide_boards[board]->bit32) { io_removehandler(ide_base_main[board], 1, ide_readb, ide_readw, ide_readl, diff --git a/src/dma.c b/src/dma.c index a9a4389f4..6f9bfea8a 100644 --- a/src/dma.c +++ b/src/dma.c @@ -8,7 +8,7 @@ * * Implementation of the Intel DMA controllers. * - * Version: @(#)dma.c 1.0.4 2018/11/18 + * Version: @(#)dma.c 1.0.5 2019/02/07 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -659,7 +659,7 @@ dma_channel_read(int channel) if ((dma_c->mode & 0xC) != 8) return(DMA_NODATA); - if ((!AT) && !channel) + if (!AT) refreshread(); if (! dma_c->size) { @@ -730,7 +730,7 @@ dma_channel_write(int channel, uint16_t val) if ((dma_c->mode & 0xC) != 4) return(DMA_NODATA); - if ((!AT) && !channel) + if (!AT) refreshread(); if (! dma_c->size) { diff --git a/src/keyboard.h b/src/keyboard.h index 8b501dc56..bda91929a 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -8,15 +8,15 @@ * * Definitions for the keyboard interface. * - * Version: @(#)keyboard.h 1.0.16 2018/09/15 + * Version: @(#)keyboard.h 1.0.17 2019/02/08 * * Authors: Sarah Walker, * Miran Grca, * Fred N. van Kempen, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + * Copyright 2017-2019 Fred N. van Kempen. */ #ifndef EMU_KEYBOARD_H # define EMU_KEYBOARD_H @@ -61,7 +61,9 @@ extern int mouse_scan; #ifdef EMU_DEVICE_H extern const device_t keyboard_pc_device; +extern const device_t keyboard_pc82_device; extern const device_t keyboard_xt_device; +extern const device_t keyboard_xt86_device; extern const device_t keyboard_tandy_device; #if defined(DEV_BRANCH) && defined(USE_LASERXT) extern const device_t keyboard_xt_lxt3_device; diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index b1fb90c1d..3e4637ac4 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -24,6 +24,7 @@ #include #include #include "86box.h" +#include "floppy/fdd.h" #include "machine/machine.h" #include "io.h" #include "pic.h" @@ -54,8 +55,7 @@ typedef struct { int blocked; int tandy; - uint8_t pa; - uint8_t pb; + uint8_t pa, pb, pd; uint8_t key_waiting; uint8_t type; } xtkbd_t; @@ -472,14 +472,9 @@ kbd_read(uint16_t port, void *priv) switch (port) { case 0x60: - if (!kbd->type && (kbd->pb & 0x80)) { - if (video_is_ega_vga()) - ret = 0x4d; - else if (video_is_mda()) - ret = 0x7d; - else - ret = 0x6d; - } else if ((kbd->type == 1) && (kbd->pb & 0x80)) + if ((kbd->type <= 1) && (kbd->pb & 0x80)) + ret = kbd->pd; + else if (((kbd->type == 2) || (kbd->type == 3)) && (kbd->pb & 0x80)) ret = 0xff; /* According to Ruud on the PCem forum, this is supposed to return 0xFF on the XT. */ else ret = kbd->pa; @@ -490,39 +485,37 @@ kbd_read(uint16_t port, void *priv) break; case 0x62: - if (!kbd->type) { + if (!kbd->type) + ret = 0x00; + else if (kbd->type == 1) { if (kbd->pb & 0x04) ret = ((mem_size-64) / 32) & 0x0f; else ret = ((mem_size-64) / 32) >> 4; } else { - if (kbd->pb & 0x08) { - if (video_is_ega_vga()) - ret = 0x4; - else if (video_is_mda()) - ret = 0x7; - else - ret = 0x6; - } else { + if (kbd->pb & 0x08) + ret = kbd->pd >> 4; + else { /* LaserXT = Always 512k RAM; LaserXT/3 = Bit 0: set = 512k, clear = 256k. */ #if defined(DEV_BRANCH) && defined(USE_LASERXT) - if (kbd->type == 3) + if (kbd->type == 5) ret = (mem_size == 512) ? 0x0d : 0x0c; else #endif - ret = 0x0d; + ret = kbd->pd & 0x0f; } } ret |= (ppispeakon ? 0x20 : 0); - if (kbd->type == 2) + if (kbd->type == 4) ret |= (tandy1k_eeprom_read() ? 0x10 : 0); break; - default: - pclog("XTkbd: bad read %04X\n", port); - ret = 0xff; + case 0x63: + if ((kbd->type == 2) || (kbd->type == 3)) + ret = kbd->pd; + break; } return(ret); @@ -549,6 +542,8 @@ kbd_reset(void *priv) static void * kbd_init(const device_t *info) { + int i, fdd_count = 0; + xtkbd_t *kbd; kbd = (xtkbd_t *)malloc(sizeof(xtkbd_t)); @@ -560,6 +555,78 @@ kbd_init(const device_t *info) kbd_reset(kbd); kbd->type = info->local; + if (kbd->type <= 3) { + for (i = 0; i < FDD_NUM; i++) { + if (fdd_get_flags(i)) + fdd_count++; + } + + /* DIP switch readout: bit set = OFF, clear = ON. */ + /* Switches 7, 8 - floppy drives. */ + if (!fdd_count) + kbd->pd = 0x00; + else + kbd->pd = ((fdd_count - 1) << 6) | 0x01; + /* Switches 5, 6 - video. */ + if (video_is_mda()) + kbd->pd |= 0x30; + else + kbd->pd |= 0x20; /* 0x10 would be 40x25 */ + /* Switches 3, 4 - memory size. */ + if (kbd->type == 3) { + switch (mem_size) { + case 256: + kbd->pd |= 0x00; + break; + case 512: + kbd->pd |= 0x04; + break; + case 576: + kbd->pd |= 0x08; + break; + case 640: + default: + kbd->pd |= 0x0c; + break; + } + } else if (kbd->type == 2) { + switch (mem_size) { + case 64: + kbd->pd |= 0x00; + break; + case 128: + kbd->pd |= 0x04; + break; + case 192: + kbd->pd |= 0x08; + break; + case 256: + default: + kbd->pd |= 0x0c; + break; + } + } else { + switch (mem_size) { + case 16: + kbd->pd |= 0x00; + break; + case 32: + kbd->pd |= 0x04; + break; + case 48: + kbd->pd |= 0x08; + break; + case 64: + default: + kbd->pd |= 0x0c; + break; + } + } + /* Switch 2 - return bit clear (switch ON) because no 8087 right now. */ + /* Switch 1 - always off. */ + kbd->pd |= 0x01; + } + timer_add(kbd_poll, &keyboard_delay, TIMER_ALWAYS_ENABLED, kbd); keyboard_set_table(scancode_xt); @@ -589,7 +656,7 @@ kbd_close(void *priv) const device_t keyboard_pc_device = { - "IBM PC Keyboard", + "IBM PC Keyboard (1981)", 0, 0, kbd_init, @@ -598,8 +665,8 @@ const device_t keyboard_pc_device = { NULL, NULL, NULL }; -const device_t keyboard_xt_device = { - "XT Keyboard", +const device_t keyboard_pc82_device = { + "IBM PC Keyboard (1982)", 0, 1, kbd_init, @@ -608,10 +675,30 @@ const device_t keyboard_xt_device = { NULL, NULL, NULL }; +const device_t keyboard_xt_device = { + "XT (1982) Keyboard", + 0, + 2, + kbd_init, + kbd_close, + kbd_reset, + NULL, NULL, NULL +}; + +const device_t keyboard_xt86_device = { + "XT (1986) Keyboard", + 0, + 3, + kbd_init, + kbd_close, + kbd_reset, + NULL, NULL, NULL +}; + const device_t keyboard_tandy_device = { "Tandy 1000 Keyboard", 0, - 2, + 4, kbd_init, kbd_close, kbd_reset, @@ -622,7 +709,7 @@ const device_t keyboard_tandy_device = { const device_t keyboard_xt_lxt3_device = { "VTech Laser XT3 Keyboard", 0, - 3, + /*5*/ 3, kbd_init, kbd_close, kbd_reset, diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 4d8261ab7..06ede7582 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -14,14 +14,13 @@ #include "machine.h" -void -machine_pc_init(const machine_t *model) +static void +machine_xt_common_init(const machine_t *model) { machine_common_init(model); pit_set_out_func(&pit, 1, pit_refresh_timer_xt); - device_add(&keyboard_pc_device); device_add(&fdc_xt_device); nmi_init(); if (joystick_type != 7) @@ -29,16 +28,37 @@ machine_pc_init(const machine_t *model) } +void +machine_pc_init(const machine_t *model) +{ + machine_xt_common_init(model); + + device_add(&keyboard_pc_device); +} + + +void +machine_pc82_init(const machine_t *model) +{ + machine_xt_common_init(model); + + device_add(&keyboard_pc82_device); +} + + void machine_xt_init(const machine_t *model) { - machine_common_init(model); - - pit_set_out_func(&pit, 1, pit_refresh_timer_xt); + machine_xt_common_init(model); device_add(&keyboard_xt_device); - device_add(&fdc_xt_device); - nmi_init(); - if (joystick_type != 7) - device_add(&gameport_device); +} + + +void +machine_xt86_init(const machine_t *model) +{ + machine_xt_common_init(model); + + device_add(&keyboard_xt86_device); } diff --git a/src/machine/machine.h b/src/machine/machine.h index 5d6c0a017..3d2e6c3a0 100644 --- a/src/machine/machine.h +++ b/src/machine/machine.h @@ -8,7 +8,7 @@ * * Handling of the emulated machines. * - * Version: @(#)machine.h 1.0.32 2019/01/13 + * Version: @(#)machine.h 1.0.33 2019/02/08 * * Authors: Sarah Walker, * Miran Grca, @@ -151,6 +151,8 @@ extern void machine_at_r418_init(const machine_t *); extern void machine_at_wd76c10_init(const machine_t *); extern void machine_pc_init(const machine_t *); +extern void machine_pc82_init(const machine_t *); + extern void machine_pcjr_init(const machine_t *); extern void machine_ps1_m2011_init(const machine_t *); @@ -186,6 +188,7 @@ extern void machine_tandy1k_init(const machine_t *); extern int tandy1k_eeprom_read(void); extern void machine_xt_init(const machine_t *); +extern void machine_xt86_init(const machine_t *); extern void machine_xt_compaq_init(const machine_t *); #if defined(DEV_BRANCH) && defined(USE_LASERXT) extern void machine_xt_laserxt_init(const machine_t *); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index f19b9bd67..d95791c94 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11,7 +11,7 @@ * NOTES: OpenAT wip for 286-class machine with open BIOS. * PS2_M80-486 wip, pending receipt of TRM's for machine. * - * Version: @(#)machine_table.c 1.0.45 2019/01/13 + * Version: @(#)machine_table.c 1.0.46 2019/02/08 * * Authors: Sarah Walker, * Miran Grca, @@ -37,18 +37,20 @@ const machine_t machines[] = { { "[8088] AMI XT clone", ROM_AMIXT, "amixt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL }, { "[8088] Compaq Portable", ROM_PORTABLE, "portable", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_xt_compaq_init, NULL }, { "[8088] DTK XT clone", ROM_DTKXT, "dtk", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL }, - { "[8088] IBM PC", ROM_IBMPC, "ibmpc", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 32, 0, machine_pc_init, NULL }, + { "[8088] IBM PC (1981)", ROM_IBMPC, "ibmpc", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 16, 64, 16, 0, machine_pc_init, NULL }, + { "[8088] IBM PC (1982)", ROM_IBMPC82, "ibmpc82", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 256, 64, 0, machine_pc82_init, NULL }, { "[8088] IBM PCjr", ROM_IBMPCJR, "ibmpcjr", {{"Intel", cpus_pcjr}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_VIDEO, 128, 640, 128, 0, machine_pcjr_init, pcjr_get_device }, - { "[8088] IBM XT", ROM_IBMXT, "ibmxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL }, + { "[8088] IBM XT (1982)", ROM_IBMXT, "ibmxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 256, 64, 0, machine_xt_init, NULL }, + { "[8088] IBM XT (1986)", ROM_IBMXT86, "ibmxt86", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 256, 640, 64, 0, machine_xt86_init, NULL }, { "[8088] Generic XT clone", ROM_GENXT, "genxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL }, { "[8088] Juko XT clone", ROM_JUKOPC, "jukopc", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL }, { "[8088] Phoenix XT clone", ROM_PXXT, "pxxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 64, 640, 64, 0, machine_xt_init, NULL }, { "[8088] Schneider EuroPC", ROM_EUROPC, "europc", {{"Siemens", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_HDC | MACHINE_MOUSE, 512, 640, 128, 15, machine_europc_init, NULL }, - { "[8088] Tandy 1000", ROM_TANDY, "tandy", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 128, 640, 128, 0, machine_tandy1k_init, tandy1k_get_device }, - { "[8088] Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 256, 640, 128, 0, machine_tandy1k_init, tandy1k_hx_get_device }, + { "[8088] Tandy 1000", ROM_TANDY, "tandy", {{"Intel", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 128, 640, 128, 0, machine_tandy1k_init, tandy1k_get_device }, + { "[8088] Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", {{"Intel", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 256, 640, 128, 0, machine_tandy1k_init, tandy1k_hx_get_device }, { "[8088] Toshiba T1000", ROM_T1000, "t1000", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO, 512, 1280, 768, 63, machine_xt_t1000_init, t1000_get_device }, #if defined(DEV_BRANCH) && defined(USE_LASERXT) - { "[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 512, 512, 256, 0, machine_xt_laserxt_init, NULL }, + { "[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 256, 640, 256, 0, machine_xt_laserxt_init, NULL }, #endif { "[8088] Xi8088", ROM_XI8088, "xi8088", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 64, 1024, 128, 127, machine_xt_xi8088_init, NULL }, { "[8088] Zenith Data SupersPort", ROM_ZD_SUPERS, "zdsupers", {{"Intel", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 128, 640, 128, 0, machine_xt_zenith_init, NULL }, @@ -62,7 +64,7 @@ const machine_t machines[] = { { "[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA, 512, 768, 128, 0, machine_tandy1k_init, NULL }, { "[8086] Toshiba T1200", ROM_T1200, "t1200", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_VIDEO, 1024, 2048,1024, 63, machine_xt_t1200_init, t1200_get_device }, #if defined(DEV_BRANCH) && defined(USE_LASERXT) - { "[8086] VTech Laser XT3", ROM_LXT3, "lxt3", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 256, 512, 256, 0, machine_xt_lxt3_init, NULL }, + { "[8086] VTech Laser XT3", ROM_LXT3, "lxt3", {{"Intel", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA, 256, 640, 256, 0, machine_xt_lxt3_init, NULL }, #endif { "[286 ISA] AMI 286 clone", ROM_AMI286, "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,8192, 128, 127, machine_at_neat_ami_init, NULL }, diff --git a/src/pc.c b/src/pc.c index baa1a97df..a1aa9a5a1 100644 --- a/src/pc.c +++ b/src/pc.c @@ -513,10 +513,7 @@ pc_full_speed(void) if (! atfullspeed) { pc_log("Set fullspeed - %i %i %i\n", is386, AT, cpuspeed2); - if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_286) - setpitclock(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed); - else - setpitclock(14318184.0); + setpitclock(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed); } atfullspeed = 1; @@ -527,54 +524,12 @@ pc_full_speed(void) void pc_speed_changed(void) { - if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_286) - setpitclock(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed); - else - setpitclock(14318184.0); + setpitclock(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed); nvr_period_recalc(); } -#if 0 -/* Re-load system configuration and restart. */ -/* FIXME: this has to be reviewed! */ -void -pc_reload(wchar_t *fn) -{ - int i; - - config_write(cfg_path); - - for (i=0; i= CPU_286) - setpitclock(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed); - else - setpitclock(14318184.0); + setpitclock(machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed); } diff --git a/src/pit.c b/src/pit.c index 65c435cf1..99e0e97b6 100644 --- a/src/pit.c +++ b/src/pit.c @@ -30,7 +30,7 @@ int64_t displine; PIT pit, pit2; float cpuclock; -float isa_timing, bus_timing; +float /*isa_timing, */bus_timing; double PITCONST; float CGACONST; @@ -42,49 +42,68 @@ float RTCCONST; int64_t firsttime=1; void setrtcconst(float clock) { - RTCCONST=clock/32768.0; - TIMER_USEC = (int64_t)((clock / 1000000.0f) * (float)(1 << TIMER_SHIFT)); + /* Set default CPU/crystal clock and xt_cpu_multi. */ + cpuclock = 14318184.0; + if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_286) { + cpuclock = clock; + PITCONST=cpuclock/1193182.0; + CGACONST=(cpuclock/(19687503.0/11.0)); + xt_cpu_multi = 1; + } else { + PITCONST=12.0; + CGACONST=8.0; + xt_cpu_multi = 3; + switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed) { + case 7159092: + if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_flags & CPU_ALTERNATE_XTAL) { + cpuclock = 28636368.0; + xt_cpu_multi = 4; + } else + xt_cpu_multi = 2; + break; + case 8000000: + cpuclock = 24000000.0; + break; + case 9545456: + cpuclock = 28636368.0; + break; + case 10000000: + cpuclock = 30000000.0; + break; + case 12000000: + cpuclock = 36000000.0; + break; + case 16000000: + cpuclock = 48000000.0; + break; + default: + if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_flags & CPU_ALTERNATE_XTAL) { + cpuclock = 28636368.0; + xt_cpu_multi = 6; + } + break; + } + if (cpuclock == 28636368.0) { + PITCONST=24.0; + CGACONST=16.0; + } else if (cpuclock != 14318184.0) { + PITCONST=cpuclock/1193182.0; + CGACONST=(cpuclock/(19687503.0/11.0)); + } + } + xt_cpu_multi <<= TIMER_SHIFT; + + MDACONST=(cpuclock/2032125.0); + VGACONST1=(cpuclock/25175000.0); + VGACONST2=(cpuclock/28322000.0); + RTCCONST=cpuclock/32768.0; + TIMER_USEC = (int64_t)((cpuclock / 1000000.0f) * (float)(1 << TIMER_SHIFT)); + bus_timing = cpuclock/(double)cpu_busspeed; } void setpitclock(float clock) { - /* Some calculations are done differently 4.77 MHz, 7.16 MHz, and 9.54 MHz CPU's, so that - loss of precision is avoided and the various component kept in better synchronization. */ - - cpuclock=clock; - if (clock == 4772728.0) { - PITCONST=4.0; - CGACONST=(8.0 / 3.0); - } else if (clock == 7159092.0) { - /* 7.16 MHz CPU - simplify the calculation to avoid - loss of precision. */ - PITCONST=6.0; - CGACONST=4.0; - } else if (clock == 9545456.0) { - /* 9.54 MHz CPU - simplify the calculation to avoid - loss of precision. */ - PITCONST=8.0; - CGACONST=(8.0 / 1.5); - } else { - PITCONST=clock/1193182.0; - CGACONST=(clock/(19687503.0/11.0)); - } - MDACONST=(clock/2032125.0); - VGACONST1=(clock/25175000.0); - VGACONST2=(clock/28322000.0); - isa_timing = clock/8000000.0; - bus_timing = clock/(double)cpu_busspeed; video_update_timing(); - - if (clock == 4772728.0) - xt_cpu_multi = 3 * (1 << TIMER_SHIFT); - else if (clock == 7159092.0) - xt_cpu_multi = 2 * (1 << TIMER_SHIFT); - else if (clock == 9545456.0) - xt_cpu_multi = (int64_t)(1.5*(double)(1 << TIMER_SHIFT)); - else - xt_cpu_multi = (int64_t)((14318184.0*(double)(1 << TIMER_SHIFT)) / (double)machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed); - device_speed_changed(); } @@ -333,7 +352,7 @@ int pit_get_timer_0() read <<= 1; return read; } - + static int pit_read_timer(PIT *pit, int t) { timer_clock(); @@ -354,7 +373,7 @@ static int pit_read_timer(PIT *pit, int t) return pit->count[t] + 1; return pit->count[t]; } - + void pit_write(uint16_t addr, uint8_t val, void *p) { PIT *pit = (PIT *)p; @@ -540,13 +559,39 @@ void pit_clock(PIT *pit, int t) pit_over(pit, t); } +static int64_t pit_read_timer_ex(PIT *pit, int t) +{ + int64_t read; + timer_clock(); + if (pit->using_timer[t] && !(pit->m[t] == 3 && !pit->gate[t])) + { + read = (int)(pit->c[t] + ((1 << TIMER_SHIFT) - 1)); + if (pit->m[t] == 2) + read += (1LL << TIMER_SHIFT) * PITCONST; + if (read < 0) + read = 0; + if (read > ((0x10000LL << TIMER_SHIFT) * PITCONST)) + read = ((0x10000LL << TIMER_SHIFT) * PITCONST); + if (pit->m[t] == 3) + read <<= 1; + return read; + } + if (pit->m[t] == 2) { + read = (int64_t) (((pit->count[t] + 1LL) << TIMER_SHIFT) * PITCONST); + return read; + } + read = (int64_t) ((pit->count[t] << TIMER_SHIFT) * PITCONST); + return read; +} + void pit_set_using_timer(PIT *pit, int t, int using_timer) { timer_process(); if (pit->using_timer[t] && !using_timer) pit->count[t] = pit_read_timer(pit, t); if (!pit->using_timer[t] && using_timer) - pit->c[t] = (int64_t)((((int64_t) pit->count[t]) << TIMER_SHIFT) * PITCONST); + pit->c[t] = pit_read_timer_ex(pit, t); + // pit->c[t] = (int64_t)((((int64_t) pit->count[t]) << TIMER_SHIFT) * PITCONST); pit->using_timer[t] = using_timer; pit->running[t] = pit->enabled[t] && pit->using_timer[t] && !pit->disabled[t]; timer_update_outstanding(); diff --git a/src/rom.c b/src/rom.c index c16499dc1..e4db89a6d 100644 --- a/src/rom.c +++ b/src/rom.c @@ -13,7 +13,7 @@ * - c386sx16 BIOS fails checksum * - the loadfont() calls should be done elsewhere * - * Version: @(#)rom.c 1.0.43 2019/01/13 + * Version: @(#)rom.c 1.0.44 2019/02/08 * * Authors: Sarah Walker, * Miran Grca, @@ -330,9 +330,9 @@ rom_load_bios(int rom_id) mem_mapping_disable(&romext_mapping); switch (rom_id) { - case ROM_IBMPC: /* IBM PC */ + case ROM_IBMPC: /* IBM PC (1981) */ if (! rom_load_linear( - L"roms/machines/ibmpc/pc102782.bin", + L"roms/machines/ibmpc/BIOS_5150_24APR81_U33.BIN", 0x00e000, 8192, 0, rom)) break; /* Try to load the (full) BASIC ROM. */ @@ -355,7 +355,32 @@ rom_load_bios(int rom_id) 0x00c000, 8192, 0, rom)) break; /* nope */ return(1); - case ROM_IBMXT: /* IBM PX-XT */ + case ROM_IBMPC82: /* IBM PC (1982) */ + if (! rom_load_linear( + L"roms/machines/ibmpc82/pc102782.bin", + 0x00e000, 8192, 0, rom)) break; + + /* Try to load the (full) BASIC ROM. */ + if (rom_load_linear( + L"roms/machines/ibmpc82/ibm-basic-1.10.rom", + 0x006000, 32768, 0, rom)) return(1); + + /* Nope. Try to load the first BASIC ROM image. */ + if (! rom_load_linear( + L"roms/machines/ibmpc82/basicc11.f6", + 0x006000, 8192, 0, rom)) return(1); /* nope */ + if (! rom_load_linear( + L"roms/machines/ibmpc82/basicc11.f8", + 0x008000, 8192, 0, rom)) break; /* nope */ + if (! rom_load_linear( + L"roms/machines/ibmpc82/basicc11.fa", + 0x00a000, 8192, 0, rom)) break; /* nope */ + if (! rom_load_linear( + L"roms/machines/ibmpc82/basicc11.fc", + 0x00c000, 8192, 0, rom)) break; /* nope */ + return(1); + + case ROM_IBMXT: /* IBM PX-XT (1982) */ if (rom_load_linear( L"roms/machines/ibmxt/xt.rom", 0x000000, 65536, 0, rom)) return(1); @@ -368,6 +393,15 @@ rom_load_bios(int rom_id) 0x008000, 32768, 0, rom)) return(1); break; + case ROM_IBMXT86: /* IBM PX-XT (1986) */ + if (! rom_load_linear( + L"roms/machines/ibmxt86/BIOS_5160_09MAY86_U19_62X0819_68X4370_27256_F000.BIN", + 0x000000, 32768, 0, rom)) break; + if (rom_load_linear( + L"roms/machines/ibmxt86/BIOS_5160_09MAY86_U18_59X7268_62X0890_27256_F800.BIN", + 0x008000, 32768, 0, rom)) return(1); + break; + case ROM_XI8088: if (rom_load_linear_inverted( L"roms/machines/xi8088/bios-xi8088.bin", diff --git a/src/rom.h b/src/rom.h index b48805a6b..6e50467e7 100644 --- a/src/rom.h +++ b/src/rom.h @@ -8,7 +8,7 @@ * * Definitions for the ROM image handler. * - * Version: @(#)rom.h 1.0.21 2019/01/13 + * Version: @(#)rom.h 1.0.22 2019/02/08 * * Author: Fred N. van Kempen, * Copyright 2018 Fred N. van Kempen. @@ -28,10 +28,12 @@ typedef struct { enum { - ROM_IBMPC = 0, /* 301 keyboard error, 131 cassette (!!!) error */ + ROM_IBMPC = 0, /* 1981 - 16-64 variant */ + ROM_IBMPC82, /* 1982 - 64-256 variant */ ROM_AMIXT, /* XT Clone with AMI BIOS */ ROM_DTKXT, - ROM_IBMXT, /* 301 keyboard error */ + ROM_IBMXT, + ROM_IBMXT86, ROM_GENXT, /* 'Generic XT BIOS' */ ROM_JUKOPC, ROM_PORTABLE, diff --git a/src/sound/snd_opl.c b/src/sound/snd_opl.c index 3daea480b..b18509d8e 100644 --- a/src/sound/snd_opl.c +++ b/src/sound/snd_opl.c @@ -22,7 +22,7 @@ uint8_t opl2_read(uint16_t a, void *priv) { opl_t *opl = (opl_t *)priv; - cycles -= (int)(isa_timing * 8); + cycles -= ISA_CYCLES(8); opl2_update2(opl); return opl_read(0, a); } @@ -39,7 +39,7 @@ uint8_t opl2_l_read(uint16_t a, void *priv) { opl_t *opl = (opl_t *)priv; - cycles -= (int)(isa_timing * 8); + cycles -= ISA_CYCLES(8); opl2_update2(opl); return opl_read(0, a); } @@ -55,7 +55,7 @@ uint8_t opl2_r_read(uint16_t a, void *priv) { opl_t *opl = (opl_t *)priv; - cycles -= (int)(isa_timing * 8); + cycles -= ISA_CYCLES(8); opl2_update2(opl); return opl_read(1, a); } @@ -71,7 +71,7 @@ uint8_t opl3_read(uint16_t a, void *priv) { opl_t *opl = (opl_t *)priv; - cycles -= (int)(isa_timing * 8); + cycles -= ISA_CYCLES(8); opl3_update2(opl); return opl_read(0, a); } diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index 449ab3a0d..dd13236dc 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -463,10 +463,17 @@ cga_poll(void *p) cga->cgadispon = 1; cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; } - if ((cga->crtc[10] & 0x60) == 0x20) - cga->cursoron = 0; - else - cga->cursoron = cga->cgablink & 8; + switch (cga->crtc[10] & 0x60) { + case 0x20: + cga->cursoron = 0; + break; + case 0x60: + cga->cursoron = cga->cgablink & 0x10; + break; + default: + cga->cursoron = cga->cgablink & 0x08; + break; + } } if (cga->vc == cga->crtc[7]) { diff --git a/src/video/vid_hercules.c b/src/video/vid_hercules.c index 7962b59f1..1fae48528 100644 --- a/src/video/vid_hercules.c +++ b/src/video/vid_hercules.c @@ -8,13 +8,13 @@ * * Hercules emulation. * - * Version: @(#)vid_hercules.c 1.0.16 2018/11/18 + * Version: @(#)vid_hercules.c 1.0.17 2019/02/07 * * Authors: Sarah Walker, * Miran Grca, * - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. */ #include #include @@ -22,6 +22,7 @@ #include #include #include "../86box.h" +#include "../cpu/cpu.h" #include "../mem.h" #include "../rom.h" #include "../io.h" @@ -92,6 +93,7 @@ static void hercules_out(uint16_t addr, uint8_t val, void *priv) { hercules_t *dev = (hercules_t *)priv; + uint8_t old; switch (addr) { case 0x03b0: @@ -105,6 +107,7 @@ hercules_out(uint16_t addr, uint8_t val, void *priv) case 0x03b3: case 0x03b5: case 0x03b7: + old = dev->crtc[dev->crtcreg]; dev->crtc[dev->crtcreg] = val; /* @@ -115,11 +118,15 @@ hercules_out(uint16_t addr, uint8_t val, void *priv) dev->crtc[10] = 0xb; dev->crtc[11] = 0xc; } - recalc_timings(dev); + if (old ^ val) + recalc_timings(dev); break; case 0x03b8: + old = dev->ctrl; dev->ctrl = val; + if (old ^ val) + recalc_timings(dev); break; case 0x03bf: @@ -158,7 +165,9 @@ hercules_in(uint16_t addr, void *priv) break; case 0x03ba: - ret = (dev->stat & 0xf) | ((dev->stat & 8) << 4); + ret = 0x72; /* Hercules ident */ + if (dev->stat & 0x08) + ret |= 0x88; break; default: @@ -169,12 +178,24 @@ hercules_in(uint16_t addr, void *priv) } +static void +hercules_waitstates(void *p) +{ + int ws_array[16] = {3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8}; + int ws; + + ws = ws_array[cycles & 0xf]; + cycles -= ws; +} + + static void hercules_write(uint32_t addr, uint8_t val, void *priv) { hercules_t *dev = (hercules_t *)priv; dev->vram[addr & 0xffff] = val; + hercules_waitstates(dev); } @@ -184,6 +205,7 @@ hercules_read(uint32_t addr, void *priv) hercules_t *dev = (hercules_t *)priv; return(dev->vram[addr & 0xffff]); + hercules_waitstates(dev); } @@ -221,7 +243,10 @@ hercules_poll(void *priv) ca += 0x8000; for (x = 0; x < dev->crtc[1]; x++) { - dat = (dev->vram[((dev->ma << 1) & 0x1fff) + ca] << 8) | dev->vram[((dev->ma << 1) & 0x1fff) + ca + 1]; + if (dev->ctrl & 8) + dat = (dev->vram[((dev->ma << 1) & 0x1fff) + ca] << 8) | dev->vram[((dev->ma << 1) & 0x1fff) + ca + 1]; + else + dat = 0; dev->ma++; for (c = 0; c < 16; c++) { buffer->line[dev->displine][(x << 4) + c] = (dat & (32768 >> c)) ? 7 : 0; @@ -231,8 +256,11 @@ hercules_poll(void *priv) } } else { for (x = 0; x < dev->crtc[1]; x++) { - chr = dev->vram[(dev->ma << 1) & 0xfff]; - attr = dev->vram[((dev->ma << 1) + 1) & 0xfff]; + if (dev->ctrl & 8) { + chr = dev->vram[(dev->ma << 1) & 0xfff]; + attr = dev->vram[((dev->ma << 1) + 1) & 0xfff]; + } else + chr = attr = 0; drawcursor = ((dev->ma == ca) && dev->con && dev->cursoron); blink = ((dev->blink & 16) && (dev->ctrl & 0x20) && (attr & 0x80) && !drawcursor); @@ -267,9 +295,6 @@ hercules_poll(void *priv) } else { dev->vidtime += dev->dispontime; - if (dev->dispon) - dev->stat &= ~1; - dev->linepos = 0; if (dev->vsynctime) { dev->vsynctime--; @@ -327,7 +352,8 @@ hercules_poll(void *priv) x = dev->crtc[1] * 9; dev->lastline++; - if ((x != xsize) || ((dev->lastline - dev->firstline) != ysize) || video_force_resize_get()) { + if ((dev->ctrl & 8) && + ((x != xsize) || ((dev->lastline - dev->firstline) != ysize) || video_force_resize_get())) { xsize = x; ysize = dev->lastline - dev->firstline; if (xsize < 64) xsize = 656; @@ -360,6 +386,9 @@ hercules_poll(void *priv) dev->ma = dev->maback; } + if (dev->dispon) + dev->stat &= ~1; + if ((dev->sc == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3)==3 && dev->sc == ((dev->crtc[10] & 31) >> 1)))) dev->con = 1; diff --git a/src/video/vid_herculesplus.c b/src/video/vid_herculesplus.c index 071d8b89b..d3ea2efda 100644 --- a/src/video/vid_herculesplus.c +++ b/src/video/vid_herculesplus.c @@ -8,7 +8,7 @@ * * Hercules Plus emulation. * - * Version: @(#)vid_herculesplus.c 1.0.14 2018/11/18 + * Version: @(#)vid_herculesplus.c 1.0.15 2019/02/07 * * Authors: Sarah Walker, * Miran Grca, @@ -113,6 +113,7 @@ static void herculesplus_out(uint16_t port, uint8_t val, void *priv) { herculesplus_t *dev = (herculesplus_t *)priv; + uint8_t old; switch (port) { case 0x3b0: @@ -127,6 +128,7 @@ herculesplus_out(uint16_t port, uint8_t val, void *priv) case 0x3b5: case 0x3b7: if (dev->crtcreg > 22) return; + old = dev->crtc[dev->crtcreg]; dev->crtc[dev->crtcreg] = val; if (dev->crtc[10] == 6 && dev->crtc[11] == 7) { /*Fix for Generic Turbo XT BIOS, @@ -134,11 +136,15 @@ herculesplus_out(uint16_t port, uint8_t val, void *priv) dev->crtc[10] = 0xb; dev->crtc[11] = 0xc; } - recalc_timings(dev); + if (old ^ val) + recalc_timings(dev); return; case 0x3b8: + old = dev->ctrl; dev->ctrl = val; + if (old ^ val) + recalc_timings(dev); return; case 0x3bf: @@ -414,8 +420,11 @@ text_line(herculesplus_t *dev, uint16_t ca) uint32_t col; for (x = 0; x < dev->crtc[1]; x++) { - chr = dev->vram[(dev->ma << 1) & 0xfff]; - attr = dev->vram[((dev->ma << 1) + 1) & 0xfff]; + if (dev->ctrl & 8) { + chr = dev->vram[(dev->ma << 1) & 0xfff]; + attr = dev->vram[((dev->ma << 1) + 1) & 0xfff]; + } else + chr = attr = 0; drawcursor = ((dev->ma == ca) && dev->con && dev->cursoron); @@ -459,8 +468,11 @@ graphics_line(herculesplus_t *dev) ca += 0x8000; for (x = 0; x < dev->crtc[1]; x++) { - val = (dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane] << 8) - | dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane + 1]; + if (dev->ctrl & 8) + val = (dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane] << 8) + | dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane + 1]; + else + val = 0; dev->ma++; for (c = 0; c < 16; c++) { @@ -559,7 +571,8 @@ herculesplus_poll(void *priv) else x = dev->crtc[1] * 9; dev->lastline++; - if ((x != xsize) || ((dev->lastline - dev->firstline) != ysize) || video_force_resize_get()) { + if ((dev->ctrl & 8) && + ((x != xsize) || ((dev->lastline - dev->firstline) != ysize) || video_force_resize_get())) { xsize = x; ysize = dev->lastline - dev->firstline; if (xsize < 64) xsize = 656; diff --git a/src/video/vid_incolor.c b/src/video/vid_incolor.c index 9b762d82c..40ea0a6ab 100644 --- a/src/video/vid_incolor.c +++ b/src/video/vid_incolor.c @@ -8,7 +8,7 @@ * * Hercules InColor emulation. * - * Version: @(#)vid_incolor.c 1.0.13 2018/10/11 + * Version: @(#)vid_incolor.c 1.0.14 2019/02/08 * * Authors: Sarah Walker, * Miran Grca, @@ -210,6 +210,7 @@ static void incolor_out(uint16_t port, uint8_t val, void *priv) { incolor_t *dev = (incolor_t *)priv; + uint8_t old; switch (port) { case 0x3b0: @@ -226,6 +227,7 @@ incolor_out(uint16_t port, uint8_t val, void *priv) dev->palette[dev->palette_idx % 16] = val; ++dev->palette_idx; } + old = dev->crtc[dev->crtcreg]; dev->crtc[dev->crtcreg] = val; if (dev->crtc[10] == 6 && dev->crtc[11] == 7) { @@ -234,11 +236,15 @@ incolor_out(uint16_t port, uint8_t val, void *priv) dev->crtc[10] = 0xb; dev->crtc[11] = 0xc; } - recalc_timings(dev); + if (old ^ val) + recalc_timings(dev); return; case 0x3b8: + old = dev->ctrl; dev->ctrl = val; + if (old ^ val) + recalc_timings(dev); return; case 0x3bf: @@ -795,8 +801,11 @@ text_line(incolor_t *dev, uint16_t ca) uint32_t col; for (x = 0; x < dev->crtc[1]; x++) { - chr = dev->vram[(dev->ma << 1) & 0xfff]; - attr = dev->vram[((dev->ma << 1) + 1) & 0xfff]; + if (dev->ctrl & 8) { + chr = dev->vram[(dev->ma << 1) & 0xfff]; + attr = dev->vram[((dev->ma << 1) + 1) & 0xfff]; + } else + chr = attr = 0; drawcursor = ((dev->ma == ca) && dev->con && dev->cursoron); @@ -862,10 +871,13 @@ graphics_line(incolor_t *dev) mask = dev->crtc[INCOLOR_CRTC_MASK]; /* Planes to display */ for (plane = 0; plane < 4; plane++, mask = mask >> 1) { - if (mask & 1) - val[plane] = (dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane] << 8) | - dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane + 1]; - else val[plane] = 0; + if (dev->ctrl & 8) { + if (mask & 1) + val[plane] = (dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane] << 8) | + dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane + 1]; + else val[plane] = 0; + } else + val[plane] = 0; } dev->ma++; @@ -976,7 +988,8 @@ incolor_poll(void *priv) else x = dev->crtc[1] * 9; dev->lastline++; - if ((x != xsize) || ((dev->lastline - dev->firstline) != ysize) || video_force_resize_get()) { + if ((dev->ctrl & 8) && + ((x != xsize) || ((dev->lastline - dev->firstline) != ysize) || video_force_resize_get())) { xsize = x; ysize = dev->lastline - dev->firstline; if (xsize < 64) xsize = 656; diff --git a/src/win/win_joystick.cpp b/src/win/win_joystick.cpp index 1a2ee031c..c50ee3e79 100644 --- a/src/win/win_joystick.cpp +++ b/src/win/win_joystick.cpp @@ -85,7 +85,7 @@ BOOL CALLBACK DIEnumDeviceObjectsCallback( lpddoi->guidType == GUID_RxAxis || lpddoi->guidType == GUID_RyAxis || lpddoi->guidType == GUID_RzAxis || lpddoi->guidType == GUID_Slider) { - memcpy(state->axis[state->nr_axes].name, lpddoi->tszName, strlen(state->axis[state->nr_axes].name) + 1); + memcpy(state->axis[state->nr_axes].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); joystick_log("Axis %i : %s %x %x\n", state->nr_axes, state->axis[state->nr_axes].name, lpddoi->dwOfs, lpddoi->dwType); if (lpddoi->guidType == GUID_XAxis) state->axis[state->nr_axes].id = 0; @@ -103,13 +103,13 @@ BOOL CALLBACK DIEnumDeviceObjectsCallback( } else if (lpddoi->guidType == GUID_Button) { - memcpy(state->button[state->nr_buttons].name, lpddoi->tszName, strlen(state->button[state->nr_buttons].name) + 1); + memcpy(state->button[state->nr_buttons].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); joystick_log("Button %i : %s %x %x\n", state->nr_buttons, state->button[state->nr_buttons].name, lpddoi->dwOfs, lpddoi->dwType); state->nr_buttons++; } else if (lpddoi->guidType == GUID_POV) { - memcpy(state->pov[state->nr_povs].name, lpddoi->tszName, strlen(state->pov[state->nr_povs].name) + 1); + memcpy(state->pov[state->nr_povs].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1); joystick_log("POV %i : %s %x %x\n", state->nr_povs, state->pov[state->nr_povs].name, lpddoi->dwOfs, lpddoi->dwType); state->nr_povs++; } @@ -155,7 +155,7 @@ void joystick_init() joystick_log("Joystick %i :\n", c); joystick_log(" tszInstanceName = %s\n", device_instance.tszInstanceName); joystick_log(" tszProductName = %s\n", device_instance.tszProductName); - memcpy(plat_joystick_state[c].name, device_instance.tszInstanceName, 260); + memcpy(plat_joystick_state[c].name, device_instance.tszInstanceName, strlen(device_instance.tszInstanceName) + 1); memset(&devcaps, 0, sizeof(devcaps)); devcaps.dwSize = sizeof(devcaps); diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c index 8f7510489..cd2bdc93f 100644 --- a/src/win/win_sdl.c +++ b/src/win/win_sdl.c @@ -12,7 +12,7 @@ * we will not use that, but, instead, use a new window which * coverrs the entire desktop. * - * Version: @(#)win_sdl.c 1.0.4 2018/11/18 + * Version: @(#)win_sdl.c 1.0.5 2019/02/08 * * Authors: Fred N. van Kempen, * Michael Drüing, @@ -62,6 +62,9 @@ #include #include #include +/* This #undef is needed because a SDL include header redefines HAVE_STDARG_H. */ +#undef HAVE_STDARG_H +#define HAVE_STDARG_H #include "../86box.h" #include "../device.h" #include "../plat.h"