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"